我最终结合了选项#1 和#3。我在模块配置文件中设置了一条包罗万象的路线:
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。看起来分段路由约束使用正则表达式。这可能会对性能造成一些影响。