Php Zend framework 1.12前端控制器配置
我正试图使用以下代码,使用引导类向前端控制器注册我的模块:Php Zend framework 1.12前端控制器配置,php,zend-framework,Php,Zend Framework,我正试图使用以下代码,使用引导类向前端控制器注册我的模块: $this->bootstrap('FrontController'); $front = $this->getResource('FrontController'); $front->addModuleDirectory(APPLICATION_PATH."/modules"); $front->setParam('prefixDefaultModule', true); 这工作正常,所有模块都已注
$this->bootstrap('FrontController');
$front = $this->getResource('FrontController');
$front->addModuleDirectory(APPLICATION_PATH."/modules");
$front->setParam('prefixDefaultModule', true);
这工作正常,所有模块都已注册。但是当我执行以下操作时,我的模块目录没有注册,并且我得到了“controller not found error”
由于前端控制器实现了单例设计模式,两个代码块不应该引用同一个实例,并且我的两个代码块都应该工作吗 您需要首先引导前控制器,以便对其进行初始化。在循环中完成后,您始终可以使用静态getInstance检索它。下面是发生的情况。蒂姆是对的。application.ini文件中的以下行就是罪魁祸首。如果将其删除,应用程序将正确加载
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
您可能还必须删除该行,因为它也是frontcontroller的一部分
resources.frontController.params.displayExceptions = 1
但是您还有另外两个选项可以使用Zend\u Controller\u Front::getInstance()
备选案文1。将index.php更改为特定于引导的资源:
$application->bootstrap(array('FrontController', 'ModuleConfig'))->run();
这将首先从application.ini引导FrontController,然后运行initModuleConfig
方法。本质上,这允许您控制加载哪些资源以及加载顺序。当您有只想在特定时间引导的资源时,这非常有用
我认为,如果您不在这里为bootstrap方法提供数组,那么它将按照声明的顺序调用以init
为前缀的所有方法
备选案文2。您可以在application.ini中配置模块目录
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.params.prefixDefaultModule = 1
resources.frontController.params.displayExceptions = 1
这将完成您在代码中尝试执行的操作。需要注意的一点是,您可能希望在bootstrap
类的构造函数中引导FrontController。这只是为了防止在自定义初始化期间需要使用它
下面是选项1工作原理的解释 这是来自
Zend\u应用程序\u引导\u引导的方法
protected function _bootstrap($resource = null)
{
if (null === $resource) {
foreach ($this->getClassResourceNames() as $resource) {
$this->_executeResource($resource);
}
foreach ($this->getPluginResourceNames() as $resource) {
$this->_executeResource($resource);
}
} elseif (is_string($resource)) {
$this->_executeResource($resource);
} elseif (is_array($resource)) {
foreach ($resource as $r) {
$this->_executeResource($r);
}
} else {
throw new Zend_Application_Bootstrap_Exception('Invalid argument passed to ' . __METHOD__);
}
}
调用public引导
方法时,将调用此\u引导
。示例$this->bootstrap(“FrontController”)
或$this->bootstrap()
请注意不传入参数的情况。这将调用null
案例,这是您在index.php
-$application->bootstrap()->run()中得到的案例代码>
首先它将加载您的类资源
,然后它还将调用您的插件资源
。请注意,插件资源
在其他情况下不会加载
如果遵循类资源的方法调用,基本上就是在引导调用类中调用init
方法
之后将调用插件资源和其中一个插件资源。我不完全确定所有插件资源是如何加载的,但我相信有一个源代码在您的应用程序.ini
文件中。这些将是以资源
开头的行。示例包括视图、frontcontroller、db
因此,在您调用$application->bootstrap()->run()的情况下
,首先加载您的init
方法。但是您的FrontController
尚未启动。它最终被引导为一个插件资源,该资源取自您的应用程序.ini
。这显然覆盖了您在引导类中所做的操作
您可能会问的另一个问题是,当您显式调用$this->bootstrap(“FrontController”)
时,为什么FrontController实例没有被覆盖。我想这很明显,但我个人也有这个问题
在引导类中,有一个名为\u executesource
的方法,它将检查资源是否已引导。它使用关联数组来跟踪。关联数组名为$this->\u started
这就是为什么在您第一次显式引导前控制器时,不会调用前控制器的插件资源。因此,不会替换前控制器实例。问题在于application.ini中的这一行:
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
您提供的文件结构不包含此目录,因此我认为您可以删除它,它将解决您的问题
更详细地解释为什么它以一种方式工作,而不是以另一种方式工作:
使用Zend应用程序配置资源有两种方式:类资源和插件资源。Application.ini中的资源.xxx
行是插件资源,\u init
方法是类资源。类资源在插件资源之前运行,但如果运行$this->bootstrap(“…”)
它将确保资源已初始化(无论类型如何)
因此,在您的第一个代码示例中,$this->bootstrap('FrontController');
触发您在application.ini中定义的FrontController资源。这将使用您提供的路径设置控制器目录。然后添加一个模块目录,该目录似乎是您的应用程序实际使用的目录
在您的第二个代码示例中,您获得了front controller的一个实例,然后将您的模块目录添加到该实例中(都很好),但是插件资源将运行(请记住这些将在之后运行)。这将获取现有的front controller实例,但设置控制器目录会覆盖模块目录,因此这就是导致您以后出错的原因
我通常会尝试避免混合和匹配插件和类资源,因为这可能会导致一些奇怪的问题。因此,要么将其全部放在application.ini中,要么将其全部放在Bootstrap类中。我个人认为后者更具可读性
如果您确实也需要控制器目录,请将$this->bootstrap('FrontController');
添加到代码的开头
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"