• 1. Zend Framework
  • 2. 主要内容什么是框架 PHP开发是否需要框架 如何使用框架进行PHP开发 Zend Framework简介 分别使用传统方式和Zend Framework开发一个文章管理发布系统 细节问题 MVC,数据库,模板,权限控制,AJAX等
  • 3. 什么是框架?框架,即Framework。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。注意,框架体现了程序的设计思想,但又不只是规划性的东西,它已经实现了部份核心代码。 简单说就是使用别人搭好的舞台,你来做表演,但你要按照一定的规则。 框架一般是成熟的,不断升级的软件。
  • 4. PHP开发是否需要框架使用框架的好处 面向对象开发,有成熟的设计思想可以借鉴 MVC分层,避免业务层与表现层混合,有利于后续开发 有固定的程序结构和编码规范,代码易分享,有利于团队协作
  • 5. MVC绝大部份PHP框架以MVC模式为基础来划分结构: 模型(Model):就是封装数据和所有基于对这些数据的操作。业务层 视图(View):就是封装的是对数据显示,即用户界面。表现层 控制器(Controller):就是封装外界作用于模型的操作和对数据流向的控制等。
  • 6. 使用框架开发PHP框架层出不穷,现在最流行的有: Zend Framework CakePHP Symphony Seagull
  • 7. 使用Zend Frameworkapp目录为站点的核心部份 www目录为向公众开放的部份
  • 8. ZF内部
  • 9. 控制器 ControllerController“肥大”问题,拆分 ZF提供的控制器“Module”功能,可以把ArticleController.php 拆分成一个目录下的多个文件article = new Article(); } public function listAction() { $articles = $this->article->fetchAll($where, $order); $this->view->articles = $articles; echo $this->view->render($this->tplDir.'articleList.php'); } public function editAction(){} ?>
  • 10. 模型 Modelinsert($data); } catch (PDOException $e) { echo "Exception caught : {$e->getMessage()}\n"; exit; } } } ?>Zend_Db_Table类似于大家常用的mysql.class.php,但更强大,默认绑定了数据表,各种查询方法,大部份情况下不用写sql;使用PDO,更加安全。
  • 11. 视图 View
  • 12. Zend_View Zend_Config Zend_Session+Zend_Auth+Zend_Acl 用户认证、权限、状态维持 “三件套”
  • 13. 访问方式Zend Framework http://phpchina.com/article/view/id/2 传统方式: http://phpchina.com/article.php?action=view&id=2 思考:哪种对搜索引擎友好?
  • 14. 总结:使用框架开发易于维护,改进和扩展 通过类的继承和类方法的覆写,非常方便可以定制出自己想要的扩展后的对象。 易于分享给第三方程序员,如发布一个API 这是为什么大家分享PHP代码时,都是写成类库,而不是函数的原因。
  • 15. 概述Zend Framework(以后简称ZF) Zend类是整个Zend Framework的基类,这个类只包含静态方法,这些类方法具有ZF中的很多组件都需要的功能。 (Zend类是个功能性的类,它只包含静态方法,也就是说,不需要实例化就可以直接调用Zend的各种功能方法/函数。通俗地说,Zend类相当于我们熟悉的functions.inc.php,而且是corefunctions.inc.php,提供了最核心最常用的函数。
  • 16. 获取Zend Framework从http://framework.zend.com/download下载 安装Zend Framework
  • 17. 环境配置Apache:编辑httpd.conf文件 找到 :#LoadModule rewrite_module modules/ mod_rewrite.so 这行并将前面的"#"去掉。 找到:AllowOverride None           更改为:           AllowOverride All,才能让.htaccess文件起作用 PHP:配置php.ini文件 找到下面这几行,并将前面的分号去掉,安装PDO模块 ;extension=php_pdo.dll ;extension=php_pdo_mysql.dll
  • 18. 目录结构通用框架目录结构项目URL:http://localhost/zf-tutorial
  • 19. application:放置应用程序 controllers:放置控制器 models:放置模型 views:放置视图 library:放置ZendFramework框架文件和其他库文件 public:放置资源文件 images:放置图像 js:放置javascript脚本文件 css:放置css样式表文件分析目录
  • 20. 启动文件ZF框架的控制器Zend Controller,被设计支持使用clean urls的网站,为实现这个目的,所有请求需要通过单一的index.php文件,这就是所谓的启动文件(bootstrapper)。 启动文件提供了程序中所有页面的中心点并确保运行环境配置正确。我们使用.htaccess文件来实现这个目标
  • 21. .htaccesspublic/.htaccess # Zend Framework rewrite规则 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php #任何url重定向到index.php # 安全性考虑:不允许列表目录内容 Options -Indexes # PHP设置 php_flag magic_quotes_gpc off php_flag register_globals off php_flag short_open_tag on
  • 22. index.phppublic/index.php是我们的启动文件 throwExceptions(true);//设置异常属性 $frontController->setControllerDirectory('../application/controllers'); //设置控制器路径 //run $frontController->dispatch();//执行输出
  • 23. 注意part1部分:设置确保看到我们的错误,选择自己的时区。 Part2部分:目录设置和类装载,所有文件要包含在include path中,同时也将模型目录加入到包含路径中,以便将来方便装入模型类。然后再包含Zend/Loader.php文件,以便访问Zend_Loader类。最后调用registerAutoload()方法,这样以后我们实例化ZF对象时就可以自动装入相应的文件。 setup controller部分:必须设置前端控制器去哪个目录找我们的控制器类,设置抛出所有异常显示在页面上。(注:前端控制器用路由类来映射请求的URL 到正确的PHP 函数,然后显示页面) run部分:运行我们的程序 结尾没有放?>因为在文件的结尾它不是必需的。这样可以避免产生一些难于调试的错误问题。例如,我们在使用header()函数来重定向(redirect)时,如果在 ?> 后面不小心加上了空格就会出现问题。
  • 24. 组织页面需求:建立一个简单的库存系统网站,来管理我们的图书收藏,在主页上将列出我们的图书并允许添加、编辑和删除这些图书。页面说明主页显示数据列表并提供添加、编辑和删除的链接添加页添加一个新图书的表单编辑页编辑一个图书的表单删除页确认是否删除一个图书,然后删除它
  • 25. ZF组织页面每个应用程序的页面叫做“action”,许多“action”组成控制器,例如: http://localhost/zf-tutorial/public/news/view 控制器:news action:view 允许把相关的action组织成组,例如一个news控制器可以有current、archived和view等多个actions ZF的MVC系统也支持把控制器组成模块
  • 26. 缺省控制器和actionZF保留了一个缺省的控制器为index ZF控制器保留了一个缺省的action为index http://localhost/zf-tutorial/将执行index控制器下的action index http://localhost/zf-tutorial/news/将执行news控制器下的action index
  • 27. 安排控制器和action页面控制器action主页indexindex添加页indexadd编辑页indexedit删除页indexdelete
  • 28. 设置控制器在ZF中,控制器是一个必须按照一定规则定义的类 类名:{控制器名Controller}必须以大写开头,其他字母一定是小写 扩展:继承Zend_Controller_Action类 函数:{action名Action}必须以小写字母开头 类文件:跟类名相同的.php文件 存放位置:zf-tutorial/application/controllers/
  • 29. IndexController.php in IndexController::indexAction()

    "; } function addAction(){ echo "

    in IndexController::addAction()

    "; } function editAction(){ echo "

    in IndexController::editAction()

    "; } function deleteAction(){ echo "

    in IndexController::deleteAction()

    "; } } ?>
  • 30. 添加视图添加视图文件,这些文件就是模板文件,视图允许我们把显示页面的代码从action中分离出来。这些模板文件必须使用action名来定义,扩展名使用phtml,保存在以下目录中 zf-tutorial/application/views/scripts/index/index.phtml zf-tutorial/application/views/scripts/index/add.phtml zf-tutorial/application/views/scripts/index/edit.phtml zf-tutorial/application/views/scripts/index/delete.phtml
  • 31. 设置视图ZF的视图叫Zend_View,是用来在MVC模式中处理View(视图)部份的一个类。也就是说它用来使视图部份的代码与Model及Controller分离。它提供了helper,output filter,variable escaping等几个功能组件。 Zend_View的初始化用法: $view = new Zend_View(); $view->setScriptPath('/path/to/view_files'); echo $view->render('viewScript.php');
  • 32. 使用控制器初始化视图使用Zend_View主要有两步: 1. 你的Controller建立一个Zend_View实例,并将需要的变量传递给它; 2. Controller告诉Zend_View显示一个特定的视图,生成View输出的内容。 初始化视图 view:视图属性 通知Zend_View对象在views/scripts/{controller name}目录中查找显示脚本,然后显示与动作名称相同,扩展名为.phtml的显示脚本 即显示的视图文件名为views/scripts/{controller name}/{action name}.phtml,
  • 33. IndexController.php view->title=“我的图书馆”;//给view属性添加title属性 } function addAction(){ $this->view->title=“添加新的图书”; } //…………… } ?>
  • 34. 编辑视图文件index.phtml
    <?php echo $this->escape($this->title); ?>

    escape($this->title); ?>

  • 35. 共同的HTML代码在我们的视图里有许多相同的HTML 代码,因此我们使用Zend_Layout组件来解决这个问题,Zend_Layout允许我们将相同的头部和尾部代码移到独立的布局显示脚本中。确定布局保存位置: zf-tutorial/appliaction/layouts/layout.phtml 清空index.phtml、add.phtml……
  • 36. 启用Zend_Layoutindex.php Zend_Layout::startMvc(array('layoutPath'=>'../application/layouts')); //dispath() ---启动之前添加启用Zend_Layout
  • 37. layout.phtml <?php echo $this->escape($this->title); ?>

    escape($this->title); ?>

    layout()->content; ?>
  • 38. 风格为了使我们的网站更为美观,要定位CSS文件,因为URL并不是指向正确的根目录,这需要创建自己的视图辅助函数baseUrl(),它通过收集请求对象的相关信息使我们可以得到不知道的URL,并把它传递给视图
  • 39. 视图助手在你的视图脚本中,经常需要执行某些特定的复杂的函数,例如,格式化日期,生成表单对象,或者显示action的链接等等。你可以使用助手类来完成这些工作。 视图辅助类 保存在application/views/helpers文件夹中 文件名为{Helper name}.php(文件名第一个字母大写) 视图辅助类名必须是Zend_View_Helper_{Helper name}形式(每个单词第一个字母大写) 在这个类中,必须有一个名为{helper name}()的函数(函数名第一个字母小写)
  • 40. BaseUrl.phpgetBaseUrl(); } } ?>
  • 41. 添加样式layout.phtml public/css/site.css body,html { margin: 0 5px; font-family: Verdana,sans-serif; } h1 { font-size:1.4em; color: #008000; }
  • 42. 数据库我们已将程序的控制与视图分离开来了,继续我们的例子,接下来是存取数据库。 我们将利用ZF提供的Zend_Db_Table类,该类是ZF的表模块,可以来进行查找、插入、修改和删除数据库表中的记录。
  • 43. 连接数据库Zend_Db_Adapter是ZF的数据库抽象层API。 基于PDO,你可以使用它连接和处理多种数据库,包括:SQL Server,MySql,SQLite等等。 针对不同的数据库实例化一个Zend_Db_Adapter对象, 需要将adapter的名字和描述数据库连接的参数数组作为参数,静态调用 Zend_Db::factory()方法。
  • 44. 什么是PDOPHP Data Object(PDO)是PHP一个扩展. 它定义了一个简便持久访问数据库的方法. 我们可以方便地使用一组定义好的函数来访问每个实现了PDO的数据库. PDO提供了一组访问数据库的抽象方法, 也就是说, 不论访问何种类型的数据库, 我们只用同样名称的方法访问就可以了, 这样就大大简便了数据库操作。
  • 45. PDO安装(参考)extension=pdo.so extension=pdo_MySQL.so extension=php_pdo.dll extension=php_pdo_firebird.dll extension=php_pdo_informix.dll extension=php_pdo_mssql.dll extension=php_pdo_mysql.dll extension=php_pdo_oci.dll extension=php_pdo_oci8.dll extension=php_pdo_odbc.dll extension=php_pdo_pgsql.dll extension=php_pdo_sqlite.dll
  • 46. '127.0.0.1', 'username'=> 'root', 'password' =>‘123', 'dbname' =>'books'); $db = Zend_Db::factory('PDO_MYSQL', $params); // 为所有的Zend_Db_Table对象设定默认的adapter require_once 'Zend/Db/Table.php'; Zend_Db_Table::setDefaultAdapter($db); ?> 初始化数据库连接
  • 47. 配置文件为了访问数据库,必须先配置使用的数据库及登录数据库的用户名密码等信息,把这些信息保存在配置文件中,更便于以后的更新,配置文件存放在application目录下,或者存在在单独目录中application/config 使用Zend_Config来提供灵活的面向对象访问配置文件,配置文件可以是PHP数组、一个INI文件或者XML文件。
  • 48. config.ini[general] db.adapter=PDO_MYSQL db.params.host=localhost db.params.username=root db.params.password=root db.params.dbname=bookdb db.params.charset=gb2312
  • 49. Zend_Config在index.php中添加 // load configuration $config = new Zend_Config_Ini('../application/config.ini', 'general'); $registry = Zend_Registry::getInstance(); $registry->set('config', $config); // setup database $db = Zend_Db::factory($config->db); $db->query(“SET NAMES ‘”.$config->db->params->charset.“’”); //设置字符集 Zend_Db_Table::setDefaultAdapter($db);//设置默认适配器
  • 50. //load configuration 构造Zend_Config_Ini和Zend_Registry对象 读取config.ini配置文件中“general”节中的数据 保存$config对象到$registry对象中,留以后其他地方使用 // setup database 创建Zend_Db对象,并读取配置信息 设置操作数据库字符集 通过Zend_Db对象的静态方法将db注册到Zend_Db_Table中
  • 51. 模型现在该是考虑模型的时候了。记住,模型是用来处理程序的核心议题(即所谓的“商业规则”business rules) 管理我们的图书是我们要考虑的业务核心,使用Zend_Db_Table类来完成这个功能,由于它是抽象类,所以我们继承它来创建管理图书的数据库模型
  • 52. Zend_Db_TableZend_Db_Table 是Zend Framework的表模块。它通过zend_db_adapter连接到 数据库,为数据库模式检查表对象,并对该表进行操作和查询。 Zend_DB_Table为抽象类,所以不能直接实例化,只能先继承该类,然后实例化子类
  • 53. 扩展Zend_Db_Table模型根据操作的数据库来创建 类名:使用的数据库表名 属性:设置$_name属性为要操作的表名 存放路径: application\models\Books.php
  • 54. 数据库操作插入数据 /*insert book(id,name,title) values('201','alex','PHP')*/ $books=new Books(); $data=array('id'=>'201', 'name'=>'alex', 'title'=>'PHP'); $id=$books->insert($data);//返回插入数据行号
  • 55. 更新数据 /*update books set name='alex0018' where id='201'*/ $books=new Books(); $db=$books->getAdapter(); $set=array('name'=>'alex0018'); $where=$db->quoteInto('id=?','201'); $row_affected=$books->update($set,$where); //返回更新行数
  • 56. 删除数据 /*delete from books where name='alex0018'*/ $books=new Books(); $db=$books->getAdapter(); $where=$db->quoteInto('name=?','alex0018'); $row_affected=$books->delete($where); //返回删除行数
  • 57. Zend_Db_Table_Row该类不能实例化,只能通过调用Zend_Db_Table::find()方法或者Zend_Db_Table::fetchRow()做为结果数据返回过来,一旦得到对象还可以进行记录值的修改等操作。
  • 58. 取回一条记录和修改一条记录 $books = new Books(); // 从表中取回的结果数据是一个Zend_Db_Table_Row对象 $row = $books->fetchRow('name = "alex"'); // $row现在是一个带有多种公有属性的Zend_Db_Table_Row对象 // that map to table columns:// // $row->id = '201' // $row->name = 'alex' // $row->title = 'PHP‘ // $row->save(); 保存修改,但不能修改主键
  • 59. 设置查询条件取回一条记录 /*select * from books where title='PHP' and name='alex' order by id*/ $books=new Books(); $db=$books->getAdapter(); $where=$db->quoteInto('title=?','PHP') . $db->quoteInto(' and name=?','alex'); $order='id'; $row=$books->fetchRow($where,$order); //返回满足条件的第一行数据的Zend_Db_Table_Row对象.
  • 60. Zend_Db_Table_RowsetZend_Db_Table_Rowset是 Zend_Db_Table_Row对象集合的迭代器。通常来说,你不可以自己实例化该对象,而是通过调用Zend_Db_Table::find()方法或者fetchAll()方法将Zend_Db_Table_Rowset作为结果数据返回过来,接下来就可以遍历Zend_Db_Table_Row对象集合并进行修改
  • 61. 根据主键查找数据 $books=new Books(); /*select * from books where id='201'*/ $rows=$books->find(201); /*select * from books where id in('201', '202', '203',)*/ $rows=$books->find(array(201,202,203)); //返回满足条件的Zend_Db_Table_Rowset对象 $rows=$books->fetchAll(); //返回所有的记录
  • 62. 取回多条记录 $books=new Books(); $db = $books->getAdapter(); /*select * from books where title='PHP' order by id limit 10 offset 20*/ $where = $db->quoteInto('title=?', 'PHP'); $order = 'id'; $count = 10; $offset = 20; $rowset = $books->fetchAll($where, $order, $count, $offset); //返回满足条件的数据的Zend_Db_Table_Rowset对象
  • 63. 程序核心部分显示图书列表 添加图书 编辑图书 删除图书
  • 64. 显示图书列表控制器 function indexAction(){ $this->view->title="我的图书馆"; $books = new Books(); $this->view->books = $books->fetchAll(); }
  • 65. 视图: application\views\scripts\index\index.phtml

    添加图书

    books as $book) : ?>
    Title Name  
    escape($book->title);?> escape($book->name);?> 编辑 删除
  • 66. 样式:public/css/site.css /* Table */ th { text-align: left; } td, th { padding-right: 5px; }
  • 67. 添加图书添加图书包括两个工作 显示一个表单供用户输入详细的图书信息 处理提交的表单,将图书信息保存到数据库中 使用Zend_Form来完成这个工作,Zend_Form组件可以用来创建输入表单并对用户的输入信息进行验证。我们引入一个新的继承自Zend_Form的模型类BookForm来定义该表单
  • 68. Zend_Form获取用户数据的最简单方式就是使用表单,ZF提供Zend_Form可以完成复杂的验证并在表单验证失败时在表单中显示错误信息。 Zend_Form附带了:按钮、复选框、隐藏、图片、多选框、密码、单选、重置、提交、文本、文本域等元素,内置的Zend_Form_Element类允许您创建自己的元素 application/models/BookForm.php
  • 69. 一个简单的表单require_once "Zend_Form.php"; $form=new Zend_Form(array( 'method'=>'post', 'elements'=>array( 'name'=>array('text', array('required'=>true, 'label'=>'Name', 'validators'=>array('alpha') )), 'age'=>array('text', array('required'=>true, 'label'=>'Name', 'validators'=>array('digits') )), 'submit'=>array('submit', array('label'=>'send' )) ) ));
  • 70. setName('book'); //$id = new Zend_Form_Element_Hidden('id'); $id = new Zend_Form_Element_Text('id'); $id->setLabel('Id')->setRequired(true) ->addFilter('StripTags')->addFilter('StringTrim') ->addValidator('NotEmpty'); $name = new Zend_Form_Element_Text('name'); $name->setLabel('Name')->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, $name, $title, $submit)); } } ?>
  • 71. 在BookForm的构造函数中,我们创建了包括四个元素的表单:id, name, title和submit按钮。每个元素都设置了不同的属性,包括要显示的文本标签。 对于文本元素,我们增加了两个过滤器,StripTags和StringTrim,它们分别用来删除不必要的HTML标记和不必要的空格。我们还将它们设置为必需的字段,通过添加一个NotEmpty验证器来保证用户确实输入了我们需要的信息。 现在我们需要显示这个表单,并能在表单提交后进行处理。这可以通过addAction()来实现
  • 72. 控制器 function addAction(){ //part1 $this->view->title="添加图书"; $form = new BookForm(); $form->submit->setLabel('Add'); $this->view->form = $form; //part2 if ($this->_request->isPost()) { $formData = $this->_request->getPost(); if ($form->isValid($formData)) { //part3 $books = new Books(); $row = $books->createRow();//添加一条新记录 $row->id = $form->getValue('id'); $row->name = $form->getValue('name'); $row->title = $form->getValue('title'); $row->save(); $this->_redirect('/'); } else { //part4 $form->populate($formData); } } }
  • 73. Part1:创建一个BookForm的实例,提交按钮标签改为“Add”,然后将$form保存到视图中去,以便以后显示它。 Part2:使用请求对象的isPost()判断表单是否为提交状态,再使用getPost()从请求对象中获取表单提交的数据,然后用isValid()来验证表单是否有效。 Part3:如果表单有效,创建一个新的Books对象,使用createRow()来生成一条新记录,然后填充数据,最后保存到数据库中,保存完成后使用控制器的_redirect()重定向到主页上。 Part4:如果表单无效,则将用户输入的数据重新添回表单重新显示给用户。
  • 74. 视图:application\views\scripts\index\add.phtml form ;?>
  • 75. 修改图书信息类似添加图书
  • 76. 控制器 function editAction(){ $this->view->title="编辑图书"; $form = new BookForm(); $form->submit->setLabel('Save'); $this->view->form = $form; if ($this->_request->isPost()) { $formData = $this->_request->getPost(); if ($form->isValid($formData)) {//part2 $books = new Books(); $id = (int)$form->getValue('id'); $row = $books->fetchRow('id='.$id); $row->name = $form->getValue('name'); $row->title = $form->getValue('title'); $row->save(); $this->_redirect('/'); } else { $form->populate($formData); } } else { //part1 books id is expected in $params['id'] $id = (int)$this->_request->getParam('id', 0); if ($id > 0) { $books = new Books(); $book = $books->fetchRow('id='.$id); $form->populate($book->toArray()); } } }
  • 77. Part1:如果请求不是POST,那么将执行这个填充过程,它通过模型从数据库中获取记录的值。我们可以使用Zend_Db_Table_Row类的成员函数toArray()来直接填充表单。 Part2:最后我们需要将数据重新写回数据库的相应记录。这可以通过先获取相应记录,再保存该记录的方式来实现。
  • 78. 视图: application\views\scripts\index\edit.phtml form ;?>
  • 79. 删除图书在主页的图书列表中每本图书都有一个删除该图书的链接,当点击该链接时,相应的图书记录就会被删除,但这样做是错误的。请再回顾我一下我们的HTTP规范,对于不可逆的动作我们不应该使用GET而应使用POST。 当用户点击删除链接时我们应该显示一个确认表单,只有在用户选择了“是”的时候我们才做这个删除操作。
  • 80. 控制器 function deleteAction(){ $this->view->title="删除图书"; if ($this->_request->isPost()) { $id = (int)$this->_request->getPost('id'); $del = $this->_request->getPost('del'); if ($del == 'Yes' && $id > 0) { $books = new Books(); $where = 'id = ' . $id; $books->delete($where); } $this->_redirect('/'); } else { $id = (int)$this->_request->getParam('id'); if ($id > 0) { $books = new Books(); $this->view->book = $books->fetchRow('id='.$id); } } }
  • 81. 视图:application\views\scripts\index\delete.phtml book) :?>

    Are you sure that you want to delete 'escape($this->book->title); ?>' by 'escape($this->book->name); ?>'?

    Cannot find book.

  • 82. 备注如果index/index之外的动作出现问题,通常是因为路由类不能确定你的网站在哪个子目录下。这通常是由于网站的url与web根目录的路径不同。 如果默认的代码不能工作,你应该将$baseURL设置成你的服务器的正确路径 你应该将‘/mysubdir/zf-tutorial/public’替换成访问index.php的正确的路径。 例如:访问index.php的路径是 http://localhost/ralle/zf-tutorial/public/index.php,那么$baseUrl就是/ralle/zf-tutorial/public
  • 83. index.php// setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setControllerDirectory('../application/controllers'); $frontController->setBaseUrl('/mysubdir/zf-tutorial/public'); Zend_Layout::startMvc(array('layoutPath'=>'../application/layouts'));
  • 84. Zend_Auth准备工作 确保Session可用 创建一个用户管理的数据库,并添加一个用户记录 创建一个登录表单 创建一个控制器,包含登录与登出的动作 修改footer来允许登出 确保用户必须在登录之后方可访问程序
  • 85. 修改index.php// setup database $db = Zend_Db::factory($config->db); Zend_Db_Table::setDefaultAdapter($db); $registry->set("db",$db);
  • 86. Auth控制器类application/controllers/AuthController.php class AuthController extends Zend_Controller_Action{ function init(){ //默认返回到主页面 $this->initView(); $this->view->baseUrl = $this->_request->getBaseUrl(); } function indexAction(){//默认返回到主页面 $this->_redirect("/"); } }
  • 87. 登录视图application/views/scripts/auth/login.phtml message)) :?>
    escape($this->message);?>
  • 88. 登录控制器 function loginAction() { $this->view->message = ''; $this->view->title = "Log in"; }
  • 89. 登录验证if ($this->_request->isPost()) { // 收集用户的录入信息collect the data from the user Zend_Loader::loadClass(‘Zend_Filter_StripTags’);//去出标签 $f = new Zend_Filter_StripTags(); $username = $f->filter($this->_request->getPost('username')); $password = $f->filter($this->_request->getPost('password')); if (empty($username)) { $this->view->message = 'Please provide a username.'; }
  • 90. else { // 设置Zend_Auth数据库表适配器setup Zend_Auth adapter for a database table Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable'); $db = Zend_Registry::get('db'); $authAdapter = new Zend_Auth_Adapter_DbTable($db); $authAdapter->setTableName('users'); $authAdapter->setIdentityColumn('username'); $authAdapter->setCredentialColumn('password'); // 设置需要认证的用户信息 $authAdapter->setIdentity($username); $authAdapter->setCredential($password); // 认证 $auth = Zend_Auth::getInstance(); $result = $auth->authenticate($authAdapter);
  • 91. if ($result->isValid()) { // success: store database row to auth's storage // system. (Not the password though!) $data = $authAdapter->getResultRowObject(null, 'password'); $auth->getStorage()->write($data); $this->_redirect('/'); } else { // failure: clear database row from session $this->view->message = 'Login failed.'; } } }
  • 92. 登出控制器 function logoutAction() { Zend_Auth::getInstance()->clearIdentity(); $this->_redirect('/'); }
  • 93. 显示用户名修改控制器init() function init() { //……… $this->view->user = Zend_Auth::getInstance()->getIdentity(); }
  • 94. 修改视图,添加显示信息 user) : ?>

    Logged in as escape($this->user->real_name); ?>. Logout

  • 95. 保护动作IndexController.php//session保护 function preDispatch() { $auth = Zend_Auth::getInstance(); if (!$auth->hasIdentity()) { $this->_redirect('auth/login'); } }
  • 96. 谢谢