9

我有一个通过自定义 URL 访问的控制器和操作。尽管在默认位置,原始路线仍然可以访问

zend.com/controller/action

当用户尝试访问此 URL 时,如何更改它以模拟“找不到页面”?是否可以?

4

7 回答 7

6

您可以更改主控制器脚本以将某个控制器名称和操作名称重定向到新页面。但是向.htaccess文件中添加新规则可能更容易,表明应该将这个特定的 URL 重定向到错误页面。例子:

RewriteRule ^controller/action/?$ / [R=404,L]

或将页面重定向到您网站中的错误页面:

RewriteRule ^controller/action/?$ /error/page-not-found/ [L]
于 2010-10-03T19:45:24.803 回答
6

如果操作处理程序用于响应两个 URL,则首先必须检测正在请求哪个 URL(使用 $this->_request->getRequestUri())。如果检测到默认 URL,我认为创建“找不到页面”的最简单方法是使用

$this->_redirect("/path/to/simulated/404/page") 

并设置一个控制器和动作来响应。

不过,这实际上不会发送 HTTP 404。为此,我认为您必须在动作处理程序中引发异常。我不知道这样做的官方“zendy”方式是什么,但这似乎有效:

throw new Zend_Controller_Action_Exception('Not Found', 404);
于 2010-10-15T16:57:11.377 回答
3

如果您正在寻找其他解决方案而不是mod_rewrite基于,您可以创建一个正则表达式路由来匹配您需要隐藏的操作。

另一种解决方案是使用Zend_Acl限制对 Actions的访问,将每个操作视为 ACL 资源。

但最简单、最轻量级的解决方案仍然mod_rewrite.htaccess.

编辑:

如您所见,这可以通过多种方式完成。但可能,您将需要某种switch,以仍然允许以某种方式访问​​“隐藏”操作。在这种情况下,请使用:

  • mod_rewrite快速实施(切换需要知道.htaccess规则的人)
  • Zend_Router - 知道正确路线的人仍然可以访问该功能
  • Zend_Acl + Zend_Auth用于可扩展和安全的解决方案。

如果您不需要经过身份验证的用户,则Zend_Acl结合使用Zend_Router可能是解决方案。

有关智能处理异常和构建 ACL,请参阅此(以及此博客上的其他帖子):

Zend 框架中的错误处理 | CodeUtopia - Jani Hartikainen 的博客

于 2010-10-15T17:57:30.843 回答
3

你需要使用:

$this->getResponse()->setHttpResponseCode(404);

并建立自己的 404 视图

$this->view->message = 'Page not found';

或者您可以转发到错误控制器,例如

$this->_forward('page-not-found', 'error');

最后,如果您的错误控制器中有

//...
switch ($errors->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:

                // 404 error -- controller or action not found
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;
//...

你可以像@bogeymin 说的那样做:

throw new Zend_Controller_Action_Exception('Not Found', 404);
于 2010-10-15T19:40:18.143 回答
3

默认情况下,路由器包含:module/:controller/:action/和的默认路由:controller/:action/。您可以使用以下方法禁用这些:

$router->removeDefaultRoutes();

那么只有您设置的路线才会起作用。如果您仍想将默认路由用于其他一些事情,您要么必须使用发布的其他答案之一,要么添加您自己的“默认”路由,该路由将匹配除您拥有自定义路由的模块/控制器之外的所有路由.

于 2010-10-18T10:56:37.060 回答
2

如果你不想像@Tim Fountain建议的那样删除默认路由,你应该在你的控制器中做这样的事情(preDispatch或者whateverAction方法)

$router = $this->getFrontController()->getRouter();
$route = $router->getCurrentRouteName();
// if we reached this controller/action from the default route, 404
if ($route == 'default')
{
  throw new Zend_Controller_Action_Exception('Not Found', 404);
}
于 2010-10-20T23:40:28.397 回答
0

我认为,以上所有答案都不正确。这些展示了实现相同目标的方法,但在应用程序中的错误位置显示逻辑,这最终可能会在以后造成麻烦。

路线逻辑的正确部分是,在路线中非常简单。缺少的是默认路由Zend_Controller_Router_Route_Module不允许您向特定路由添加例外。因此,您需要做的是从您的路由中删除默认路由,并在其位置添加一个新的自定义路由(其功能应与默认路由完全相同,但允许排除)。

您可以通过扩展默认路由的类来编写新路由。

class My_Custom_Route extends Zend_Controller_Router_Route_Module
{
    protected $_excludes = array();

    public function exclude($abc)
    {
         //add to $_excludes here the controller/action you want to exclude
    }

    public function match($abc)
    {
         //add functionality here that denies if the mod/contr/action is in $_excludes
         //you can also add this in a separate method
         //re-use parent code
    }
}

您现在可以添加添加排除项,例如在配置文件中,并在您启动新路由的位置加载 + 添加排除项(并将其添加到路由器)。就行了。

于 2010-10-22T10:30:00.957 回答