function deleteAction() {
echo \
in IndexController::deleteAction()\} }
开始,我们让每个action 输出它们的名字,导航到下表的URL 做测试:
现在,我们在程序里有个能工作的路由器和能够在每个页面被执行的正确的action。如果它不能工作,请到本教程后面查阅“故障排除”一节,看看能否得到帮助。 好啦,现在来做视图。
设置视图
Zend Framework 的视图叫做Zend_View,有点顾名思义。视图将允许我们把显示页面的代码从action 函数里分离出来。 基本的Zend_View 的用法是: $vie引用:
引用: w = new Zend_View();
$view->setScriptPath('/path/to/view_files'); echo $view->render('view.php');
如果我们打算直接把这个骨架放到action 函数并重复这个对action 毫无意义的代码,这将非常容易。但我们宁愿在其他地方初始化它,然后在action 里使用这个已经初始化过的对象。
Zend Framework 的设计者已经预料到这类问题并提供了方案,它放在
Zend_Controller_Action 里。有两个助手函数:initView()和render()。 initView()函数创建Zend_View 对象并赋值给给$view 属性,准备好让我们赋值给它。它也设置Zend_View 对象去查找views/scripts/{controller name},以便视图脚本被调用。视图脚本通过render()来调用,它将调用脚本{action_name}.phtml 并追加到响应对象的body 里。响应对象用来把所有的
头,body content 和MVC 系统产生的异常放在一起。前端控制器接着自动地发送头以及紧接着的在dispatch 尾端的body content。
引用: To integrate the view into our application we need to initialise the view in the init() function and then ensure we call render() in each action. We also need to create some view files with test display code.
为了集成视图到程序中,我们需要在init()函数里初始化视图并确保在每个action 里调用render()。我们也需要创建一些带有测试显示代码的视图文件。
如下修改 IndexController。(被修改的部分是黑体字)。正如你看到的,我们添加一个新的函数叫做init(),它被Zend_Controller_Action 的构造器自动地调用。这就确保视图能够在开始被初始化并且我们确信它已经准备好能被用在action 函数中。
zf-tutorial/application/controllers/IndexController.php复制PHP内容到剪贴板PHP代码:
代码:
class IndexController extends Zend_Controller_Action {
function init()
6
{
$this->initView(); }
function indexAction() {
$this->view->title = \$this->render(); }
function addAction() {
$this->view->title = \$this->render(); }
function editAction() {
$this->view->title = \$this->render(); }
function deleteAction() {
$this->view->title = \$this->render(); } }
在每个函数中,我们分配一个title 变量给视图属性,接着,调用render()来显示视图模板。注意在这点上实际的显示并没有发生-它在dispatch 进程结束后由前端控制器来完成。
我们现在需要做四个视图文件。这些文件就是所知的模板并且render()方法期望每个模版文件的命名在它的action 之后并且带有.phtml 的扩展名来表明它是模板文件。模板文件必须在名字在控制器之后的子目录中,所以这四个文件是: zf-tutorial/application/views/scripts/index/index.phtml
代码: escape($this->title); ?>
zf-tutorial/application/views/scripts/index/add.phtml
代码: escape($this->title); ?>
zf-tutorial/application/views/scripts/index/edit.phtml
代码: escape($this->title); ?>
zf-tutorial/application/views/scripts/index/delete.phtml
代码: escape($this->title); ?>
测试每个控制器/action,它们应该显示出四个黑体字标题。
7
共同的 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() 看上去象这样:
8
代码: 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代码: ...
代码:
代码: 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! 数据库
既然我们从显示视图里分离了程序的控制, 是时候看一下程序中的模型部分。记住,模型
9
是处
理程序的核心意图(所谓的“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 = 123456
db.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代码:
10