最新Zend Framework(共87张PPT课件).pptx
Zend Framework第一页,共八十七页。主要(zhyo)内容p什么是框架pPHP开发是否(sh fu)需要框架p如何使用框架进行PHP开发nZend Framework简介n分别使用传统方式和Zend Framework开发一个文章管理发布系统p细节问题 nMVC,数据库,模板,权限控制,AJAX等第二页,共八十七页。什么(shn me)是框架?p框架,即Framework。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。注意,框架体现了程序的设计思想,但又不只是规划性的东西,它已经实现了部份核心代码。p简单说就是使用别人搭好的舞台,你来做表演(bioyn),但你要按照一定的规则。p框架一般是成熟的,不断升级的软件。第三页,共八十七页。PHP开发是否(sh fu)需要框架使用框架的好处p面向对象开发,有成熟的设计思想可以借鉴pMVC分层,避免业务层与表现层混合,有利于后续(hux)开发p有固定的程序结构和编码规范,代码易分享,有利于团队协作第四页,共八十七页。MVC绝大部份PHP框架以MVC模式为基础来划分结构:p模型(Model):就是封装数据和所有(suyu)基于对这些数据的操作。业务层p视图(View):就是封装的是对数据显示,即用户界面。表现层p控制器(Controller):就是封装外界作用于模型的操作和对数据流向的控制等。 第五页,共八十七页。使用框架(kun ji)开发pPHP框架层出不穷(cng ch b qing),现在最流行的有:pZend FrameworkpCakePHPpSymphonypSeagull第六页,共八十七页。使用(shyng)Zend Frameworkapp目录为站点的核心(hxn)部份www目录为向公众开放的部份第七页,共八十七页。ZFZF内部内部(nib)(nib)第八页,共八十七页。p控制器 ControllerController“肥大”问题,拆分ZF提供的控制器“Module”功能,可以把ArticleController.php拆分成一个(y )目录下的多个文件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()?第九页,共八十七页。p模型(mxng) Modelinsert($data); catch (PDOException $e) echo Exception caught : $e-getMessage()n; exit; ?Zend_Db_Table类似于大家常用(chn yn)的mysql.class.php,但更强大,默认绑定了数据表,各种查询方法,大部份情况下不用写sql;使用PDO,更加安全。第十页,共八十七页。p视图(sht) View第十一页,共八十七页。访问(fngwn)方式pZend Frameworkhttp:/ sh)pZend Framework(以后(yhu)简称ZF)pZend类是整个Zend Framework的基类,这个类只包含静态方法,这些类方法具有ZF中的很多组件都需要的功能。 (Zend类是个功能性的类,它只包含静态方法,也就是说,不需要实例化就可以直接调用Zend的各种功能方法/函数。通俗地说,Zend类相当于我们熟悉的functions.inc.php,而且是corefunctions.inc.php,提供了最核心最常用的函数。第十四页,共八十七页。获取(huq)Zend Frameworkp从http:/ zi)p安装Zend Framework第十五页,共八十七页。环境(hunjng)配置Apache:编辑httpd.conf文件n找到 :#LoadModule rewrite_module modules/mod_rewrite.so 这行并将前面的#去掉。n找到:AllowOverride None 更改为: AllowOverride All,才能让.htaccess文件起作用(zuyng)pPHP:配置php.ini文件n找到下面这几行,并将前面的分号去掉,安装PDO模块;extension=php_pdo.dll ;extension=php_pdo_mysql.dll第十六页,共八十七页。目录(ml)结构通用(tngyng)框架目录结构项目(xingm)URL:http:/localhost/zf-tutorial第十七页,共八十七页。papplication:放置应用程序ncontrollers:放置控制器nmodels:放置模型nviews:放置视图plibrary:放置ZendFramework框架文件和其他库文件ppublic:放置资源(zyun)文件nimages:放置图像njs:放置javascript脚本文件ncss:放置css样式表文件分析(fnx)目录第十八页,共八十七页。启动(qdng)文件pZF框架的控制器Zend Controller,被设计支持(zhch)使用clean urls的网站,为实现这个目的,所有请求需要通过单一的index.php文件,这就是所谓的启动文件(bootstrapper)。p启动文件提供了程序中所有页面的中心点并确保运行环境配置正确。我们使用.htaccess文件来实现这个目标第十九页,共八十七页。.htaccessppublic/.htaccess# Zend Framework rewrite规则(guz) 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 第二十页,共八十七页。index.phpppublic/index.php是我们的启动(qdng)文件throwExceptions(true);$frontController-setControllerDirectory(./application/controllers);/run$frontController-dispatch();第二十一页,共八十七页。注意(zh y)ppart1部分:设置确保看到我们的错误,选择自己的时区。pPart2部分:目录设置和类装载,所有文件要包含在include path中,同时也将模型目录加入到包含路径中,以便将来方便装入模型类。然后再包含Zend/Loader.php文件,以便访问Zend_Loader类。最后调用registerAutoload()方法,这样以后我们实例化ZF对象时就可以自动装入相应的文件。psetup controller部分:必须设置前端控制器去哪个目录找我们的控制器类,设置抛出所有异常显示在页面上。(注:前端控制器用路由类来映射请求的URL 到正确的PHP 函数,然后显示页面)prun部分:运行我们的程序p结尾没有放?因为在文件的结尾它不是必需的。这样可以避免产生一些难于调试的错误问题。例如,我们在使用(shyng)header()函数来重定向(redirect)时,如果在 ? 后面不小心加上了空格就会出现问题。第二十二页,共八十七页。组织(zzh)页面p需求:建立一个简单的库存系统网站,来管理我们的图书收藏,在主页(zh y)上将列出我们的图书并允许添加、编辑和删除这些图书。页面页面说明说明主页显示数据列表并提供添加、编辑和删除的链接添加页添加一个新图书的表单编辑页编辑一个图书的表单删除页确认是否删除一个图书,然后删除它第二十三页,共八十七页。ZF组织(zzh)页面p每个应用程序的页面叫做“action”,许多“action”组成控制器,例如:http:/localhost/zf-tutorial/public/news/viewn控制器:newsnaction:viewp允许把相关的action组织成组,例如一个news控制器可以有current、archived和view等多个(du )actionspZF的MVC系统也支持把控制器组成模块第二十四页,共八十七页。缺省控制器和actionpZF保留了一个(y )缺省的控制器为indexpZF控制器保留了一个缺省的action为indexnhttp:/localhost/zf-tutorial/将执行index控制器下的action indexnhttp:/localhost/zf-tutorial/news/将执行news控制器下的action index第二十五页,共八十七页。安排(npi)控制器和action页面页面控制器控制器action主页indexindex添加页indexadd编辑页indexedit删除页indexdelete第二十六页,共八十七页。设置(shzh)控制器p在ZF中,控制器是一个必须按照一定规则定义的类n类名(li mn):控制器名Controller必须以大写开头,其他字母一定是小写n扩展:继承Zend_Controller_Action类n函数:action名Action必须以小写字母开头n类文件:跟类名相同的.php文件n存放位置:zf-tutorial/application/controllers/第二十七页,共八十七页。pIndexController.php?phpclass IndexController extends Zend_Controller_Actionfunction indexAction()echo in IndexController:indexAction();function addAction()echo in IndexController:addAction();function editAction()echo in IndexController:editAction();function deleteAction()echo in IndexController:deleteAction();?第二十八页,共八十七页。p public function noRouteAction() $this-_redirect(/); 例如,在FooController.php不存在的条件(tiojin)下,访问/foo/bar就会执行noRouteAction()。但是访问/index/foo仍会出错,因为foo是action,而不是controller. 第二十九页,共八十七页。添加(tin ji)视图p添加视图文件,这些文件就是(jish)模板文件,视图允许我们把显示页面的代码从action中分离出来。这些模板文件必须使用action名来定义,扩展名使用phtml,保存在以下目录中zf-tutorial/application/views/scripts/index/index.phtmlzf-tutorial/application/views/scripts/index/add.phtmlzf-tutorial/application/views/scripts/index/edit.phtmlzf-tutorial/application/views/scripts/index/delete.phtml第三十页,共八十七页。设置(shzh)视图pZF的视图(sht)叫Zend_View,是用来在MVC模式中处理View(视图)部份的一个类。也就是说它用来使视图部份的代码与Model及Controller分离。它提供了helper,output filter,variable escaping等几个功能组件。 pZend_View的初始化用法:$view = new Zend_View();$view-setScriptPath(/path/to/view_files);echo $view-render(viewScript.php);第三十一页,共八十七页。使用(shyng)控制器初始化视图p使用Zend_View主要有两步:n 1. 你的Controller建立一个Zend_View实例,并将需要的变量传递给它; n2. Controller告诉Zend_View显示一个特定的视图,生成View输出的内容。 p初始化视图nview:视图属性n通知Zend_View对象在views/scripts/controller name目录中查找显示脚本,然后(rnhu)显示与动作名称相同,扩展名为.phtml的显示脚本即显示的视图文件名为views/scripts/controller name/action name.phtml,第三十二页,共八十七页。pIndexController.phpview-title=“我的图书馆我的图书馆”;/给给view属性属性(shxng)添加添加title属性属性function addAction()$this-view-title=“添加新的图书添加新的图书”;/?第三十三页,共八十七页。编辑(binj)视图文件pindex.phtmlescape($this-title); ?escape($this-title); ?第三十四页,共八十七页。共同(gngtng)的HTML代码p在我们的视图里有许多(xdu)相同的HTML 代码,因此我们使用Zend_Layout组件来解决这个问题,Zend_Layout允许我们将相同的头部和尾部代码移到独立的布局显示脚本中。确定布局保存位置:nzf-tutorial/appliaction/layouts/layout.phtmln清空index.phtml、add.phtml第三十五页,共八十七页。启用(qyng)Zend_Layoutpindex.phpZend_Layout:startMvc(array(layoutPath=./application/layouts);/dispath() -启动(qdng)之前添加启用Zend_Layout第三十六页,共八十七页。playout.phtmlescape($this-title); ?escape($this-title); ?layout()-content; ?第三十七页,共八十七页。风格(fngg)p为了使我们的网站更为美观(migun),要定位CSS文件,因为URL并不是指向正确的根目录,这需要创建自己的视图辅助函数baseUrl(),它通过收集请求对象的相关信息使我们可以得到不知道的URL,并把它传递给视图第三十八页,共八十七页。视图(sht)助手p在你的视图脚本中,经常需要执行某些特定的复杂的函数,例如,格式化日期,生成表单对象,或者显示action的链接等等。你可以使用助手类来完成这些工作。p视图辅助类n保存在application/views/helpers文件夹中n文件名为Helper name.php(文件名第一个字母大写(dxi))n视图辅助类名必须是Zend_View_Helper_Helper name形式(每个单词第一个字母大写)n在这个类中,必须有一个名为helper name()的函数(函数名第一个字母小写)第三十九页,共八十七页。BaseUrl.phpgetBaseUrl();?第四十页,共八十七页。添加(tin ji)样式playout.phtmllink rel=stylesheet type=text/css media=screenhref=baseUrl();?/css/site.css /ppublic/css/site.cssbody,html margin: 0 5px;font-family: Verdana,sans-serif;h1 font-size:1.4em;color: #008000;第四十一页,共八十七页。数据库p我们已将程序的控制与视图分离开来了,继续(jx)我们的例子,接下来是存取数据库。p我们将利用ZF提供的Zend_Db_Table类,该类是ZF的表模块,可以来进行查找、插入、修改和删除数据库表中的记录。 第四十二页,共八十七页。连接(linji)数据库pZend_Db_Adapter是ZF的数据库抽象层API。 基于PDO,你可以使用它连接和处理多种数据库,包括:SQL Server,MySql,SQLite等等(dn dn)。p针对不同的数据库实例化一个Zend_Db_Adapter对象, 需要将adapter的名字和描述数据库连接的参数数组作为参数,静态调用 Zend_Db:factory()方法。第四十三页,共八十七页。什么(shn me)是PDOpPHP Data Object(PDO)是PHP一个扩展. 它定义了一个简便(jinbin)持久访问数据库的方法. 我们可以方便地使用一组定义好的函数来访问每个实现了PDO的数据库. PDO提供了一组访问数据库的抽象方法, 也就是说, 不论访问何种类型的数据库, 我们只用同样名称的方法访问就可以了, 这样就大大简便了数据库操作。第四十四页,共八十七页。PDO安装(nzhung)(参考)pextension=pdo.sopextension=pdo_MySQL.sopextension=php_pdo.dllextension=php_pdo_firebird.dllextension=php_pdo_informix.dllextension=php_pdo_mssql.dllextension=php_pdo_mysql.dllextension=php_pdo_oci.dllextension=php_pdo_oci8.dllextension=php_pdo_odbc.dllextension=php_pdo_pgsql.dllextension=php_pdo_sqlite.dll第四十五页,共八十七页。127.0.0.1, username= root, password =root, dbname =bookdb);$db = Zend_Db:factory(PDO_MYSQL, $params);/ 为所有的Zend_Db_Table对象设定默认的adapterrequire_once Zend/Db/Table.php;Zend_Db_Table:setDefaultAdapter($db);? 初始化数据库连接(linji)第四十六页,共八十七页。配置文件p为了访问数据库,必须先配置使用的数据库及登录数据库的用户名密码等信息,把这些信息保存在配置文件中,更便于以后的更新,配置文件存放在application目录下,或者存在在单独目录中application/configp使用Zend_Config来提供灵活的面向对象访问配置文件,配置文件可以是PHP数组、一个(y )INI文件或者XML文件。第四十七页,共八十七页。config.inigeneraldb.adapter=PDO_MYSQLdb.params.host=localhostdb.params.username=rootdb.params.password=rootdb.params.dbname=bookdbdb.params.charset=gb2312第四十八页,共八十七页。Zend_Configp在index.php中添加(tin ji)/ 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);第四十九页,共八十七页。p/load configurationn构造Zend_Config_Ini和Zend_Registry对象n读取config.ini配置文件中“general”节中的数据n保存$config对象到$registry对象中,留以后(yhu)其他地方使用p/ setup databasen创建Zend_Db对象,并读取配置信息n设置操作数据库字符集n通过Zend_Db对象的静态方法将db注册到Zend_Db_Table中第五十页,共八十七页。模型(mxng)p现在该是考虑模型的时候了。记住,模型是用来处理程序的核心议题(yt)(即所谓的“商业规则”business rules)p管理我们的图书是我们要考虑的业务核心,使用Zend_Db_Table类来完成这个功能,由于它是抽象类,所以我们继承它来创建管理图书的数据库模型第五十一页,共八十七页。Zend_Db_TablepZend_Db_Table 是Zend Framework的表模块。它通过zend_db_adapter连接到 数据库,为数据库模式检查表对象,并对该表进行操作(cozu)和查询。pZend_DB_Table为抽象类,所以不能直接实例化,只能先继承该类,然后实例化子类第五十二页,共八十七页。扩展(kuzhn)Zend_Db_Tablep模型(mxng)根据操作的数据库来创建n类名:使用的数据库表名n属性:设置$_name属性为要操作的表名p存放路径:napplicationmodelsBooks.php 第五十三页,共八十七页。数据库操作(cozu)p插入(ch r)数据/*insert book(id,name,title) values(201,alex,PHP)*/$books=new Books();$data=array(id=201, name=alex, title=PHP);$id=$books-insert($data);/返回插入数据行号第五十四页,共八十七页。p更新数据(shj)/*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);/返回更新行数第五十五页,共八十七页。p删除数据(shj)/*delete from books where name=alex0018*/$books=new Books();$db=$books-getAdapter();$where=$db-quoteInto(name=?,alex0018);$row_affected=$books-delete($where);/返回删除行数第五十六页,共八十七页。Zend_Db_Table_Rowp该类不能实例化,只能通过调用Zend_Db_Table:find()方法或者Zend_Db_Table:fetchRow()做为结果数据返回过来,一旦(ydn)得到对象还可以进行记录值的修改等操作。第五十七页,共八十七页。p取回一条记录(jl)和修改一条记录(jl)$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(); 保存修改,但不能修改主键第五十八页,共八十七页。p设置查询条件取回一条(y tio)记录/*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对象. 第五十九页,共八十七页。Zend_Db_Table_RowsetpZend_Db_Table_Rowset是 Zend_Db_Table_Row对象集合的迭代器。通常来说,你不可以(ky)自己实例化该对象,而是通过调用Zend_Db_Table:find()方法或者fetchAll()方法将Zend_Db_Table_Rowset作为结果数据返回过来,接下来就可以遍历Zend_Db_Table_Row对象集合并进行修改第六十页,共八十七页。p根据(gnj)主键查找数据$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();/返回所有的记录第六十一页,共八十七页。p取回(q hu)多条记录$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对象第六十二页,共八十七页。程序核心(hxn)部分p显示图书列表p添加(tin ji)图书p编辑图书p删除图书第六十三页,共八十七页。显示图书(tsh)列表p控制器function indexAction()$this-view-title=我的图书馆;$books = new Books();$this-view-books = $books-fetchAll();第六十四页,共八十七页。p视图(sht): applicationviewsscriptsindexindex.phtmla href=url(array(controller=index,action=add);?添加图书TitleName books as $book) : ?escape($book-title);?escape($book-name);?a href=url(array(controller=index,action=edit, id=$book-id);?编辑a href=url(array(controller=index,action=delete, id=$book-id);?删除第六十五页,共八十七页。p样式(yngsh):public/css/site.css/* Table */th text-align: left;td, th padding-right: 5px;第六十六页,共八十七页。添加(tin ji)图书p添加图书包括两个工作n显示一个表单供用户输入详细的图书信息n处理提交的表单,将图书信息保存到数据库中p使用Zend_Form来完成这个工作,Zend_Form组件可以用来创建输入表单并对用户的输入信息进行验证。我们引入一个新的继承自Zend_Form的模型(mxng)类BookForm来定义该表单第六十七页,共八十七页。Zend_Formp获取用户数据的最简单方式就是使用表单,ZF提供Zend_Form可以完成复杂的验证并在表单验证失败时在表单中显示错误信息。pZend_Form附带了:按钮、复选框、隐藏、图片(tpin)、多选框、密码、单选、重置、提交、文本、文本域等元素,内置的Zend_Form_Element类允许您创建自己的元素papplication/models/BookForm.php 第六十八页,共八十七页。一个(y )简单的表单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);第六十九页,共八十七页。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);?第七十页,共八十七页。p在BookForm的构造函数中,我们创建了包括四个元素的表单:id, name, title和submit按钮。每个元素都设置了不同的属性,包括要显示的文本标签。p对于文本元素,我们增加了两个过滤器,StripTags和StringTrim,它们分别用来删除不必要的HTML标记和不必要的空格。我们还将它们设置为必需的字段,通过添加一个NotEmpty验证器来保证用户确实输入了我们需要的信息。 p现在我们需要显示这个表单,并能在表单提交后进行(jnxng)处理。这可以通过addAction()来实现第七十一页,共八十七页。p控制器控制器function addAction() /part1$this-view-title=添加添加(tin ji)图书图书;$form = new BookForm();$form-submit-setLabel(Add);$this-view-form = $form;/part2if ($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);第七十二页,共八十七页。pPart1:创建一个BookForm的实例,提交按钮标签改为“Add”,然后将$form保存到视图中去,以便以后显示它。pPart2:使用请求对象的isPost()判断表单是否为提交状态,再使用getPost()从请求对象中获取表单提交的数据,然后用isValid()来验证表单是否有效。pPart3:如果(rgu)表单有效,创建一个新的Books对象,使用createRow()来生成一条新记录,然后填充数据,最后保存到数据库中,保存完成后使用控制器的_redirect()重定向到主页上。pPart4:如果表单无效,则将用户输入的数据重新添回表单重新显示给用户。第七十三页,共八十七页。p视图(sht):applicationviewsscriptsindexadd.phtmlform ;?第七十四页,共八十七页。修改图书(tsh)信息p类似(li s)添加图书第七十五页,共八十七页。p控制器控制器function editAction()$this-view-title=编辑编辑(binj)图书图书;$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 $paramsid$id = (int)$this-_request-getParam(id, 0);if ($id 0) $books = new Books();$book = $books-fetchRow(id=.$id);$form-populate($book-toArray();第七十六页,共八十七页。pPa