Zend Framework 增加自己的library库

在以前的老版本的Zend Framework(大概是1.5.*)的年代,记得使用自己的类库,只要将对应的库放到项目的library目录下,与Zend Framework 自己Zend目录同级即可。前提是已经将对应的library库加载到系统的include_path中了。

但是,当使用新版本的Zend Framework中,发现才用同样的方法会报错误,报告找不到class。具体的情况是这样的。

我需要将用户身份认证的模块以Controller的Plugin的形式加载入系统中,因此,根据新版Zend Framework的application.ini,要才用如下方法配置frontController的plugin

resources.frontController.plugins.sesssion = Hr_Controller_Plugin_Allow

对应的,在library目录下依次建立Hr/Controller/Plugin 目录,在Plugin目录下建立Allow.php,Allow.php涉及如下内容:

< ?php
class Hr_Controller_Plugin_Allow extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch( Zend_Controller_Request_Abstract $Request )
    {
        $strModuleName = $Reques-->getModuleName() ;
        $strControllerName = $Request->getControllerName() ;
        $strActionName = $Request->getActionName() ;

        $strRule = $strModuleName . $strControllerName . $strActionName ;

        Zend_Debug::dump( $strRule ) ;
    }
}

这里只是简单的将Plugin勾上preDispatch事件,具体的代码大家自己实现,我这里只是想记录问题。

完成上述操作后,我本以为该Plugin就可以实现生效了。

不过测试使就会出现如下错误:

Fatal error: Class 'Hr_Controller_Plugin_Allow' not found in /usr/share/ZendFramework/library/Zend/Application/Resource/Frontcontroller.php on line 111

对应Frontcontroller.php的部分代码:

.....
 96                 case 'plugins':
 97                     foreach ((array) $value as $pluginClass) {
 98                         $stackIndex = null;
 99                         if(is_array($pluginClass)) {
100                             $pluginClass = array_change_key_case($pluginClass, CASE_LOWER);
101                             if(isset($pluginClass['class']))
102                             {
103                                 if(isset($pluginClass['stackindex'])) {
104                                     $stackIndex = $pluginClass['stackindex'];
105                                 }
106
107                                 $pluginClass = $pluginClass['class'];
108                             }
109                         }
110
111                         $plugin = new $pluginClass();
112                         $front->registerPlugin($plugin, $stackIndex);
113                     }
114                     break;
.......

可以看到,是在new $pluginClass(); 报的错误,而且之前的提示也是说明对应的Class没有找到。

可是默认的Project中的index.php里面已经对library目录进行了加载。

......
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));
......

这就只能从Zend自己的加载机制进行考虑。参考了这篇文章( http://www.hardcode.nl/archives_132/article_490-register-plugins-in-zf-applicationini.htm )后,我注意到作者在application配置中增加了一个配置,名为:autoloaderNamespaces

而对应的新版的application.ini中的默认项目中也有 appnamespace = “Application” 的配置

因此,仿照文章我增加了名为:”Hr_”的Autoloader的Namespace配置

......
autoloaderNamespaces[] = "Hr_"
......

增加配置后,项目就会识别Hr_Controller_Plugin_Allow的Class了。


总结:

本次问题的发现,体会到对于Zend的AutoLoader的机制还不是很理解,需要深入分析,多看手册和文档。后续有时间增加对于AutoLoader机制的学习和分析。

  • 力童

    autoload是 php5的机制,直接看php手册吧
    其实就是在写代码的时候,不需要手工去require依赖的文件了,可以直接实例化的一种机制

    好处是可以提高性能,不过zend还是很慢的…

  • rui

    在一些并发测试中,也发现Zend Framework很慢,消耗内存/CPU都很大,和面向过程的代码相比,成倍的差距 …

  • http://www.lanbolee.com Rambo Lee

    ZF,现在给我的感觉就是可以的在模仿ROR的架构和处理方式。嵌套的过于复杂,考虑大而全。想兼容并包,先都圈下来,再去考虑优化效率。
    确实,作为大项目很少有人采用ZF作为自己底层的framework。
    主要是他自身变化很快。而且,在1.*这个不是很大的版本变化中,MVC核心的模块结构变动很大,让习惯了轻松灵活的PHP程序员都变得无从下手,而且教条起来。
    这个是很难让人接收的。
    当然,最主要的是糟糕的效率。
    不过,不可否认,ZF的各个针对性的实际业务模块,已经一些OO的封装思想和设计模式,还是这的学习和称道的。

  • http://www.lanbolee.com Rambo Lee

    嗯。多谢指点。学习中。
    ZF的慢是自古以来的。
    不过作为学习性的Project,我觉得还是有利用价值的。呵呵。