Zend framework2 如何在Zend Framework 2中创建catchall路由
我正在为ZF2创建一个CMS模块,我希望它不必在url中包含“/page”之类的内容。例如,印记页面的url是 你建议怎么做?我已经考虑过以下方法,但我无法让它们中的任何一种按我所希望的方式工作:Zend framework2 如何在Zend Framework 2中创建catchall路由,zend-framework2,Zend Framework2,我正在为ZF2创建一个CMS模块,我希望它不必在url中包含“/page”之类的内容。例如,印记页面的url是 你建议怎么做?我已经考虑过以下方法,但我无法让它们中的任何一种按我所希望的方式工作: 具有连接到我的PageController并将url路径作为参数传递的catchall路由。这里的问题是让catchall路线与现有路线配合得很好。这也意味着所有应该是404错误的页面现在都将通过PageController进行路由,如果在数据库中找不到该页面,则PageController必须处理4
如果有任何关于如何做到这一点的想法,我将不胜感激。理想情况下,该解决方案将能够处理CMS支持的主页(/)。我个人会采取不同的方法 选项1当然会起作用,但我会创建一种新类型的路由器(CmsRouter),然后我们可以创建一条优先于其他静态路由的路由 此路由可以检查数据库中已知页面/段塞的列表,或者更好地使用一些智能缓存来加快查找速度
我当然不会使用方法2),因为在完全没有错误的情况下使用错误条件,我会避免这样做。我个人会采取不同的方法 选项1当然会起作用,但我会创建一种新类型的路由器(CmsRouter),然后我们可以创建一条优先于其他静态路由的路由 此路由可以检查数据库中已知页面/段塞的列表,或者更好地使用一些智能缓存来加快查找速度
我当然不会使用方法2),因为在完全没有错误的情况下使用错误条件,我会避免这样做。我最终将选项1和选项3组合在一起。我在模块配置文件中设置了一个catchall路由:
return array(
// Relative to app root
'routeCacheFile' => 'data/cache/cmsRoutes',
'router' => array(
'routes' => array(
'cmsPage' => array(
'type' => 'segment',
'priority' => 100,
'options' => array(
'route' => '/:pageRoute',
'constraints' => array(
'pageRoute' => 'dynamically-populated-by-bootstrap'
),
'defaults' => array(
'controller' => 'pages',
'action' => 'view'
)
)
)
),
// ...
);
第一个配置选项是缓存文件。稍后再谈。请注意,该路由是一个只有一个元素的段路由:pageRoute
。还有一个约束,我们将在Module.php中这样填写:
public function getConfig()
{
$config = include __DIR__ . '/config/module.config.php';
// Get the cms page routes from a cache file
if (!empty($config['routeCacheFile'])) {
$cachedRoutes = file_get_contents($config['routeCacheFile']);
$config['router']['routes']['cmsPage']['options']
['constraints']['pageRoute'] = $cachedRoutes;
}
return $config;
}
我不只是包含并返回配置数组,而是获取routeCacheFile设置,获取文件的内容,然后使用它们替换“由引导动态填充”约束。缓存文件包含一个简单的管道删除列表,其中列出了所有已发布的路由(详见下文),如下所示:about | staff | some/longer/route | terms of service
最后一点我不会让您感到厌烦,但每次我的PageController保存一个页面时,它都会触发一个服务类,该类会查找所有已发布的路由,并将它们写入配置中的缓存文件
你认为这种方法怎么样?它不中断任何现有路由(我使用优先级设置来设置路由匹配的顺序),不需要数据库查找来路由请求,也不需要滥用错误条件。缺点:存在对文件系统的依赖,这使得单元测试更加困难。也许我可以用Zend\Cache代替。看起来线段布线约束使用了正则表达式。这可能会对性能造成一些影响。我最终将选项1和选项3结合起来。我在模块配置文件中设置了一个catchall路由:
return array(
// Relative to app root
'routeCacheFile' => 'data/cache/cmsRoutes',
'router' => array(
'routes' => array(
'cmsPage' => array(
'type' => 'segment',
'priority' => 100,
'options' => array(
'route' => '/:pageRoute',
'constraints' => array(
'pageRoute' => 'dynamically-populated-by-bootstrap'
),
'defaults' => array(
'controller' => 'pages',
'action' => 'view'
)
)
)
),
// ...
);
第一个配置选项是缓存文件。稍后再谈。请注意,该路由是一个只有一个元素的段路由:pageRoute
。还有一个约束,我们将在Module.php中这样填写:
public function getConfig()
{
$config = include __DIR__ . '/config/module.config.php';
// Get the cms page routes from a cache file
if (!empty($config['routeCacheFile'])) {
$cachedRoutes = file_get_contents($config['routeCacheFile']);
$config['router']['routes']['cmsPage']['options']
['constraints']['pageRoute'] = $cachedRoutes;
}
return $config;
}
我不只是包含并返回配置数组,而是获取routeCacheFile设置,获取文件的内容,然后使用它们替换“由引导动态填充”约束。缓存文件包含一个简单的管道删除列表,其中列出了所有已发布的路由(详见下文),如下所示:about | staff | some/longer/route | terms of service
最后一点我不会让您感到厌烦,但每次我的PageController保存一个页面时,它都会触发一个服务类,该类会查找所有已发布的路由,并将它们写入配置中的缓存文件
你认为这种方法怎么样?它不中断任何现有路由(我使用优先级设置来设置路由匹配的顺序),不需要数据库查找来路由请求,也不需要滥用错误条件。缺点:存在对文件系统的依赖,这使得单元测试更加困难。也许我可以用Zend\Cache代替。看起来线段布线约束使用了正则表达式。这可能有点影响性能。我使用主机名路由器创建了一个catchall:
'wildcard' => array(
'type' => 'Hostname',
'may_terminate' => true,
'options' => array(
'route' => ':subdomain.:domain.:tld',
'defaults' => array(
'__NAMESPACE__' => 'ModName\Controller',
'controller' => 'ModName',
'action' => 'index'
),
),
),
您可能希望将其与能够更改操作的分派事件相结合。为了解决类似的问题,我附加了一个SharedListenerAggregateInterface
,其中包含以下内容:
public function attachShared(SharedEventManagerInterface $sharedManager)
{
$this->listeners[] = $sharedManager->attach('ModName\Controller\ModNameController', MvcEvent::EVENT_DISPATCH, array($this, 'changeAction'), 10);
}
public function changeAction(\Zend\Mvc\MvcEvent $event)
{
if (/* criteria for action foo */) {
$event->getRouteMatch()->setParam('action','foo');
} else if (/* criteria for action bar */) {
$event->getRouteMatch()->setParam('action','bar');
}
}
因为这是一个MvcEvent,所以您可以访问服务管理器,以便执行几乎所有操作,包括数据库调用,以检查路由是否有效。我使用主机名路由器创建了一个catchall:
'wildcard' => array(
'type' => 'Hostname',
'may_terminate' => true,
'options' => array(
'route' => ':subdomain.:domain.:tld',
'defaults' => array(
'__NAMESPACE__' => 'ModName\Controller',
'controller' => 'ModName',
'action' => 'index'
),
),
),
您可能希望将其与能够更改操作的分派事件相结合。解决