发新话题
打印

CakePHP控制器中helpers和components初始设置

CakePHP控制器中helpers和components初始设置

作者:老王

CakePHP控制器结构中,CakePHP核心有一个Controller“爷类”控制器,我们可以自定义的有一个AppController“父类”控制器,然后我们自定义的“子类”控制器都从它继承。这样,我们就可以在AppController父控制器或者自定义的子控制器里初始化helpers和components属性。早在CakePHP1.1.X的时候,如果我们在自定义的子控制器中设置了helpers和components,会覆盖AppController父控制器中的对应设置,这样会造成很多不方便。还好,在CakePHP1.2.X中,各个控制器中的helpers及components会自动合并,而不是覆盖。但是,如果你不熟悉的话,有时候会出现很诡异的情况,下面,我给一个简单的介绍:

以下代码环境均以假定在CakePHP1.2.0.5427alpha版本进行。

首先,我们在app目录建立自定义的app_controllers.php文件:
复制内容到剪贴板
代码:
class AppController extends Controller
{
           // 暂时不设定 var $helpers 和 var $components
}

再在app/controllers目录下建立自定义的demo_controllers.php文件:

class DemoController extends Controller
{
           // 暂时不设定 var $helpers 和 var $components

           function index()
           {
               pr($this->helpers);
               pr($this->components);

               exit;
           }
}
这时,我们浏览一下demo,就会看到CakePHP的缺省helpers和components分别是:
复制内容到剪贴板
代码:
helpers: Html
components: Session
源代码里,我们能找到这些缺省设置的相关代码:

在controller.php文件里可以看到 var $helpers = array('Html'); 设置,所以不难理解helpers的缺省设置,但是同样在controller.php文件里也可以看到 var $components = array(); 设置,那么为啥最后会出现Session呢?原来这个Session组件的设置是在component.php文件里设置的:
复制内容到剪贴板
代码:
$this->controller->components = array_merge($this->controller->components, array('Session'));
知道了helpers和components最基本的缺省设置之后,我们来尝试改变一下,在DemoController里加入下面的定义:
复制内容到剪贴板
代码:
var $helpers = array('Javascript');
var $components = array('Email');
浏览一下demo,就会看到CakePHP的缺省helpers和components分别是:
复制内容到剪贴板
代码:
helpers: Javascript,Html
components: Email,Session
不错,没有覆盖掉父类的设置,都按预想进行。那么我们再尝试改变一下,在AppController里加入下面的定义:
复制内容到剪贴板
代码:
var $helpers = array('Form');
var $components = array('Security');
浏览一下demo,就会看到CakePHP的缺省helpers和components分别是:
复制内容到剪贴板
代码:
helpers: Javascript,Form
components: Email,Security,Session
看到这里,可能会感觉比较诡异,Html助手不见了,而Session组件还在。至于为啥会这样,我们可以在controller.php文件里找到相关的代码:
复制内容到剪贴板
代码:
if (is_subclass_of($this, 'AppController')) {
$appVars = get_class_vars('AppController');
...
$merge = array('components', 'helpers');
...
foreach ($merge as $var) {
        if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) {
         $this->{$var} = array_merge($this->{$var}, array_diff($appVars[$var], $this->{$var}));
        }
}
}
从array_merge($this->{$var}, array_diff($appVars[$var], $this->{$var}));中可以看出,在这部分设定中,排除了可能的重复。既然说到重复的问题,我们回过头看看上面对于Session的处理代码:
$this->controller->components = array_merge($this->controller->components, array('Session'));
可以看出这里没有排除可能的重复。

如果没看懂也没有什么关系,只要记住下面的结论性提示就可以了:如果不想被helpers和components的初始化搞蒙,那么在建立自定义的AppController的时候,一定要在helpers里把Html重新设定一次,但是,不管是在AppController里,还是你自定义的子控制里,都不要设定Session组件,不然就会出现重复。

这也说明了CakePHP代码目前还存在很多不严谨的地方,在1.2Stable的时候,应该会好起来。

TOP

TOP

发新话题