上一节我们创建了含有几个action 函数的 IndexController.php 文件,了解了zf application 应用的大概架构,现在轮到model部分了。model 是处理application应用的业务规则核心部分(“business rule”),在我们的教程中,这也就是数据库。我们将使用Zend Framework 的 Zend_Db_Table类来查找/插入/更新或删除数据库中的行。
为了使用 Zend_Db_Table,我们要告诉zf使用哪个数据库,以及用户名和密码。Zend Framework的Zend_Application 组件自带了一个数据库配置文件application/configs/application.ini,我们在这个文件中配置数据库相关信息。
打开application.ini 文件,在[production] 部分的末尾加入以下设置(数据库名称、用户名、密码换成你自己的):
resources.db.adapter = PDO_MYSQL resources.db.params.host = localhost resources.db.params.username = root resources.db.params.password = mysqlpassword resources.db.params.dbname = zendframeworktutorial
数据库将会自动创建Mysql数据库连接,Zend_Db_Table 默认的adapter也会创建。Zend官网有其他可用的resource 插件介绍:
http://framework.zend.com/manual/en/zend.application.available-resources.html
创建数据库表
我们将使用MySQL数据库来保存专辑信息,MySQL创建数据库以及albums表的SQL语言如下:
CREATE DATABASE IF NOT EXISTS zftest default charset utf8 COLLATE utf8_general_ci; use zftest; CREATE TABLE albums ( id int(11) NOT NULL auto_increment, artist varchar(100) NOT NULL, title varchar(100) NOT NULL, PRIMARY KEY (id) );
在phpmyadmin 等MySQL客户端或标准的MySQL 命令行界面运行上面的语句。
插入数据
为了演示案例,我们在数据库表中再插入一些样本数据,执行SQL语句:
INSERT INTO albums (artist, title) VALUES ('Paolo Nutine', 'Sunny Side Up'), ('Florence + The Machine', 'Lungs'), ('Massive Attack', 'Heligoland'), ('Andre Rieu', 'Forever Vienna'), ('Sade', 'Soldier of Love');
我们有数据保存在数据库中了,下面我们可以写一个简单的model。
关于 Zend_Db_Table 和 Zend_Db_Table_Abstract
Zend Framework 没有提供 Zend_Model 这个类,因为model是你的业务逻辑,这主要由你来决定它怎么工作。不过zf根据你的需求提供了许多组件可供使用帮助完成工作。一种方法是使用model类来表示zf应用中的每一个实体(entity),并使用 mapper 对象加载或保存这个实体到数据库中。这种方法在zf官方教程中有详细介绍:http://framework.zend.com/manual/en/learning.quickstart.create-model.html。
在这个教程中,我们将创建一个扩展Zend_Db_Table类的 model 并使用 Zend_Db_Table_Row。Zend Framework 提供了实现Table Data
Gateway设计模式的 Zend_Db_Table,用来和数据库中的数据进行交互。注意Table Data Gateway 设计模式在更大型的系统中是有局限性的。同时Zend_Db_Table 也很容易使我们将数据库访问代码放到controller 的action方法中。
Zend_Db_Table_Abstract 是一个抽象类,从这个抽象类中我们可获得用于管理专辑的类。虽然我们可以任意命名我们的类,但根据数据库表来命名会更有意义一些。我们的project项目有一个由 Zend_Application 实例化的自动加载器,它将一个模块下里面的资源类(resource classes)映射到定义它的目录中。主文件夹application/ 使用Application_前缀。
自动加载器使用映射将资源和目录对应起来,如:
前缀 --》 目录 Form --》forms Model --》models Model_DbTable --》models/DbTable Model_Mapper --》models/mappers Plugin --》plugins Service --》services View_Filter --》views/filters View_Helper --》views/helpers
因为我们是根据数据库表命名albums,并使用Zend_Db_Table的,我们的类将会以 Application_Model_DbTable_Albums 命名,保存在applications/models/DbTable/Albums.php 文件中。
为了告诉 Zend_Db_Table 要管理哪个表,我们要为表名称设定protected 属性 $_name。同样,Zend_Db_Table 会认为数据库表有一个名为id自动递增的主键,这个field的名称如果有需要也可以更改。使用zf命令行工具:
zf create db-table Albums albums
文件 applications/models/DbTable/Albums.php 将会被创建,在这个文件中有一个名为 Application_Model_DbTable_Albums 的类,并设定了和这个类交互的数据库表的名称。
现在我们要编辑 application/models/DbTable/Albums.php 文件以增加一些功能,models中的文件通常是和数据库交互(读取/插入/编辑/删除数据库表中的数据信息),我们添加 getAlbum(), addAlbum(), updateAlbum() 和 deleteAlbum() 这几个方法如下:
<?php class Application_Model_DbTable_Albums extends Zend_Db_Table_Abstract { protected $_name = 'albums'; public function getAlbum($id) { $id = (int)$id; $row = $this->fetchRow('id = ' . $id); if (!$row) { throw new Exception("Could not find row $id"); } return $row->toArray(); } public function addAlbum($artist, $title) { $data = array( 'artist' => $artist, 'title' => $title, ); $this->insert($data); } public function updateAlbum($id, $artist, $title) { $data = array( 'artist' => $artist, 'title' => $title, ); $this->update($data, 'id = '. (int)$id); } public function deleteAlbum($id) { $this->delete('id =' . (int)$id); } }
上面我们创建了4个用于和数据库表交互的helper 方法。 getAlbum() 以数组的形式获取一个单一行, addAlbum() 在数据库中创建一个新行, updateAlbum() 更新一个数据库行,deleteAlbum() 删除一个整行。你也可以告诉 Zend_Db_Table 其他相关数据库表并获取相关的数据。
下面我们要在controllers 中填入models 中的数据,以及编写view 脚本代码显示它。在这之前,我们先来看看 Zend Framework的view 系统是如何工作的。