我们刚刚开始使用 zf2,所以其他人制作了一个 Thumbnail 服务器模块,然后我添加了一个 Lookup 服务器模块。我称这些服务器是因为它们都是 RESTful api。最初它们似乎一起工作,但有人对我的模块做了一些更改,现在缩略图服务器将无法工作,除非从 application.config.php
模块列表中删除 Lookup。无论如何,查找服务器都可以工作。查看代码,我看不出对 Lookup 所做的更改会如何影响 Thumbnail。我收到的错误如下所示:
<h1>A 404 error occurred</h1>
<h2>Page not found.</h2>
<p>The requested controller was unable to dispatch the request.</p>
<dl>
<dt>Controller:</dt>
<dd>Lookup\Controller\Lookup</dd>
</dl>
这是 application.config.php
的样子:
<?php
return array(
'modules' => array(
'Application',
'SanRestful',
'Album',
'AlbumRest',
'Thumbnail',
'Lookup',
'AP_XmlStrategy',
),
'module_listener_options' => array(
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
'config/autoload/{,*.}' . (getenv('APPLICATION_ENV') ?: 'production') . '.php',
),
'module_paths' => array(
'./module',
'./vendor',
),
),
);
如您所见,有初始的相册模块和其他一些实验性模块。我的查找模块使用优秀的 AP_XmlStrategy module by Allessandro Pietrobelli .
下面是缩略图 module.config.php
。它有一个可能未被使用的约束,因为没有名为“id”的参数,但这不应该把事情搞砸,不是吗?
<?php
return array(
'controllers' => array(
'invokables' => array(
'Thumbnail\Controller\Thumbnail' => 'Thumbnail\Controller\ThumbnailController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'thumbnail' => array(
'type' => 'segment',
'options' => array(
'route' => '/thumbnail[/:action][/:output]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Thumbnail\Controller\Thumbnail',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'thumbnail' => __DIR__ . '/../view',
),
),
);
还有 Lookup module.config.php
,标识符被混淆了:
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'pgsql:dbname=<dbname>;host=<host>;port=<port>',
'username' => '<username>',
'password' => '<password>',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
'aliases' => array(
'db' => 'Zend\Db\Adapter\Adapter',
),
),
'controllers' => array(
'invokables' => array(
'Lookup\Controller\Lookup' => 'Lookup\Controller\LookupController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'lookup' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:action][/:version][/:resource][/:code][/:resource_xref]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'version' => '[a-zA-Z][a-zA-Z0-9_-]*',
'resource' => '[a-zA-Z][a-zA-Z0-9_-|\.]*',
'code' => '[a-zA-Z][a-zA-Z0-9_-]*',
'resource_xref' => '[a-zA-Z][a-zA-Z0-9_-|\.]*',
),
'defaults' => array(
'controller' => 'Lookup\Controller\Lookup',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'lookup' => __DIR__ . '/../view',
),
'strategies' => array(
'ViewJsonStrategy',
'ViewXmlStrategy',
),
),
);
我是否遗漏了任何明显的错误?
最佳答案
请求可以被多条路由匹配。举个例子:url/foo 可以与文字路由 /foo
以及路由 [/:action]
匹配。要区分这两个路由,配置它们的顺序很重要。
发生了什么,路由按后进先出顺序匹配,所以最后一条路由必须是最明确的。在“/foo”示例中,此配置将匹配文字:
'router' => array(
'routes' => array(
'test1' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:action]',
'defaults' => array(
//
),
),
),
'test2' => array(
'type' => 'literal',
'options' => array(
'route' => '/foo',
'defaults' => array(
//
),
),
),
),
),
然而,在下面的配置中,文字将永远不会被匹配,因为[/:action]
可能匹配/foo
.
'router' => array(
'routes' => array(
'test2' => array(
'type' => 'literal',
'options' => array(
'route' => '/foo',
'defaults' => array(
//
),
),
),
'test1' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:action]',
'defaults' => array(
//
),
),
),
),
),
现在看看您的两个模块。第一个 (Thumbnail) 有一个路由 /thumbnail[/:action][/:output]
。它以文字部分开始。然后你的第二个模块(Lookup)有一个路由 [/:action][/:version][/:resource][/:code][/:resource_xref]
。
现在,如果您回到后进先出顺序,任何以 /thumbnail
开头的路线都将在 Lookup route 匹配。
解决方案
有两种选择。首先是交换模块的顺序。如果模块之间存在相互依赖关系,这始终是一个重要的顺序。先加载 Lookup 再加载 Thumnnail,所以缩略图路由放在后面的配置中。因此,它首先匹配。因此,您的应用程序再次运行。
然后是第二种解决方案(恕我直言,更好)。您在 Lookup 中有一条“一条路线来统治他们”,这不是一个很好的做法。你可能会像现在一样陷入麻烦,却不知道出了什么问题。因此,在您的 route 尽可能多地指定。使 Lookup 的第一部分也是文字(/lookup[/:action][/:version][/:resource][/:code][/:resource_xref]
不是一个选项吗?) .或者删除 action 作为参数并使它们成为文字:
'router' => array(
'routes' => array(
'view' => array(
'type' => 'segemnt',
'options' => array(
'route' => '/view[/:version][/:resource][/:code][/:resource_xref]',
'defaults' => array(
'action' => 'view',
//
),
),
),
'create' => array(
'type' => 'segment',
'options' => array(
'route' => '/create[/:version][/:resource][/:code][/:resource_xref]',
'defaults' => array(
'action' => 'create',
//
),
),
),
'update' => array(
'type' => 'segment',
'options' => array(
'route' => '/update[/:version][/:resource][/:code][/:resource_xref]',
'defaults' => array(
'action' => 'update',
//
),
),
),
// And so on
),
),
这样,您的查找模块就有一个固定的起点,并且仅当这些第一部分在请求 uri 中时才匹配。然后你的 /thumbnail[/:action][/:output]
与 Lookup 路由完全分离。
关于zend-framework2 - zf2 router : One module makes the router unable to find another module. 我怎样才能让两者都工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16241516/