ZendChina | Zend中文权威资讯's Archiver

刘昊 发表于 2007-12-30 01:55

和Zend Framework 一起成长(一)

本教程打算介绍用Zend Framework 写一个基本的数据库驱动的应用程序。

[b]注:[/b]本教程已经在Zend Framework Version 0.9 和0.9.1 上测试过。它非常有希望和以后的版本一起工作,但很确定,它不和0.9 以前的版本工作。(谁还希望用0.9 以前的版本?译者注)对于0.9 版的警示:如果你已经下载了Zend Framework 的0.9 版,那么你必须编辑library/Zend/Db/Table/Row/Abstract.php 文件在第一行的开始加上“<”

[b]模型-视图-控制器(Model-View-Controller )架构
[/b]下面是传统的构建PHP 应用程序的方法:
[php]<?php
include "common-libs.php";
include "config.php";
mysql_connect($hostname, $username, $password);
mysql_select_db($database);
?>
<?php include "header.php"; ?>
<h1>Home Page</h1>
<?php
$sql = "SELECT * FROM news";
$result = mysql_query($sql);
?>
<table>
<?php
while ($row = mysql_fetch_assoc($result)) {
?>
<tr>
<td><?php echo $row['date_created']; ?></td>
<td><?php echo $row['title']; ?></td>
</tr>
<?php
}
?>
</table>
<?php include "footer.php"; ?>[/php]

       随着时间的推移,当客户不断地有新的需求产生,这种分布于不同地方的基于代码的应用就变得不可维护。
       一种改善应用程序可维护性的方法就是把代码分离成截然不同的三个部分(并且通常分离成不同的文件):

模型:         模型是处理被显示的数据的程序。在上面的例子中,它就是”news”的概念。这样,模型一般来说
                   关心”business”逻辑并从数据库中读取和存储数据。
视图:         视图包括一些关于显示给用户的程序,通常是HTML
控制器:     控制器同模型和视图配合在一起,把正确的数据显示在合适的页面上。

       The Zend Framework uses the Model-View-Controller (MVC) architecture. This is used to separate out the different parts of your application to make development and maintenance easier.

       Zend Framework 使用模型-视图-控制器(Model-View-Controller (MVC))架构。 这个用来把你的程序分离成不同部分使得开发和维护变得容易。

[b]需求[/b]
运行Zend Framework 需要:
[list][*]PHP 5.1.4 (或更高)[*]Web 服务器支持mod_rewrite 功能. 本教程采用Apache。[/list]
[b]获取Zend Framework[/b]
       从这里[url=http://framework.zend.com/download]http://framework.zend.com/download[/url] 下载Zend Framework,有两种格式.zip 或者.tar.gz。当前的版本是0.9.1。对于本教程,你必须使用0.9 和以上的版本。

[b]目录结构[/b]
       虽然Zend Framework 没有强求使用一个标准的目录结构,但它的手册还是推荐了一个通用的目录结构。这个目录结构假设你完全控制Apache 的配置,然而我们想使它更容易一点,所以做了一点修正。

       建立一个根目录叫做 zf-tutorial。 这个意味着指向程序的URL 将会是[url=http://localhost/zf-tutorial]http://localhost/zf-tutorial[/url]。建立如下的子目录,这些目录将存放程序所需要的文件:

zf-tutorial/
       /application
              /controllers
              /models
              /views
                     /filters
                     /helpers
                     /scripts
       /library
              /public
              /images
              /scripts
              /styles

       正如你所看到的,我们已经把我们的程序中的模型、视图和控制器的文件分离到不同的子目录中。支持的图像,脚本和CSS 文件被存放在public 目录下的不同子目录中。下载的ZendFramework 文件放在library 目录下。如果我们还需要其他库文件,都可以放在这里。

       把ZendFramwork-0.9.1-Beta.zip 解压到一个临时目录。所有的文件都包含在一个叫做ZendFramework-0.9.1-Beta 的目录。把ZendFramework-0.9.1-Beta/library 中的文件拷贝到zf-tutorial/library。在这个目录下,有一个子目录叫做Zend。

[b]启动文件(Bootstrapping)[/b]
       Zend Framework 的控制器,Zend_Controller,被设计支持使用clean urls 的网站。为实现这个目的,所有的请求需要通过单一的index.php 文件,这就是所知的启动文件(bootstrapper)。这给我们提供了程序中所有页面的中心点并确保运行环境配置正确。我们用.htaccess 文件来实现这个目的,.htaccess 在zf-tutorial 的根目录中,内容如下:
[quote]zf-tutorial/.htaccess
       RewriteEngine on
       RewriteRule .* index.php
       php_flag magic_quotes_gpc off
       php_flag register_globals off[/quote]

       RewriteRule 非常简单并可以翻译为“对任何url, 重定向到index.php”。

       为安全和稳定起见,我们也在PHP ini 中做一些设置。虽然这些都已经设置正确,我们还是要确认一下!注意在.htaccess 中的php_flag 只工作于mod_php 下。如果你使用CGI/FastCGI,就需要确保php.ini 配置正确。
       然而,对于图像,JavaScript 和CSS 文件的请求不应该重定向到启动文件,把这些文件放到public 目录下,我们很容易地通过另一个.htaccess 文件来配置Apache。这个.htaccess 文件在zf-tutorial/public 下:
[quote]zf-tutorial/public/.htaccess
       RewriteEngine off[/quote]

       虽然我们当前的rewrite rules 不需要太严格,但我们还是在application 和library 目录下添加一些.htaccess 文件用来保护我们的程序:
[quote]
zf-tutorial/application/.htaccess
       deny from all

zf-tutorial/library/.htaccess
       deny from all
[/quote]

       注意在Apache 下设置.htaccess 文件,httpd.conf 中的AllowOverride 必须设置为All。这些设置多个.htaccess 文件的主意来自于 Jayson Minard 的文章 “Blueprint for PHP Applications:
       Bootstrapping (Part 2) ”. 我建议大家去读读整个系列文章。

[b]启动文件:index.php[/b]
       zf-tutorial/index.php 是我们的启动文件,我们从下面的代码开始:
zf-tutorial/index.php
[php]
<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');
set_include_path('.' . PATH_SEPARATOR . './library'
. PATH_SEPARATOR . './application/models/'
. PATH_SEPARATOR . get_include_path());
include "Zend/Loader.php";
Zend_Loader::loadClass('Zend_Controller_Front');
// setup controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory('./application/controllers');
// run!
$frontController->dispatch();
[/php]

       注意我们没有在文件的结尾放?>,因为它不是必须的并且有个好处是:我们可以防止当多余的whitespace 发生在?>后面出现难以调试的错误。

       让我们过一遍这个文件
[quote]error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');[/quote]

       第几行确保我们能看到我们犯的错误(假定在php.ini 中的display_errors 设置为on),PHP5.1+要求设置当前时区。显然,你应该选择你自己的时区。
[quote]set_include_path('.' . PATH_SEPARATOR . './library'
. PATH_SEPARATOR . './application/models/'
. PATH_SEPARATOR . get_include_path());
include "Zend/Loader.php";[/quote]

       Zend Framework 是这样设计的,所有的文件必须包含在include path 中。我们也把我们的模型目录包含在include path 中,这样我们以后就能很容易加载我们的模型类。一开始,我们必须include Zend/Loader.php,这样我们就能访问Zend_Loader 类,在Zend_Loader 类中有静态方法使我们能够加载其他Zend Framework 类,例如:
Zend_Loader::loadClass('Zend_Controller_Front');

       Zend_Loader::loadClass 加载已经命名的类。它是把下划线转换成路径隔离符来实现的,并在最后加上.php 后缀。这样,类Zend_Controller_Front 将从Zend/Controller/font.php 加载。如果你在你的类库里使用相同的命名规则,就可以用Zend_Loader::loadCass()来加载它们。我们需要加载控制器类和路由类。

       前端控制器用路由类来映射请求的URL 到正确的PHP 函数,然后显示页面。为了能使路由工作,需要解决URL 的哪一部分是指向index.php 的路径,这样它就可以在那个点后面寻找url元素。这个由Request 对象完成, 它在自动检测正确的base URL 方面做的很出色,但如果它对你的设置不工作,你可以用函数$frontController->setBaseUrl()来override。

       我们需要配置前端路由器,这样它就知道从哪个目录里找出我们的控制器。
[quote]$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory('./application/controllers');
$frontController->throwExceptions(true);[/quote]

       因为这是一个教程并且我们打算运行一个测试系统。我决定让前端控制器抛出所有发生的异常。缺省地,前端控制器将捕获它们并把它们存储在“响应”对象所建立的 _exceptions 属性里。响应对象掌握所有关于响应给URL 的信息。 这包括HTTP 头,页面内容和异常。前端控制器在完成它的工作前将自动发送头和显示页面内容。

       这对新学Zend Framework 的人有点迷惑,仅仅重新抛出很容易,这样异常容易可见。当然,在一个生产服务器上,你不应当给用户显示错误信息!

       终于,我们到了问题的核心并且可以运行我们的程序了:
[quote]// 运行!
$frontController->dispatch();[/quote]

       如果你用[url=http://localhost/zf_tutorial/]http://localhost/zf_tutorial/[/url] 去测试,致命的错误类似于:
[quote]Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with
message 'Invalid controller specified (index)' in…[/quote]

       这个告诉我们还没有设置好我们程序。在我们动手之前,最好讨论一下我们要打算做什么,那就开始吧

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.