为什么我的站点总是使用 ErrorController 来处理所有类型的错误,而不管 HTTP 状态代码如何? [英] Why my site is always using the ErrorController for all types of errors irrespective of HTTP Status code?

查看:33
本文介绍了为什么我的站点总是使用 ErrorController 来处理所有类型的错误,而不管 HTTP 状态代码如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们多年来一直在运营 Zend Framework 电子商务网站.它没有 100% 使用 MVC 结构,但我们尝试在网站上执行新升级等时朝着更好"的编码结构发展.最近,我们也对网站进行了一些重大更改.由于有多个开发者,这个问题有点难以追踪,但我写在这里是为了寻求任何帮助或建议.

We've been running a Zend Framework e-commerce site for years. It hasn't used the MVC structure 100% but we try to progress it towards a "better" coding structure as we perform new upgrades on the site and so on. Recently we made some significant changes to the site as well. As there are multiple developers this issue is a little difficult to track, but I'm writing here to get any kind of help or advice.

在我们之前的站点上,我们的 ErrorController 用于在出现问题时简单地将 301 重定向到pagenotfound"页面,包括 404.这在我们的新站点上继续.我们意识到这不是网站应该做的,所以我们正在尝试改变这一点 - 即当我们在 404 上时使用正确的 404 代码,等等.刚刚在我们的测试站点上更新 ErrorController 时,我意识到我们站点上的每个操作都以某种方式运行 ErrorController.我怎么知道这个?因为我现在的测试站点ErrorController如下:

On our previous site, our ErrorController was used to simply do a 301 redirect to a "pagenotfound" page when something goes wrong, including a 404. This continues on our new site. We realise this is not what a website should do, so we are trying to change that - i.e. use proper 404 code when we are on a 404, and so on. On updating ErrorController just now on our test site, I have realised that EVERY action on our site is somehow running the ErrorController. How do I know this? Because my current test site ErrorController is as follows:

<?php 
/** @see Zend_Controller_Action */ 
require_once 'Zend/Controller/Action.php'; 

class ErrorController extends Zend_Controller_Action
{  
public function errorAction()
{
    $errors = $this->_getParam('error_handler');

    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;
            default:
                // application error
                $this->getResponse()->setHttpResponseCode(500);
                $e = $this->_getParam('error_handler');
                $this->view->message = $e['exception']->getMessage();
                break;
    }
    $this->view->exception = $errors->exception;
    $this->view->request   = $errors->request;
}
}

上面的代码现在在我的测试站点上很好,但是当我转到任何工作页面(查看 Firebug 上的 NET 选项卡)时,我看到的是500"服务器错误状态代码.这是令人惊讶的,因为对于工作页面,它甚至不应该加载 ErrorController 对吗?然而它是,状态代码 500(来自上面的默认开关案例)被发送.

The above code, now on my test site, is fine but when I go to any working page (viewing the NET tab on Firebug), I am a seeing "500" server error status code. This is surpising because for working pages, it shouldn't even load the ErrorController right? However it is, and the status code 500 (from the default switch case above) is sent through.

我们的站点也使用 IndexController,没有其他控制器 - 我们所有的操作都在 IndexController 中.我们有一个特殊的 PagesAction 如下:

Our site uses an IndexController as well, and no further controllers - all our actions are within IndexController. We have a special PagesAction as follows:

public function pagesAction() 
{
    $this->view->placeholder('errors')->captureStart();
    //proceed as normal
    if ($this->checkSiteCode()) { //this will be false if we are not on the correct site code (ignore this)
        $this->view->this_includefile = "pages/view";
        $this->getControllerIncludeFile($this->view->this_includefile); //include some special include file for our work
    }
    $this->view->placeholder('errors')->captureEnd();
} 

以上是我们引导程序的默认操作,例如,如果您转到www.mydomain.com/stores/然后上面的 pagesAction() 将被调用以检查我们的数据库(CMS)中是否存在商店"并适当地加载内容.内容加载正常,但错误 500 仍然存在(在测试站点上).因此,我的问题是:

The above a default action on our bootstrap, for example if you go to www.mydomain.com/stores/ then the above pagesAction() will be called to check if "stores" exists in our database (CMS) and loads the content appropriately. The content is loading fine, but the Error 500 still exists (on the test site). Therefore my questions are:

  1. 以前在旧站点(我们仍然可以通过另一个测试域访问)上,不会发生此问题.因此,我们的引导程序配置或其他核心文件上的某些更改导致了我们的新站点上发生了这种情况.这对我们来说是一个新问题,我只是想找出去哪里找.有任何想法吗?但是,我在引导程序中没有看到任何对errorcontroller"的引用.使用上面的错误占位符是因为我们使用了一个布局(新站点的新布局),出于某种原因,它隐藏了我们想要看到的任何 PHP 控制器错误.因此,我们将其存储在错误"占位符中,以便从我们的角度进行打印.这是一个单独的观点,但可能值得注意,因为我们没有在旧网站上这样做.我们现在正在比较的新旧站点之间也有一些引导程序更改.

  1. Previously on the old site (which we can still access via another test domain), this problem does not happen. Therefore something - some change on our bootstrap configuration or another core file - has caused this to happen on our new site. This is a new issue to us and I'm just trying to find out where to look. Any ideas? I don't see any reference to "errorcontroller" in my bootstrap however. The above placeholder for errors is used because we are using a Layout (new to the new site) which for some reason hides any PHP controller errors that we want to see. Therefore we store it in a "errors" placeholder for printing from our view. This is a separate point but probably worth noting since we did not do this on our old site. There are also several bootstrap changes between the old and new site which we are comparing now.

我们的主要目的是更新 pagesAction 以在我们的数据库中找不到特定 URL 时抛出 404(而不是重定向到另一个 CMS 管理页面pagenotfound",即 www.mydomain.com/pagenotfound/是一个普通页面).基本上我问的是如何编码它以便当 pagesAction 意识到特定的 URL 不存在时实际调用错误控制器?解决上述问题 1 后,我需要解决此问题,以便 ErrorController 仅在必要时加载.

Our primary aim here is to update the pagesAction to throw a 404 when a particular URL is not found in our database (and not redirect to "pagenotfound" which is another CMS managed page, i.e. www.mydomain.com/pagenotfound/ is a normal page). Basically I'm asking how to code it so that the Error Controller is actually called when the pagesAction realises that a particular URL does not exist? Once problem 1 above is resolved, I'd need to solve this problem so that the ErrorController can load only when necessary.

更新

我们刚刚发现 bootstrap.php 中的以下代码,删除后不再加载 ErrorController 和 501 错误.

We have just found out that the following code in bootstrap.php, when removed, no longer loads the ErrorController and 501 error.

$acl = new Zend_Acl();
$registry = Zend_Registry::getInstance();
$registry->set('acl', $acl);  // store whole ACL definition to registry for use in AuthPlugin plugin

但是,上面的代码完全禁用了 $registry,因此我仍在寻找实际导致问题的行,因为有更多代码可以访问 $registry.我会不断更新这篇文章,但对上述问题 1 和 2 的任何帮助将不胜感激!

However the above disables the $registry completely so I'm still looking for what line actually causes the problem as there are more codes that access the $registry. I'll keep this post updated, but ANY help on problems 1 and 2 above would be much appreciated!

推荐答案

你说得对.也有同样的挫败感(我知道那种感觉,兄弟!)

You are right. Same has been the frustration too (I know that feel, bro!)

无论如何,您可以使用 Zend_Http*

Anyways, you can define what type of error should go where using Zend_Http*

如您所见,我已将进入 ErrorController 的方式调整为SET";以这种方式处理 HTTP 状态代码,它也会更改标头";页面的信息.例如,在第一次调整中.我正在检查 Routes/Controllers/Actions 如果没有找到然后设置 404 ,记录事件并呈现脚本!

As you can see I have tweaked the way into my ErrorController to "SET" the HTTP Status Code that way, it will also change the "header" information of the page. Example, in first tweak. I am checking for Routes/Controllers/Actions if none are found then set 404 , log the incident and render a script!

class ErrorController extends Zend_Controller_Action {

  public function errorAction() {
    $errors = $this->_getParam('error_handler');

    if (!$errors || !$errors instanceof ArrayObject) {
      $this->view->message = 'You have reached the error page';
      return;
    }

    switch ($errors->type) {
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
      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);
        $priority = Zend_Log::NOTICE;
        $this->view->error_code = $this->getResponse()->getHttpResponseCode();
        $this->view->message = "Page Not Found";
        $this->renderScript('error/error_404.phtml');
        break;
      default:
        // application error
        print_r($this->getResponse());
        $this->getResponse()->setHttpResponseCode(500);
        $priority = Zend_Log::CRIT;
        $this->view->error_code = $this->getResponse()->getHttpResponseCode();
        $this->view->message = 'Application error';
        if ($log = $this->getLog()) {
        $log->log($this->view->message, $priority, $errors->exception);
        $log->log('Request Parameters', $priority, $errors->request->getParams());
        $this->renderScript('error/error_500.phtml');
        }

    // conditionally display exceptions
        if ($this->getInvokeArg('displayExceptions') == true) {
                $this->view->exception = $errors->exception;
        }

        $this->view->request = $errors->request;
        $this->view->error_code = $this->getResponse()->getHttpResponseCode();
        $this->renderScript('error/error_500.phtml');
        break;
    }

    // Log exception, if logger available
    if ($log = $this->getLog()) {
      $log->log($this->view->message, $priority, $errors->exception);
      $log->log('Request Parameters', $priority, $errors->request->getParams());
    }

    // conditionally display exceptions
    if ($this->getInvokeArg('displayExceptions') == true) {
      $this->view->exception = $errors->exception;
    }

    $this->view->request = $errors->request;
  }

  public function getLog() {
    $bootstrap = $this->getInvokeArg('bootstrap');
    if (!$bootstrap->hasResource('Log')) {
      return false;
    }
    $log = $bootstrap->getResource('Log');
    return $log;
  }

}

使用它:) :)

享受生活!

快乐编码!:)

这篇关于为什么我的站点总是使用 ErrorController 来处理所有类型的错误,而不管 HTTP 状态代码如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆