如何将控制器/操作设置为Page Not Found

时间:2010-10-03 12:34:03

标签: php zend-framework zend-route

我有一个控制器和操作,我通过自定义URL访问。虽然在默认位置

仍可访问原始路线
zend.com/controller/action

当用户尝试访问此网址时,如何更改此设置以模拟“找不到网页”?有可能吗?

7 个答案:

答案 0 :(得分:6)

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

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

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

RewriteRule ^controller/action/?$ /error/page-not-found/ [L]

答案 1 :(得分: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);

答案 2 :(得分:3)

如果您正在查找基于mod_rewrite的其他解决方案,则可以创建Regex Route以匹配您需要隐藏的操作。

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

mod_rewrite中最简单,最轻量级的解决方案仍为.htaccess

编辑:

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

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

如果您不需要经过身份验证的用户,Zend_Acl可能会与Zend_Router结合使用。

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

Handling errors in Zend Framework | CodeUtopia - The blog of Jani Hartikainen

答案 3 :(得分: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);

答案 4 :(得分:3)

默认情况下,路由器包含:module/:controller/:action/:controller/:action/的默认路由。您可以使用以下命令禁用它们:

$router->removeDefaultRoutes();

然后只有您设置的路线才有效。如果您仍然希望将默认路由用于其他一些事情,则您必须使用其中一个其他答案或添加您自己的“默认”路由,这些路由将匹配您拥有自定义路由的模块/控制器以外的所有路由

答案 5 :(得分:2)

如果您不想删除@Tim Fountain建议的默认路线,则应在控制器中执行以下操作(preDispatchwhateverAction方法)

$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);
}

答案 6 :(得分: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
    }
}

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