【问题标题】:ZF2 routing ignores namespaceZF2 路由忽略命名空间
【发布时间】:2014-04-10 08:52:01
【问题描述】:

我遇到了 zf2 路由问题。我正在使用骨架示例 https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php,但是当我绑定访问 http://localhost/admin/http://localhost/admin/answers 时,我收到 404 消息:

A 404 error occurred

Page not found.

The requested controller could not be mapped to an existing controller class.

Controller:
Index(resolves to invalid controller class or alias: Index)
No Exception available

从错误消息中我认为路由器忽略了 __NAMESPACE__。也许有人可以帮我找到解决问题的方法?

我使用https://github.com/zendframework/ZFTool 创建模块和控制器。 我的文件结构是:

module/Admin
├── config
│   └── module.config.php
├── Module.php
├── src
│   └── Admin
│       └── Controller
│           ├── AnswersController.php
│           └── IndexController.php
└── view
    └── admin
        ├── answers
        │   └── index.phtml
        └── index
            └── index.phtml

我的模块.config.php:

return array(
    'controllers'  => array(
        'invokables' => array(
            'Admin\Controller\Answers' => 'Admin\Controller\AnswersController',
            'Admin\Controller\Index'   => 'Admin\Controller\IndexController',
        ),
    ),
    'router'       => array(
        'routes' => array(
            'admin' => array(
                'type'          => 'literal',
                'options'       => array(
                    'route'    => '/admin',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Admin\Controller',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes'  => array(
                    'default' => array(
                        'type'    => 'segment',
                        'options' => array(
                            'route'       => '/[:controller[/:action]]',
                            'constraints' => array(
                                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                            ),
                            'defaults'    => array(
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
    'view_manager' => array(
        'template_path_stack' => array(
            'admin' => __DIR__ . '/../view',
        ),
    ),
);

如果我要更改:'\__NAMESPACE__' => 'Admin\Controller', 'controller' => 'Index','controller' => 'Admin\Controller\Index' 我可以访问索引控制器,但不能访问 Answers。

其他信息:

我发现了骨架应用程序的奇怪行为。我已经下载了新的骨架应用程序并且此配置有效。如果我要去localhost/application/indexlocalhost/application/answers,它可以正常工作。但是,如果我将应用程序模块名称更改为管理员并更改路由器配置(将所有应用程序替换为管理员,将应用程序替换为管理员)并且配置停止工作。谁能解释一下?也许 Application 模块在骨架应用程序中作为默认模块工作?

我正在使用 Zend Framework 2.2.4。

【问题讨论】:

  • 你添加了命名空间Admin\Controller吗?在您的控制器内?如果你能命名你的文件结构,那将会很有帮助。
  • @cptnk 是 ZFTool 添加了命名空间。我已经用文件结构更新了我的问题。
  • 您找到解决方案了吗?我在 2017 年仍然遇到这个问题。谢谢。
  • @HelloWorld 我没有找到原因。我们只是手动编写了每条路线。

标签: php routing namespaces zend-framework2


【解决方案1】:

在上面添加默认键

'answers' => array(
  'type' => 'Zend\Mvc\Router\Http\Literal',
  'options' => array(
    'route'    => '/answers',

    'defaults' => array(
      'controller' => 'Admin\Controller\Answers',
      'action'     => 'index',
    ),
  ),
),

如果这没有帮助,请尝试评论默认键 所以也许可以试试通配符?

'application' => array( 
    'type'    => 'segment', 
    'options' => array( 
        'route'    => '/[:controller][/:action][/:id]', 
        'constraints' => array(
            'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 
            'action'     => '[a-zA-Z][a-zA-Z0-9_-]*', 
            'id'         => '[0-9]+', 
        ), 
        'defaults' => array( 
            'controller' => 'Application', 
            'action'     => 'index',
        ), 
    ), 
    'may_terminate' => true, 
    'child_routes' => array( 
        'default' => array( 
            'type'    => 'Wildcard', 
            'options' => array( 
            ), 
        ), 
    ), 
), 

这只是引导而不是完整的解决方案

【讨论】:

【解决方案2】:

在 Module.php 中设置

public function onBootstrap(MvcEvent $e)
{
    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
}

【讨论】:

    【解决方案3】:

    我不能 100% 确定您要达到的目标,但这可能会在某种程度上对您有所帮助。如果你有一个可变控制器参数,我会像这样设置我的路线:

    'router' => array(
        'routes' => array(
            'admin' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/admin[/:controller[/:action]]',
                    'constraints' => array(
                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
                    ),
                    'defaults' => array(
                        'controller' => 'Admin\Controller\Admin',
                        'action'     => 'index',
                        ),
                    ),
                ),
            ),
         ),
    

    在重定向时,您需要以这种方式指定控制器和操作。

    return $this->redirect()->toRoute('admin', array('action' => 'newAction', 'controller' => 'someOtherController'));
    

    URL View-Helper 等效项:

    $this->url('admin', array('action' => 'newAction', 'controller' => 'someOtherController'));
    

    编辑:

    Zend framework2 将所有配置文件合并到您的模型中,并为路由器模块提供您已配置的阵列。事实上,您可以扩展 Router 类并将其更改为您喜欢的类型。

    正如您可能看到的那样,在您的配置文件中为路由器提供每个模块的命名空间实际上并不是“强制性的”。路由器有您调用的控制器,并且可以通过 zf2 命名约定“跟踪”它们。

    EDIT2:我忘了给路由添加一些约束,你能用更新的路由配置再试试吗?

    【讨论】:

    • 同样的问题。没有命名空间。我的目标是在不手动向所有控制器写入路由的情况下获得控制器
    • 您不必使用我描述的配置为每个控制器编写路由。您只需将参数添加到重定向中。假设您有一个管理模块、一个用户模块和一个应用程序模块。您现在为每个模块添加一个路由。在这些配置中,您只需添加一个“管理”您的控制器及其操作的段。
    • 我得到了相同的结果。我可以访问默认控制器,但不能访问其他控制器。
    • 仍然没有命名空间。 Zend 仍在寻找应答控制器而不是 Admin\Controller\Answer
    猜你喜欢
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2015-02-18
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    相关资源
    最近更新 更多