免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6848 | 回复: 17
打印 上一主题 下一主题

[学习 框架] Zend Framework体验(一)初识 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-16 09:58 |只看该作者 |倒序浏览
这是个Framework的时代,写Java程序现在基本上就是和各种Framework打交道了。PHP以简单灵活著称,很多PHPer认为Java太重,见到Framework就烦。但随着项目的扩大,特别是PHP从擅长的中小型网站开发向所谓的“企业应用”发展,有一个良好的Framework支撑,无益对多人的团队开发还是有很多好处的。
这回要说的是Zend公司推出的Zend Framework(下面简称ZF),网址是http://framework.zend.com/,目前的版本是Preview 0.1.2,还不清楚正式版释放的计划。

本文最初发表于我的blog http://blog.csdn.net/Aryang/,转载请注明出处。

先说说安装条件,ZF要求基于PHP5,还有需要Apache mod_rewrite的支持,没有考证这个是否是Apache的内置模块,我是通过加参数--enable-rewrite重新编译了Apache。
下一步就是指定rewrite的规则,有很多方法,我用的是.htaccess文件的方法。在web根目录,也就是index.php所在的目录创建文件.htaccess(注意.开头的文件在unix下默认是隐藏的)。文件的内容如下

  1. RewriteEngine on
  2. RewriteOptions Inherit
  3. RewriteCond %{REQUEST_FILENAME} !-d
  4. RewriteCond %{REQUEST_FILENAME} !-f
  5. RewriteRule  (.*) index.php?apache_path=$1 [L,QSA]
复制代码


要使.htaccess生效,在httpd.conf里对web目录的配置也有要求,

  1. Options FollowSymLinks
  2. AllowOverride All
复制代码


加上这个。
当然rewrite的规则有很多种写法,网上还有一种写法是:

  1. RewriteEngine on
  2. RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
复制代码


本人也对这个也没研究,大概意思就是URL里文件类型除(js|ico|gif|jpg|png|css)以外的都改写成index.php,瞎猜的,有懂的朋友可以讲讲这两种的区别。

然后就是下载ZF了,我的习惯是把在php.ini里include_path加上ZF/library目录,这样整个网站就可以很方便的访问ZF的库了。


这里要说说rewrite的作用了。ZF彻底封装了URL的格式,基本上看不到.php的影子了。ZF的App的根目录里只有一个index.php, rewrite会把所有的URL请求改写成对index.php的调用。index.php相当于是个Dispatch,里面会创建一个Zend_Controller_Front对象,它作为一个代理把HTTP请求传递给(dispatch)相应的你写好的Controller。

然后看网上的Tutorial,找到个例子,改了改,如下

  1. <?php
  2. //index.php
  3. include 'Zend.php'; //我是已经加入了include_path,没加的写全路径

  4. Zend::loadClass('Zend_Controller_Action');
  5. Zend::loadClass('Zend_Controller_Front');
  6. Zend::loadClass('Zend_InputFilter');
  7. Zend::loadClass('Zend_View');

  8. $controller = Zend_Controller_Front::getInstance();
  9. $controller->setControllerDirectory('./controllers');

  10. /*
  11. //数据库调用,可以先不加
  12. require_once 'Zend/Db.php';
  13. $params = array (
  14.     'database' => 'mydb',
  15.     'username' => 'myname',
  16.     'password' => 'mypass'
  17. );

  18. $db = Zend_Db::factory('Oracle', $params);
  19. Zend::register('db', $db); //全局对象注册,很好的方式
  20. */

  21. $view = new Zend_View;
  22. $view->setScriptPath('./views');
  23. Zend::register('view', $view);

  24. $controller->dispatch();

  25. ?>
复制代码


如果你的调用是 http://test.com/ ,Apache的设置里这个的实际调用 http://test.com/index.php,那么这个ZF会去找你写的IndexController.php(xxxController.php的位置通过在index.php里Zend_Controller_Front对象的setControllerDirectory方法指定),调用里面的类IndexController的IndexAction方法(我搜了很多加少ZF的文章都说是index方法,看ZF源代码才发现应该是IndexAction,不知道是什么原因,估计是版本变动的原因)。

  1. class IndexController extends Zend_Controller_Action
  2. {
  3.     function indexAction()
  4.     {
  5.         echo "这是首页";
  6.     }

  7.     function noRouteAction()
  8.     {
  9.         echo  "您所请求的页面不存在!";
  10.     }
  11. }
复制代码


如果你曾经的程序有个"http://test.com/book.php"来显示图书的相关页面,那么在ZF里的做法是写个bookController.php,在里面定义bookController类。"http://test.com/book/"会调用bookController类的IndexAction方法。传统的

"http://test.com/book.php?action=edit&book_id=888"

如何实现呢?在bookController类里定义“"editAction"方法,URL调用的写法是"http://test.com/book/edit/book_id/888",格式就是

http://host/controller_name/method_name/param1/value1/param2/value2/...

在editAction方法里可以通过 $this->_getParam("param1") 获得参数,或通过
$this->_getAllParams()获得全部的参数。

  1. class bookController extends Zend_Controller_Action
  2. {
  3.     function indexAction()
  4.     {
  5.         echo "hi, this is my books";
  6.     }

  7.     function editAction()
  8.     {
  9.         $book_id = $this->_getParam("book_id");
  10.         echo "book id:".$book_id;
  11.     }
  12.    
  13. }
复制代码


这样的话大家可以看到现在写程序方式就是实现一些类,ZF会对URL做解析,然后调用并传递参数。
所谓"Framework"都是这样的,它调用你,不是你调用它。

目前感觉严重不爽的就是应用必须是网站的跟目录,实际一个网站有多个应用的话,我们一般就是把每个应用放在不同的目录下。行动,在ZF的邮件列表里发现老外对这个也有意见,很多人做了处理。看到了这个网站

http://kpumuk.info/php/zend-framework-router-for-subdirectory-based-site/

里面实现了对App存放子目录的处理,大概就是自己写了个Router,替换掉ZF里的Router。但这个网站提供的代码在ZF 0.1.2里运行有问题,估计他是在0.1.0的时候写的。我做了相应修改:

  1. <?php

  2. /** Zend_Controller_Router_Interface */
  3. require_once 'Zend/Controller/Router/Interface.php';

  4. /** Zend_Controller_Dispatcher_Interface */
  5. require_once 'Zend/Controller/Dispatcher/Interface.php';

  6. /** Zend_Controller_Router_Exception */
  7. require_once 'Zend/Controller/Router/Exception.php';

  8. /** Zend_Controller_Dispatcher_Action */
  9. require_once 'Zend/Controller/Dispatcher/Interface.php';

  10. class Zend_Controller_SubDirectoryRouter implements Zend_Controller_Router_Interface
  11. {
  12.   public function route(Zend_Controller_Dispatcher_Interface $dispatcher)
  13.   {
  14.     // SubDirectoryRouter: what's the path to where we are?
  15.     $pathIndex = dirname($_SERVER['SCRIPT_NAME']);

  16.     // SubDirectoryRouter: remove $pathIndex from $_SERVER['REQUEST_URI']
  17.     $path = str_replace($pathIndex, '', $_SERVER['REQUEST_URI']);
  18.     if (strstr($path, '?')) {
  19.       $path = substr($path, 0, strpos($path, '?'));
  20.     }
  21.     $path = explode('/', trim($path, '/'));

  22.     /**
  23.      * The controller is always the first piece of the URI, and
  24.      * the action is always the second:
  25.      *
  26.      * http://zend.com/controller-name/action-name/
  27.      */
  28.     $controller = $path[0];
  29.     $action     = isset($path[1]) ? $path[1] : null;

  30.     /**
  31.      * If no controller has been set, IndexController::index()
  32.      * will be used.
  33.      */
  34.     if (!strlen($controller)) {
  35.       $controller = 'index';
  36.       $action = 'index';
  37.     }

  38.     /**
  39.      * Any optional parameters after the action are stored in
  40.      * an array of key/value pairs:
  41.      *
  42.      * http://www.zend.com/controller-name/action-name/param-1/3/param-2/7
  43.      *
  44.      * $params = array(2) {
  45.      *              ["param-1"]=> string(1) "3"
  46.      *              ["param-2"]=> string(1) "7"
  47.      * }
  48.      */
  49.     $params = array();
  50.     for ($i=2; $i<sizeof($path); $i=$i+2) {
  51.       $params[$path[$i]] = isset($path[$i+1]) ? $path[$i+1] : null;
  52.     }

  53.     $actionObj = new Zend_Controller_Dispatcher_Token($controller, $action, $params);

  54.     if (!$dispatcher->isDispatchable($actionObj)) {
  55.       /**
  56.        * @todo error handling for 404's
  57.        */
  58.       throw new Zend_Controller_Router_Exception('Request could not be mapped to a route.');
  59.     } else {
  60.       return $actionObj;
  61.     }
  62.   }
  63. }

  64. ?>
复制代码


文件命名SubDirectoryRouter.php,保存于ZF/library/Zend/Controller/,然后修改index.php
在  
$controller->dispatch();
之前加入如下:

Zend::loadClass('Zend_Controller_SubDirectoryRouter');

$router = new Zend_Controller_SubDirectoryRouter();
$controller->setRouter($router);

这样就可以把我们的应用置于网站某子目录下了。

ZF里有很多内容,这是我刚接触了解到的,如有新的体验,再和诸位一起探讨(wdy)。

[ 本帖最后由 HonestQiao 于 2006-5-22 12:59 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-03-16 14:44 |只看该作者
没看懂这个冬冬是干嘛用的。不过抢楼先

评分

参与人数 1可用积分 -2 收起 理由
夜猫子 -2 恶意灌水

查看全部评分

论坛徽章:
0
3 [报告]
发表于 2006-03-16 16:49 |只看该作者
不错,有点前途的东西,可惜为什么不兼容一下php4啊

论坛徽章:
0
4 [报告]
发表于 2006-03-16 17:24 |只看该作者
php4 确实太多缺陷了,php5 是趋势。

论坛徽章:
0
5 [报告]
发表于 2006-03-16 17:42 |只看该作者
php5是趋势,同意---正在开发中的php6,也依然保留了php5的oop特征!

论坛徽章:
0
6 [报告]
发表于 2006-03-17 10:24 |只看该作者
ZF好像挺有意思。

论坛徽章:
0
7 [报告]
发表于 2006-04-06 14:25 |只看该作者
结构~功能~样子像pear
运作像cakephp

论坛徽章:
0
8 [报告]
发表于 2006-04-06 16:20 |只看该作者
网上已经有人着手翻译了。初步看了一下,他用MVC架构,挺好的学习MVC范例。

论坛徽章:
0
9 [报告]
发表于 2006-04-06 23:34 |只看该作者
zf排第一
cakephp排第二
呵呵
都不错哦

论坛徽章:
0
10 [报告]
发表于 2006-04-07 00:37 |只看该作者
唉,当初没有选jsp的原因之一就是 他的framework太多了。让人看了郁闷。到底是人玩技术呢?还是技术玩人?

现在php也开始搞这个了。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP