【问题标题】:Cannot load module's index action for Zend Framework Module无法为 Zend 框架模块加载模块的索引操作
【发布时间】:2012-02-21 04:10:23
【问题描述】:

我正在尝试为管理界面创建一个模块,但无法让它响应根本 - 我到目前为止所做的是:我已经修改了我的主应用程序的引导程序加载模块目录的文件:

$modules = PROJECT_DIR . '/library/PHPLib/ZF/Modules';
define('MODULES_DIR', $modules);
$frontController->addModuleDirectory(MODULES_DIR);

该模块包含在我的外部 PHP 库中,我为每个项目重复使用,无论是否基于 ZendFramework。这是我第一次添加模块,但之前我曾使用该库来包含辅助类和插件,没有任何问题。模块的结构包含在 PHPLib/ZF/Modules 中,如下所示:

ModAdmin/
  controller/
    IndexController.php
  model/
  view/
    includes/
    layouts/
    scripts/
      index/
        index.phtml

IndexController.php 类被定义为“ModAdmin_IndexController”,因为我在我拥有的一些 ZF 资源中得到了指示。脚本已存在,但尚未创建布局。我不确定我是否会使用一个。

所以,当我尝试在浏览器中请求 ModAdmin 模块的索引时,我得到 404。我使用的 URL 是:

http://hostname/ModAdmin/

我错过了什么吗?根据一些书籍,例如“ZendFramework In Action”和“ProPHP”,他们说这就是所需要的。当我读到他们说这很简单时,我几乎忍不住笑了——ZendFramework 中没有任何东西“那么”简单——我喜欢 ZF,ALOT,但它并不简单。复杂性之所以存在,是因为它非常灵活和强大。

无论如何 - 有什么想法吗?

编辑

我想我应该补充一点,我早在 Zend_Application 或 Zend_Tool 类出现之前就开始使用 ZF - 这是在 ZF 变得明智并开始模拟 RoR 样式 MVC 之前 - 无论如何 - 我的项目没有这些,因为在我开始研究模块之前,我什至不知道它们的存在。话虽这么说 - 我没有时间设置与这些相关的学习曲线,我很满意手动创建我的引导程序。

实际上 - 老实说 - 我创建了一个名为“padmin”的“部署工具”,它是一个 CLI 运行 php 脚本,它执行 Zend_Tool 所做的很多事情 - 我将它与“phing”结合使用,就像php 的“ant” - 无论如何 - 我解决了它,就像大多数人一样。

EDIT2

我发现这个资源似乎可以在不使用 Zend_Tool 的情况下解决添加模块的问题,尽管遵循了它列出的所有要求,但在以所述方式请求模块时,我仍然收到 404 代码:

http://hostname/modulename/indexhttp://hostname/modulename/

EDIT3

伙计们 - 我无法表达这是多么令人沮丧。 Web 上的每个资源要么引用 Zend_Tool/Application 模块的创建,要么我最终只讨论了非常特定方面的模块。我需要一些可以帮助我调试为什么 FrontController 的调度/路由阶段找不到模块的东西。我已经在我的引导程序中设置了模块目录。该模块有一个控制器和一个视图脚本。就是这样 - 它不应该需要更多的东西。它可能还需要什么?我尝试单独添加模块的控制器目录(而不是通过'addModuleDirectory'添加它)并且仍然没有骰子。我之前提到的一些文档说:

匹配规则指定一个模块只有在一个 传递的控制器目录数组中存在同名键 到前端控制器和调度器。

嗯 - 伙计们 - 我就是这样做的:

    $defaultControllerDir  = PROJECT_DIR . '/application/controller';
    $modadminControllerDir = PROJECT_DIR . '/library/PHPLib/ZF/Modules/ModAdmin/controller';
$frontController->setControllerDirectory(array(
                                         'default'  => $defaultControllerDir,
                                         'modadmin' => $modadminControllerDir
                                        ));

然而 - 没有骰子。浏览器返回 404。如果前端控制器具有某种内部审计/日志记录功能,我可以打开它并查看到底发生了什么(如果我想深入研究源代码,我想我可以这样做)并添加一些打印语句,但这越来越荒谬了)。

这绝对是令人麻木的。很久以前,当我第一次学习 ZF 时,这发生在我身上——并且有据可查——当出现问题时——很难理解为什么。好吧,我又遇到了另一个问题——我遵循了所有可以想象的指令(我发现早于 zend_tool 的指令),但没有任何效果。

我唯一没有做的就是像这样设置我的目录结构:

modules/
  default/
    controllers/
    models/
    views/
  custom1/
    controllers/
    models/
    views/

但是这样做会完全破坏模块的目的,对吗?如果我不能将模块化模块代码保存在库中(即不在应用程序目录中,而是在外部库中),那么创建模块的意义何在!?我需要能够将我的模块代码放在我的库中:'/library/PHPLib/ZF/Modules/ModAdmin' - 什么给了!

编辑 - 响应选定的答案

非常有趣 - 在将 Apache 的目录设置更改为 AllowOverride All 之后,我得到你的插件对 mod-admin 请求的响应,而不是 404 (array(3) { ["module"]=> string(9 ) "mod-admin" ["controller"]=> string(5) "index" ["action"]=> string(5) "index" }) 然后如果我禁用插件我会得到这个错误:

致命错误:未捕获的异常“Zend_Controller_Dispatcher_Exception” 带有消息“指定的控制器无效(索引)” /home/nevertap/work/nevertap/library/Zend/Controller/Dispatcher/Standard.php:248 堆栈跟踪:#0 /home/nevertap/work/nevertap/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), 对象(Zend_Controller_Response_Http))#1 /home/nevertap/work/nevertap/application/configuration/bootstrap.php(100): Zend_Controller_Front->dispatch() #2 /home/nevertap/work/nevertap/application/configuration/bootstrap.php(110): 引导程序->configureFrontController() #3 /home/nevertap/www/nevertap/index.php(19): Bootstrap->runApp() #4 {main} 投入 /home/nevertap/work/nevertap/library/Zend/Controller/Dispatcher/Standard.php 第 248 行

这很奇怪,因为 .../Modules/mod-admin/controller/IndexController.php 和 .../Modules/mod-admin/view/scripts/index/index.phtml 一样存在 - 更不用说IndexController 类的前缀是“ModAdmin_IndexController”

最终编辑

好的,我终于明白了 - 看起来通过加载模块目录,它寻找默认的控制器目录,该目录总是模式为“控制器”,而我的是“控制器”,所以我没有使用 addModuleDir 加载模块,而是使用了另一个:

$modadminControllerDir = PROJECT_DIR . '/library/PHPLib/ZF/Modules/mod-admin/controller';
$frontController->addControllerDirectory($modadminControllerDir, 'mod-admin');

【问题讨论】:

  • 据我了解,ZF 1.x 中模块的概念是它们就像迷你应用程序。目的是让每个模块尽可能地反映一个完整的应用程序。通常默认模块是像全局模块这样的原始文件夹。然后添加的模块将位于应用程序下方的模块文件夹中。我认为您可能可以按照您想要的方式进行这项工作,但您可能必须几乎完全重新配置自动加载器。你的模块结构不符合默认的自动加载器,所以你可能会调查一下。
  • Rocky - 你的最后一次观察成为了我在这里工作的一个问题。当您添加一个模块时,更重要的是要注意默认自动加载器的标准,因为在引导程序中所做的更改可能只应用于主/默认应用程序。
  • 所以这一切都归结为一个's',哇!我们都在想这个。
  • 但不总是这样吗?错误通常是被忽视的小事——就像实际的错误一样 :)

标签: zend-framework module


【解决方案1】:

将你的模块目录重命名为“mod-admin”

mod-admin/
  controller/
    IndexController.php
  model/
  view/
   ...

您的控制器类应保留为 ModAdmin_IndexController,您可以通过 http://hostname/mod-admin/ 访问它

附: 当然仍然这样做

$modules = PROJECT_DIR . '/library/PHPLib/ZF/Modules';
define('MODULES_DIR', $modules);
$frontController->addModuleDirectory(MODULES_DIR);

P.P.S

要查看您的请求发生了什么,您可以注册一个插件并覆盖 routeshutdown 方法以 var_dump 像这样的参数,(您的引导文件应该看起来像这样)

<?php

class TestPlugin extends Zend_Controller_Plugin_Abstract {

    public function routeShutdown(Zend_Controller_Request_Abstract $request) {
        var_dump($request->getParams());
        die();
    }

}

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { ...

    protected function _initDebugingRequest() {
       $front = Zend_Controller_Front::getInstance();
       $front->registerPlugin(new TestPlugin());
    }
...

P.P.P.S

确保您已使用 sudo a2enmod rewrite 启用了重写,并且在 /etc/apache2/sites-available/default 文件中您有类似

<Directory /var/www/>
...
AllowOverride All
...
</Directory>

【讨论】:

  • 谢谢 - 这看起来是正确的。当我的雇主不忙着用加班杀死我时,我会试试看。看起来您将获得赏金,因为这看起来可能是问题所在。谢谢,我会尽快回来
  • 实际上 - 我不确定发生了什么 - 如果我赶时间并且浏览器上有其他内容,但我错了 - 这并没有像我想象的那样工作。我尝试访问hostname/mod-admin 的索引页,但仍然收到 404 错误。由于某种原因,该路线没有发生。当我编辑我的引导程序时,更改应该立即显而易见,每个请求都正确吗?那么我还能如何尝试调试呢?我可以查看内部前端控制器日志以了解发生了什么?
  • 这是我去根目录时得到的结果:array(3) { ["controller"]=> string(5) "index" ["action"]=> string(5) "index" ["module"]=> string(7) "default" } 但是,当我转到 root/mod-admin 时,我仍然得到 404。奇怪。
  • 不可能是我的 .htaccess 吧?它是这样的: RewriteEngine On RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^.* $ /index.php [NC,L]
  • 有趣的是,将 AllowOverride 更改为 All 以某种方式起作用 - 尽管我不明白当我的 webroot 中的 .htaccess 文件一直在做它的工作时,这会如何产生影响 - 并且如果该目录的 AllowOverride 还没有允许 All (至少我理解它是这样工作的),那就不会了 - 无论如何 - 前端控制器现在窒息说我的控制器无效但我不知道如何。
【解决方案2】:

看起来你仍然需要初始化模块,我在 application.ini 中使用
resources.modules[] = ""
我相信您可以将其转换为引导代码。
如果提供线索,您已经拥有的相当于
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

[编辑] 如果没有提到你的每个模块应该有它自己的引导扩展 Zend_Application_Module_Bootstrap。

附:我最近刚刚通过 Pro Zend Framework Techniques 工作,我发现它有很多有用的信息,但就当前配置而言已经过时,并且在 ZF 中当前使用的一些工具中。 Rob Allen 维护了一个关于 ZF 的优秀教程,他在Akrabat.com 上保持最新的当前版本,而 Padrig Brady 有一本很棒的免费在线书籍,它是相当最新的,它不是 100% 完整,但非常擅长它所涵盖的内容,找到在Survive the Deepend

【讨论】:

  • 哇哦。我实际上不知道如何翻译。但我会朝那个方向看。在我拥有的两种资源中都没有提到你提到的那行代码是多么奇怪。然而,这不是我第一次发现这些书遗漏了一些东西!谢谢,我会朝那个方向看
  • @Matt1776 选择书籍时要非常小心,其中许多信息量很大,但已经过时(有些也不完整)。在最近的几个版本中,ZF 在某些层面上发生了很大变化。看起来你书中的 ZF 版本可能是 1.8 之前的版本
猜你喜欢
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 2014-08-28
  • 1970-01-01
相关资源
最近更新 更多