如何将控制器/操作设置为“找不到页面”

发布于 2024-09-25 21:15:23 字数 150 浏览 8 评论 0原文

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

zend.com/controller/action

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

I have a controller and action which I'm accessing through a custom URL. The original route is still accessible though at the default location

zend.com/controller/action

How can I change this to simulate a "Page not found" when the user tries to access this URL? Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

魂牵梦绕锁你心扉 2024-10-02 21:15:23

如果操作处理程序用于响应两个 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);

If the action handler is used to respond to both URLs, you would first have to detect which URL is being requested (using $this->_request->getRequestUri()). If the default URL is detected I think the easiest way to create a "page not found" would be to use

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

and set up a controller and action to respond.

This won't actually send an HTTP 404, though. To do that, I think you would have to raise an exception within your action handler. I don't know what the official "zendy" way of doing this is, but this seems to work:

throw new Zend_Controller_Action_Exception('Not Found', 404);
鯉魚旗 2024-10-02 21:15:23

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

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

或者将页面重定向到站点内的错误页面:

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

You could change the main controller script to redirect a certain controller name and action name to a new page. But it's probably easier to add a new rule to the .htaccess file, indicating that this specific URL should be redirected to an error page. Example:

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

Or redirect the page to an error page within your site:

RewriteRule ^controller/action/?$ /error/page-not-found/ [L]
天邊彩虹 2024-10-02 21:15:23

您需要使用:

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

You need to use:

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

And build your own 404 view

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

Or you could forward to an error controller for example

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

Finally, if you have in your error controller

//...
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;
//...

You can just do as @bogeymin said:

throw new Zend_Controller_Action_Exception('Not Found', 404);
静谧 2024-10-02 21:15:23

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

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

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

编辑:

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

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

如果您不需要经过身份验证的用户,Zend_AclZend_Router 组合可能是解决方案。

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

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

If you are looking other solutions than mod_rewrite based, you may create a Regex Route to match the actions you need to hide.

The other solution is to restrict access to Actions using Zend_Acl, treating each action as an ACL resource.

But the simplest and most lightweight solution is still mod_rewrite in .htaccess.

Edit:

As you can see, this may be done in numerous ways. But probably, you will need some kind of the switch, to still allow somehow to access the "hidden" action. In this case, use:

  • mod_rewrite for quick implementation (switching requires the person to know the .htaccess rules)
  • Zend_Router - the person who knows the right route can still access the feature
  • Zend_Acl + Zend_Auth for scalable and secure solution.

If you don't need to have authenticated users, Zend_Acl combined with Zend_Router might be the solution.

For smart handling the exceptions and building ACL's, see this (and other posts on this blog):

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

风尘浪孓 2024-10-02 21:15:23

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

$router->removeDefaultRoutes();

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

By default the router includes default routes for :module/:controller/:action/ and :controller/:action/. You can disable these with:

$router->removeDefaultRoutes();

then only routes you setup will work. If you still want to use the default routes for some other things, you'll either have to go with one of the other answers posted or add your own 'default' routes which will match all but the modules/controllers you have custom routes for.

岁月蹉跎了容颜 2024-10-02 21:15:23

如果您不想删除默认路由 @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);
}

If you don't want to remove the default route as @Tim Fountain suggests, you should do something like this in your controller (either preDispatch or whateverAction methods)

$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);
}
与他有关 2024-10-02 21:15:23

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

路线逻辑的正确部分是在路线中,多么简单。缺少的是默认路由 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
    }
}

您现在可以在配置文件中添加排除项,然后在启动新路由的位置加载+添加排除项(并将其添加到路由器)。你走吧。

I think, all answers above are incorrect. Those show ways to achieve the same thing, but present logic at the wrong place in your application, which eventually can cause trouble later on.

The correct part of your route logic is, how extremely simple, in the routes. What is missing is that the default route Zend_Controller_Router_Route_Module does not allow you to add exceptions to specific routes. So what you need to do, is remove the default route from your routes, and add a new custom route (which should function exactly as the default route, but allows excludes) at it's place.

You can write the new route by extending the class of the default route.

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
    }
}

You can now add add the excludes for example in a config file, and load + add the excludes at the place you initiate the new Route (and add it to the router). Off you go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文