CakePHP:如何创建路由;后退”;


CakePHP: How to create a routing "fall-back"

我们的URL结构发展迅速,我们的日志有时会充满404个错误,这些错误来自用户试图访问不存在的旧URL。我希望保持日志的整洁,同时避免向这些用户显示404页面。有没有办法设置一个"回退"路由,这样,如果没有找到操作,用户就会降落在控制器的索引上(或者错误页面之外的任何地方)。

我知道如何有条件地手动连接路由。到目前为止,我们就是这样处理这个问题的,但这是一项劳动密集型的工作,因为每次URL结构发生变化时,我们都需要添加一个新的。

例如:

Router::connect('/old/url/:param', array('controller' => 'new', 'action' => 'index'), array('param' => '.*[^0-9/]+.*'));

如果我们能做这样的事情会容易得多:

Router::connect('/some_controller/ + ...anything that doesnt exist', array('controller' => 'some_controller', 'action' => 'index') );

这可能吗?

更新

为了澄清,我不简单地使用通配符的原因是:我需要连接/重定向的URL并不都遵循相同的模式。为了演示,以下是我试图重定向的一些URL。。。

example.com/a/b/ --> example.com/a/
example.com/a/b/34  --> example.com/a/
example.com/a/c/ --> example.com/a/

但我不想重定向。。。

example.com/a/d

因此,我的问题并没有通过Burzum以下建议(翻译为本例)来解决:Router::redirect('/a/b/*' ...Router::redirect('/a/*' ...,因为这将错过应该成为目标的链接或应该(分别)成为目标的链路。

当然,我可以为我想要的每个链接编写新的连接/重定向路由,但避免这种麻烦是这个问题的重点。此外,这是一个完全"被动"的解决方案,因为我需要在检查调试日志并看到对不存在的控制器/actions/的请求后应用新的路由。我正在努力做到主动,防止日志在发生变化时出现错误请求。

有关重定向路由,请参阅本书。我不会为你复制粘贴整个部分,所以我建议你阅读链接。

根据你的评论,我认为你不理解答案,或者你有其他要求。您的问题陈述如下:

我们的URL结构发展迅速,有时我们的日志填充404个用户试图访问旧的、不存在的错误URL

对此的正确解决方案是使用重定向和HTTP状态301。以下部分摘自官方文档,并对示例进行了修改,以帮助您理解它

重定向路由允许您为传入路由,并将它们指向不同的URL。当您希望通知客户端应用程序资源已经移动,并且您不希望为同一内容公开两个URL。

Router::redirect('/old/url/*', array('controller' => 'some', 'action' => 'index'), array('status' => 301));

阅读HTTP状态,主要是301。

HTTP响应状态代码301 Moved Permanently用于永久重定向,即使用URL的当前链接或记录接收到的301 Moved Permanently响应应该是更新为响应的位置字段中提供的新URL。此状态代码应与位置标头一起使用。RFC 2616声明:

  • 如果客户端具有链接编辑功能,它应该更新对请求URI的所有引用
  • 人们的反应令人啼笑皆非
  • 除非请求方法是HEAD,否则实体应该包含一个小的超文本注释,其中包含指向新URI的超链接
  • 如果301状态代码是响应于除GET或HEAD之外的任何类型的请求而接收的,则客户端必须在重定向之前询问用户

更新:

此外,这是一个完全"被动"的解决方案,因为我需要应用新的检查调试日志并查看请求后路由到不存在的控制器/操作/。

嗯,这应该是有限的行动量。因此,你必须声明所有这些,至少对于每个控制器,并确保它与一组操作匹配:

Router::redirect('/a/:action/*', array('controller' => 'some', 'action' => 'index'), array('status' => 301, 'action' => 'action1|action2'));

如果你有更具体的URL想要匹配,你必须找到一个可以匹配的模式,或者你必须声明每个路由/重定向。

example.com/a/b/34

这看起来更像是一个再也找不到的特定记录。您应该有一个尝试获取数据的方法,在您的(希望如此)模型方法中抛出NotFoundException,并在控制器中捕获它,然后使用$this->redirect(array(…),301);以重定向它们。

你应该使用301状态在路由上重定向的另一个原因是SEO:如果你只是将相同的内容连接到几个URL,你很可能会从大多数搜索引擎中得到负面影响。