共同的
HTML 代码
很快,明显地在我们的视图里有许多相同的HTML 代码。我们把他们提取到两个文件header.phtml 和footer.phtml 中,这两个
文件放在脚本目录中。我们用它们存放从视图模版里提取的“共同的”HTML:
新文件是:
zf-tutorial/application/views/scripts/header.phtml
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
(注意我们已经纠正了HTML 并且我们现在也已经适应了!)
zf-tutorial/application/views/scripts/footer.phtml
再一次,我们的视图需要修改:
zf-tutorial/application/views/scripts/index/index.phtml
复制内容到剪贴板
代码:
render('header.phtml'); ?>
escape($this->title); ?>
render('footer.phtml'); ?>zf-tutorial/application/views/scripts/index/add.phtml
复制内容到剪贴板
代码:
render('header.phtml'); ?>
escape($this->title); ?>
render('footer.phtml'); ?>zf-tutorial/application/views/scripts/index/edit.phtml
复制内容到剪贴板
代码:
render('header.phtml'); ?>
escape($this->title); ?>
render('footer.phtml'); ?>zf-tutorial/application/views/scripts/index/delete.phtml
复制内容到剪贴板
代码:
render('header.phtml'); ?>
escape($this->title); ?>
render('footer.phtml'); ?>风格
尽管这仅仅是个
教程,我们需要CSS 文件来使我们的程序看起来使可展示的。因为URL 不指向正确的根目录,我们不知道如何定位CSS 文件,这会导致一个微小的问题。为了解决它,我们使用getBaseURL()函数,它是请求的一部分并把它传递给视图。这提供给我们所不知道的一点URL。
修改 IndexController::init() 看上去象这样:
复制内容到剪贴板
代码:
zf-tutorial/application/controllers/IndexController.php复制PHP内容到剪贴板PHP代码:
...
function init()
{
$this->initView();
$this->view->baseUrl = $this->_request->getBaseUrl();
}
...我们需要把CSS 文件添加到header.phtml 的一节中:
zf-tutorial/application/views/scripts/header.phtml复制PHP内容到剪贴板PHP代码:
...
复制内容到剪贴板
代码:
<LINK media=screen type=text/css rel=stylesheet
href="baseUrl;?>/public/styles/site.css" />最后,我们需要一些 CSS 风格:
">-tutorial/public/styles/site.css
复制内容到剪贴板
代码:
body,html {
font-size:100%;
margin: 0;
font-family: Verdana,Arial,Helvetica,sans-serif;
color: #000;
background-color: #fff;
}
h1 {
font-size:1.4em;
color: #800000;
background-color: transparent;
}
#content {
width: 770px;
margin: 0 auto;
}
label {
width: 100px;
display: block;
float: left;
}
#formbutton {
margin-left: 100px;
}
a {
color: #800000;
}This should make it look slightly prettier!数据库
既然我们从显示视图里分离了程序的控制, 是时候看一下程序中的模型部分。记住,模型是处
理程序的核心意图(所谓的“business rules”)因此,对我们来说就是数据库。我们将利用
Zend Framework 中的 Zend_Db_Table 类来操作数据库中表的插入,更新和删除记录。
配置
为了使用Zend_Db_Table,我们需要告诉它哪个数据库(连同用户和密码)将被使用。因为我们不愿意在程序中hard-code,所以我们用一个配置文件来保存这些信息。
Zend Framework 提供了一个Zend_Config 来提供灵活的
面向对象访问配置文件。此刻,配置文件可以是一个PHP 数组,一个INI 文件或者
XML 文件。我们将使用INI 文件:
zf-tutorial/application/config.ini引用:
复制内容到剪贴板
代码:
[general]
db.adapter = PDO_MYSQL
db.config.host = localhost
db.config.username = rob
db.config.password = 123456db.config.dbname = zftest显然,你应该使用你自己的用户名,密码和数据库名,而不是我的!
使用Zend_Config 非常容易:引用:
$config = new Zend_Config_Ini('config.ini', 'section');注意在这个例子中,Zend_Config_Ini 从INI 文件中加载一个section,而不是每一个section(尽管如果你想,所有的section 都可以被加载)。它支持section 名字中的符号并允许加载另外的section。Zend_Config_Ini 还认为参数中的“点”等级分离符,它允许把一组相关的参数组成一个组。在我们的config.ini 里,主机,用户名,密码,数据库名参数都是在组$config->db->config 之下。
我们将在启动文件里加载配置文件(index.php)
Relevant
part of zf-tutorial/index.php
复制内容到剪贴板
代码:
...
Zend_Loader::loadClass('Zend_Controller_Front');
Zend_Loader::loadClass('Zend_Config_Ini');
Zend_Loader::loadClass('Zend_Registry');
// 加载配置
$config = new Zend_Config_Ini('./application/config.ini', 'general');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);
// 设置控制器
...修改的部分是黑体字。我们加载我们将要用的类(Zend_Config_Ini 和Zend_Registry)并加载application/config.ini 中的’general’section 到$config 对象。最后,我们分配$config 对象给注册表,这样它可以在程序的任何地方被取出来使用。
注:在这个教程里,我们实际上不需要把$config 存到注册表里,但是在“真正的”
项目中,你可能在INI 文件里有很多配置信息,而不仅仅是数据库。同样,要知道如果你不小心,注册表有一点象全局
变量并导致对象之间的依赖,而他们并不互相依靠。
建立Zend_Db_Table
为了使用Zend_Db_Table,我们需要告诉它我们刚刚加载的数据库配置信息。我们需要建立一个Zend_Db 的
实例并用静态函数Zend_Db_Table:: setDefaultAdapter()来注册它。
强调一下,我们在启动文件里完成它(黑体字):
Relevant part of zf-tutorial/index.php复制PHP内容到剪贴板PHP代码:
复制内容到剪贴板
代码:
...
Zend_Loader::loadClass('Zend_Controller_Front');
Zend_Loader::loadClass('Zend_Config_Ini');
Zend_Loader::loadClass('Zend_Registry');
Zend_Loader::loadClass('Zend_Db');
Zend_Loader::loadClass('Zend_Db_Table');
// 加载配置
$config = new Zend_Config_Ini('./application/config.ini', 'general');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);
// 设置数据库
$db = Zend_Db::factory($config->db->adapter,
$config->db->config->asArray());
Zend_Db_Table::setDefaultAdapter($db);
// 设置控制器
...建表
我打算用
MySQL,所以建表
SQL 语句如下:引用:
复制内容到剪贴板
代码:
CREATE TABLE album (
id int(11) NOT NULL auto_increment,
artist varchar(100) NOT NULL,
title varchar(100) NOT NULL,
PRIMARY KEY (id)
)在MySQL 的客户端运行这个语句,例如phpMyAdmin 或者标准的MySQL 命令行客户端。
插入测试 Albums
我们还要给表中插入一些记录来测试主页中的检索功能。我打算用Amazon.co.uk 中”Hot100”CD 中的头两条:引用:
引用:
INSERT INTO album (artist, title)
VALUES
('James Morrison', 'Undiscovered'),
('Snow Patrol', 'Eyes Open');
模型
Zend_Db_Table 是一个abstract 类,所以我们派生一个专门管理album 的类。如何命名类无关紧要,但类名和表名用同样的名字比较有意义。这样,类名就叫做Album 因为表名是album。为了告诉Zend_Db_Table 它将管理的表名,我们必须设置保护属性$_name 为表名。
并且,Zend_Db_Table 假定表有一个主键叫做id,它能够自动增长。如果需要的话,这个
字段可以更改。
我们将保存我们的Album 表到模型目录:
zf-tutorial/application/models/Album.php复制PHP内容到剪贴板PHP代码:
复制内容到剪贴板
代码:
<?php
class Album extends Zend_Db_Table
{
protected $_name = 'album';
}不是很复杂吧?!我们很幸运,我们的需求非常简单并且Zend_Db_Table 提供了所有我们需要的函数。然而,如果你需要特殊的函数管理你的模型,你可以把它们放到这个类里。一般来说,附加的函数将是附加的”find”类型方法,它使你要寻找的精确数据的集合有效。你也可以告诉Zend_Db_Table 关于相关的表并且它也可以获取相关的数据。
[
本帖最后由 Ajax_chou 于 2008-4-7 08:53 编辑 ]