zend framework 示例 zend framework demo zf sample zend framework 1.11 例子 zf1.11 实例

php因为种种原因起步比较慢,虽然发展比较快,但是众多开源项目使得,从事二次开发的人比研发的要多很多,所以一半以上的传说中的PHPER根本就不知道框架如何使用。

网上也存在了大量的教材,但总起来说,”已经过时N久了“。无论视频啊,教程啊,基本上都不怎么能用,毕竟zend framework的升级也很快,而且和PHP的更新相似的是,很多内容变动还是比较大的,所以按照原来的教程走下去,100%的是不能运行,除非你下载的zend framework的老掉牙的版本。

以后的日子里,我会将一个完整的例子发布出来。当然最低版本是zend framework 1.11

下面是现有的比较新的例子,首先声明,这个例子不是我写的,我并没有运行测试过,但是基本配置都是正确的,思路也是对的。

我们来看一下吧:

使用Zend Framework需要满足下面的条件:

•  PHP 5.2.4 或以上版本

•  支持mod_rewrite或类似功能的WEB服务器

本教程以PHP5.2.8或更高版本,Apache Web服务器。而且Apache已安装并正确配置了mod_rewrite扩
展。 (apache 的版本是:2.2.16)

必须保证Apache支持 .htaccess文件, 这通常中通过修改httpd.conf中的

AllowOverride None

AllowOverride All

来实现。

1,去官方下载一个zf框架,选择适合你版本,建议不要低于1.8.4.。现在开始创建项目:cmd 运行zf.bat 来创建工程

create module myproject就可以创建一个叫myproject的项目工程。会生成一下目录结构

配置虚拟主机,建议配置虚拟主机,这样对调试比较有利。
上面的东西就不再细细讲解。网上资料一大把的。用谷歌一搜就知道了。
1编辑application.ini文件
打开application/
configs/application.ini,在[production]部分的最后添加下面的代码:
phpSettings.date.timezone = “UTC” //设置时区
resources.db.adapter = PDO_MYSQL //链接mysql数据库
resources.db.params.host = localhost
resources.db.params.username = root
resources.db.params.password = 123456
resources.db.params.dbname = nestable
扩展自动加载类
我们需要创建一个 自动加载器来自动从程序目录下加载资源,比如从models  目录和forms  目录。
Zend_Application_Module_Autoloader类用来做这些工作,我们可以在Bootstrap类中使用它。要添加的部分已
经加粗:
application/Bootstrap.php
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAutoload()
{
$moduleLoader = new Zend_Application_Module_Autoloader(array(
‘namespace’ => ”,
‘basePath’ => APPLICATION_PATH));
return $moduleLoader;
}
}
下面我们来做一个简单的唱片的增删改查功能
模型
Zend Framework提供的Zend_Db_Table类实现了表数据入口(Table Data Gateway)设计模式,以方便与数据库
表格建立数据接口。对于较复杂的项目,经常需要建一个模型类,这个类以保护(protected)成员变量的方式
使用一个或多个Zend_Db_Table实例。但在这个教程中,我们将创建一个扩展自Zend_Db_Table的模型。
Zend_Db_Table 是抽象类,因此必须用它派生一个类才能管理我们的唱片。虽然派生类叫什么名字都可以,但
使用数据表名来命名更容易让人理解。因为我们表名为albums,加上前缀后类名将是Model_DbTable_Albums。
为了让Zend_Db_Table知道它要操作的表的名称,我们需要将其保护成员属性$_name设置为数据表名称。另外,
Zend_Db_Table假定表有一个字段名为id自动增加(Auto Increment)的主键,当然根据需要,这个字段名称可以
改变。
我们要把类Model_DbTable_Albums放到applications/models/DbTable/Albums.php中。创建文件Albums.php并键入下面
的内容:
zf-tutorial/application/models/DbTable/Albums.php
<?php
class 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(“Count 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);

}

}

我们创建了四个辅助方法,用来与数据表接口。getAlbum()查询一条记录存放到数组中,addAlbum()向数据库
中增加一条记录,updateAlbum()修改一条唱片记录,deleteAlbum()完全删除一条记录。每个方法的代码都很
容易理解。你也可以为Zend_Db_Table设置关联表获取关联数据,虽然这个教程中不需要这么做。

我们需要使用从模型中获取的数据填充到控制器中,并获取视图脚本来展示这些数据,但在此之前,我们需要
理解Zend Framework的视图系统是如何工作的。

布局和视图(Layouts and Views)

毫不奇怪,Zend Framework的视图组件叫做Zend_View。Zend_View让我们可以将页面和动作函数分离。
Zend_View的基本使用方法如下:

$view = new Zend_View();

$view->setScriptPath(‘/path/to/scripts’);

echo $view->render(‘script.php’);

显然,如果我们直接将这些代码写到每一个动作函数中,就不得不到处无聊地重复这些跟动作关系不大的 “结
构化”代码。我们希望能将视图的初始化代码放在其它的地方,然后在每个动作函数中直接访问已初始化过的
视图对象。Zend Framework为我们提供一个叫做ViewRenderer的视图助手(Action Helper)。它负责为我们初始
化控制器中的view属性($this->view),并在动作调度后显示视图脚本。

显示过程首先通知Zend_View对象在views/scripts/{controller name} 目录中查找显示脚本,然后显示与动作
名称相同,扩展名为.phtml 的显示脚本。即显示的视图文件名为views/scripts/{controller name}/{action
name}.phtml,显示的内容将附加到应答对象(Response Object)的应答内容(body)中。

应答对象将MVC系统生成的HTTP头,应答内容以及所有异常信息整合在一起。前端控制器在调度过程的结尾处自
动将HTTP头以及应答内容返回给用户。

在用zf命令创建项目和添加控制器与动作的时候,这些都已经由Zend_Tool为我们创建好。

公共HTML代码: Layouts

很快你就会发现在我们的视图中有大量相同的HTML代码,至少有用于网页头部或底部的相同代码,还有可能有
一两个相同的侧边栏。由于这个问题非常普遍,因此Zend Framework专门设计了Zend_Layout组件来解决这个问
题。 Zend_Layout组件允许我们将相同的头部和尾部代码移到独立的布局显示脚本(layout view script)中,
并在布局显示脚本中包含与正在执行的动作相关的显示代码。

这些布局文件默认保存在application/layouts/,有一个资源可以被Zend_Application用来配置Zend_Layout。

首先创建application/layouts/文件夹,然后在配置文件configs/applications.ini中的[production]部分最
后添加一行:

resources.layout.layoutpath = APPLICATION_PATH “/layouts”

我们还需要在Bootstrap类中为视图设置全局变量。我们再一次使用_init方法,命名为_initViewHelpers()。编
辑application/Bootstrap.php文件,将下面的代码添加到_initAutoload()方法下面:

application/Bootstrap.php

protected function _initViewHelpers()

{

$this->bootstrap(‘layout’);

$layout = $this->getResource(‘layout’);

$view = $layout->getView();

$view->doctype(‘XHTML1_STRICT’);

$view->headMeta()->appendHttpEquiv(‘Content-Type’, ‘text/html;charset=utf-8′);

$view->headTitle()->setSeparator(‘ – ‘);

$view->headTitle(‘Zend Framework Tutorial’);

}
我们使用bootstrap()成员变量确保初始化布局资源(layout resource),然后使用getResource()方法得到
Zend_Layout对象,最后利用getView()方法得到视图。

一旦我们有了$view实例,我们就可以用一些助手函数来准备后面的渲染。doctype()视图助手用来设置我们想
要的DOCTYPE。它对保证其他的视图助手能生成准备的HTML代码来说是非常有用的。我们使用headMeta()来设置
content-type META标签,headTitle()视图助手用来设置title中的分隔符和title最后一部分。

调试的时候,Zend_Layout将从application/layouts目录下寻找名称为layout.phtml的布局视图脚本,所以我
们最好写好这个文件,下面是这个文件的内容:

zf-tutorial/application/layouts/layout.phtml

<?php echo $this->doctype(); ?>

<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>

<head>

<?php echo $this->headMeta(); ?>

<?php echo $this->headTitle(); ?>

</head>

<body>

<div id=”content”>

<h1><?php echo $this->escape($this->title); ?></h1>

<?php echo $this->layout()->content; ?>

</div>

</body>
</html>

布局文件包含非常标准的外层HTML代码。因为这个文件是个普通的PHP文件,我们可以在里面使用PHP。里面有
个变量$this,它是视图对象的一个实例,在程序引导时被创建。我们可以用它来获取已经赋给视图的数据,也
可以调用方法。这些方法(即视图助手view helpers)返回数据可以直接用echo输出。
首先输出Bootstrap::_initViewHelpers()中创建的脚本助手,它将为<head>部分创建准备的代码。在<body>
中,我们创建一个div层,div中有一个包含标题的<h1>。为了显示当前动作的显示脚本(view scripts),我们
使用了layout()辅助函数:          echo $this->layout()->content;它将内容显示到content占位符中。这也意味着
动作的显示脚本在布局显示脚本之前执行。

在再测试一下上述四个URL,你会发现看到的内容与上次一模一样!然而它们有一个关键的不同,就是这次所有
的工作都是利用布局显示脚本(layout)来完成的。

样式

虽然只是一个教程,我们还是需要一个 CSS 文件来使得我们的程序看起来漂亮一些。因为 URL 并不是指向正
确的根目录,这使得我们在如何引用CSS文件时碰到一点小麻烦。

在zend Framework 1.9 中,引入视图助手baseUrl()。它可以从请求对象中收集我们需要的信息,提供我们不知
道的URL内容。

在zend Framework 1.8 中,还没有提供baseUrl()视图助手,所以我们要自己创建。视图助手放在application/
views/helpers子目录下,并被命名为{HelpName}.php (首字母必须大写),其中的类有一个预料中的命名规
则:必须被命名为Zend_View_Helper_{HelperName} (首字母必须大写)。类中必须有一个名为{helperName}()
(首字母小写,勿记!)的函数。在我们的例子中,这个文件命名为BaseUrl.php,内容如下:

zf-tutorial/application/views/helpers/BaseUrl.php

<?php

class Zend_View_Helper_BaseUrl

{

function baseUrl()

{
$fc = Zend_Controller_Front::getInstance();

return $fc->getBaseUrl();

}

}

这个函数并不复杂。我们简单地得到一个前端控制器的实例,然后返回getBaseUrl()成员函数的值。

注意在ZF1.8 和 1.9 中,如果你想创建自己的视图助手,创建过程都跟上面我们建立baseUrl()一样。

下面,我们需要添加CSS文件到application/layouts/layout.phtml的<head>部分,我们再使用一个视图助手-
headLink():

zf-tutorial/application/layouts/layout.phtml

<head>

<?php echo $this->HeadMeta(); ?>

<?php echo $this->headTitle(); ?>

<?php echo $this->headLink()->prependStylesheet($this->baseUrl().’/css/site.css’); ?>

</head>

利用headLink(),我们允许有其它特殊作用的CSS文件添加在控制器视图脚本中,它们将显示在<head>部分的
site.css之后。

最后,我们需要添加CSS样式,所以在public中创建一个css目录:
zf-tutorial/public/css/site.css

body,html {

margin: 0 5px;

font-family: Verdana,sans-serif;

}

h1 {

font-size: 1.4em;

color: #008000;

}

a {

color: #008000;

}

/* Table */

th {

text-align: left;

}

td, th {
padding-right: 5px;

}

/* style form */

form dt {

width: 100px; display: block; float: left; clear: left;

}

form dd {

margin-left: 0;

float: left;

}

form #submitbutton {

margin-left: 100px;

}

这会使它看起来稍微好看一些,但像你可能会说的那样,我不是个设计师(所以别指望太好看)!

现在我们可以清理前面为了填充内容而自动创建的四个动作脚本,清空index.phtml、add.phtml、add.phtml、
edit.html和delete.phtml (提醒一下,它们在application/view/scripts/index目录下)。

唱片列表功能

既然我们已经配置好配置文件、数据库和视图骨架,我们可以开始进行程序的中心内容,首先显示一个唱片的
列表。这在 IndexController 类中的 indexAction()函数中实现,开始时我们将唱片的列表在一个表格中显示
出来:

zf-tutorial/application/controllers/IndexController.php

function indexAction()

{

$this->view->title = “My Albums”;

$this->view->headTitle($this->view->title, ‘PREPEND’);

$albums = new Model_DbTable_Albums();

$this->view->albums = $albums->fetchAll();

}

首先我们为页面设置标题,然后把这引标题添加到head title的前面,显示在浏览器标题栏。

fetchAll函数返回一个Zend_Db_Table_Rowset对象,它允许我们在动作的视图脚本文件中遍历返回的记录。现
在我们可以填充相关的视图脚本index.phtml:

zf-tutorial/application/views/scripts/index/index.phtml

<p><a href=”<?php echo $this->url(array(‘controller’=>’index’,'action’=>’add’));?>”>Add new album</a></p>

<table>

<tr>

<th>Title</th>
<th>Artist</th>

<th>&nbsp;</th>

</tr>

<?php foreach($this->albums as $album) : ?>

<tr>

<td><?php echo $this->escape($album->title);?></td>

<td><?php echo $this->escape($album->artist);?></td>

<td>

<a href=”<?php echo $this->url(array(‘controller’=>’index’,

‘action’=>’edit’, ‘id’=>$album->id));?>”>Edit</a>

<a href=”<?php echo $this->url(array(‘controller’=>’index’,

‘action’=>’delete’, ‘id’=>$album->id));?>”>Delete</a>

</td>

</tr>

<?php endforeach; ?>

</table>

首先我们创建一下链向 “添加新唱片”的超链接。ZF提供的url()视图助手非常有助于创建包含正确baseurl的
超链接。我们只需要将需要的参数以数组的形式传递给它,剩下的工作它都自动完成。

下面我们创建一个html表格来显示每个唱片的标题和作者,并提供修改和删除唱片的链接。我们用一个标准的
foreach:循环来显示唱片列表。这里我们使用替代语法:用一个冒号和endforeach;,因为这样比使用配对大括号
更容易查看。同样的,我们可以使用url()视图助手来创建编辑和删除的链接。

打开http://localhost/zf-tutorial,应该显示一个不错的唱片列表

 

添加新唱片

我们可以开始编写添加新唱片的功能了。这部分包括两点:

• 提供一个表单让用户填写资料

• 处理提交的表单并添加到数据库中

我们使用Zend_From来做这个工作。Zend_Form组件可以用来创建表单和验证表单。我们创建一个扩展自
Zend_Form的新类Form_Album来定义我们的表单。因为我们使用模块自动加载,这个类应该存储在forms目录下
的Album.php文件中:

zf-tutorial/application/forms/Album.php

<?php

class Form_Album extends Zend_Form

{

public function   construct($options = null)

{

parent::  construct($options);

$this->setName(‘album’);

$id = new Zend_Form_Element_Hidden(‘id’);

$artist = new Zend_Form_Element_Text(‘artist’);

$artist->setLabel(‘Artist’)

->setRequired(true)

->addFilter(‘StripTags’)

->addFilter(‘StringTrim’)

->addValidator(‘NotEmpty’);

$title = new Zend_Form_Element_Text(‘title’);

$title->setLabel(‘Title’)

->setRequired(true)

->addFilter(‘StripTags’)

->addFilter(‘StringTrim’)

->addValidator(‘NotEmpty’);

$submit = new Zend_Form_Element_Submit(‘submit’);

$submit->setAttrib(‘id’, ‘submitbutton’);

$this->addElements(array($id, $artist, $title, $submit));

}

}

在form_Album的构造函数中,我们创建四个表单元素,分别用作id、artist、title和submit按钮。我们给每个
元素设置不同的属性,包括要显示的label。对text元素,我们添加两个过滤器-StripTags和StringTrim,来移
除不想要的HTML代码和空格。我们也可以设置他们是必填项,通过添加一个NotEmpty验证器来保证用户确实输
入了我们需要的信息。

现在我们需要显示这个表单,然后在提交后进行处理。这结都在IndexController的addAction()中做到:

zf-tutorial/application/controllers/IndexController.php

function addAction()

{

$this->view->title = “Add new album”;

$this->view->headTitle($this->view->title, ‘PREPEND’);

$form = new Form_Album();

$form->submit->setLabel(‘Add’);
$this->view->form = $form;

if ($this->getRequest()->isPost()) {

$formData = $this->getRequest()->getPost();

if ($form->isValid($formData)) {

$artist = $form->getValue(‘artist’);

$title = $form->getValue(‘title’);

$albums = new Model_DbTable_Albums();

$albums->addAlbum($artist, $title);

$this->_redirect(‘/’);

} else {

$form->populate($formData);

}

}

}

下面详解部分细节:

$form = new Form_Album();

$form->submit->setLabel(‘Add’);

$this->view->form = $form;

我们实例化Form_Album,将提交按钮的lable设置为 “Add”,然后定义到视图中以备显示。
if ($this->getRequest()->isPost()) {

$formData = $this->getRequest()->getPost();

if ($form->isValid($formData)) {

如果请求对象的isPost()方法返回真(true)则表示表单已经提交,然后使用getPost()获取表单数据,使用
isValid成员函数来判断是否有效。

$artist = $form->getValue(‘artist’);

$title = $form->getValue(‘title’);

$albums = new Model_DbTable_Albums();

$albums->addAlbum($artist, $title);

如果表单有效,则实例化Model_DbTable_Albums模型类,然后用我们之前创建addAlbum()方法向数据库中添加
一条新记录。

$this->_redirect(‘/’);

在我们保存这条新唱片记录后,利用控制器的_redirect()方法使页面重定向到首页。

} else {

$form->populate($formData);

}

如果表单数据无效,则将用户刚才填写的数据填充表单,并再次显示表单。现在我们需要在add.phtml视图脚本
中显示表单:
zf-tutorial/application/views/scripts/index/add.phtml

<?php echo $this->form ;?>

如你所见,显示一个表单非常简单,就好像表单自己知道如何去显示一样。

编辑唱片

编辑唱片跟添加唱片差不多是一样的,所以代码也差不多:

zf-tutorial/application/controllers/IndexController.php

function editAction()

{

$this->view->title = “Edit album”;

$this->view->headTitle($this->view->title, ‘PREPEND’);

$form = new Form_Album();

$form->submit->setLabel(‘Save’);

$this->view->form = $form;

if ($this->getRequest()->isPost()) {

$formData = $this->getRequest()->getPost();

if ($form->isValid($formData)) {

$id = (int)$form->getValue(‘id’);

$artist = $form->getValue(‘artist’);

$title = $form->getValue(‘title’);

$albums = new Model_DbTable_Albums();

$albums->updateAlbum($id, $artist, $title);

$this->_redirect(‘/’);

} else {

$form->populate($formData);

}

} else {

$id = $this->_getParam(‘id’, 0);

if ($id > 0) {

$albums = new Model_DbTable_Albums();

$form->populate($albums->getAlbum($id));

}

}

}

让我们看一下与添加唱片的不同。首先,在为用户显示表单的时候,我们需要读取数据库的唱片的作者和标
题,填充在表单中。这是这个方法的最后一部分:

$id = $this->_getParam(‘id’, 0);

if ($id > 0) {

$albums = new Model_DbTable_Albums();

$form->populate($albums->getAlbum($id));

}

当页面请求不是POST的时候,这部分会被执行。我们使用_getParam()方法从请求中获得id。然后用模型查询数
据库,并将结果直接显示在表单中。

在验证完表单后,我们需要把数据更新到当前操作的数据库记录中。这个工作由模型中的updateAlbum()方法完
成:

$id = (int)$form->getValue(‘id’);
$artist = $form->getValue(‘artist’);

$title = $form->getValue(‘title’);

$albums = new Model_DbTable_Albums();

$albums->updateAlbum($id, $artist, $title);

视图模板跟add.phtml一样:

zf-tutorial/application/views/scripts/index/edit.phtml

<?php echo $this->form ;?>

现在你就可以添加和编辑唱片信息了。

删除唱片

为了完善程序,我们需要增加删除功能。需要在唱片列表页的每个唱片后面加一个删除链接,当点击击该链接
时相应的唱片记录就会被删除,但这样做是错误的。记住我们的HTTP规范,对于不可逆的操作,不应该使用
GET,而应使用POST。
当用户点击删除链接时我们应该显示一个确认表单,如果在用户选择了“是”,我们就进行删除操作。因为这
个表单非常简单,我们直接将表单的HTML代码写到视图中。

先写IndexController::deleteAction()中的动作代码:

zf-tutorial/application/controllers/IndexController.php

public function deleteAction()

{

$this->view->title = “Delete album”;

$this->view->headTitle($this->view->title, ‘PREPEND’);

if ($this->getRequest()->isPost()) {

$del = $this->getRequest()->getPost(‘del’);

if ($del == ‘Yes’) {

$id = $this->getRequest()->getPost(‘id’);

$albums = new Model_DbTable_Albums();

$albums->deleteAlbum($id);

}

$this->_redirect(‘/’);

} else {

$id = $this->_getParam(‘id’, 0);

$albums = new Model_DbTable_Albums();

$this->view->album = $albums->getAlbum($id);

}

}

和添加和编辑时一样,我们通过使用请求对象的isPost()方法来确定是显示确认表单还是进行删除操作。实际
的删除操作是通过调用Model_DbTable_Albums()的deleteAlbum()方法来删除记录的。如果不是POST请求,就通
过id参数将相应的记录从数据库中读取出来并保存至视图中。

视图脚本是个简单的表单:

zf-tutorial/application/views/scripts/index/delete.phtml

<p>Are you sure that you want to delete

‘<?php echo $this->escape($this->album['title']); ?>’ by

‘<?php echo $this->escape($this->album['artist']); ?>’?

</p>

<form action=”<?php echo $this->url(array(‘action’=>’delete’)); ?>” method=”post”>

<div>

<input type=”hidden” name=”id” value=”<?php echo $this->album['id']; ?>” />

<input type=”submit” name=”del” value=”Yes” />

<input type=”submit” name=”del” value=”No” />

</div>

在这个脚本中,我们先给用户显示一条警告信息,然后是一个包含 “Yes”和 “No”按钮的表单。在动作代码中
做删除操作时先检查是否含有“Yes”值。

现在你有了一个完整可用的程序了。

发表评论

电子邮件地址不会被公开。 必填项已被标记为 *

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>