为什么我的网站总是使用ErrorController来处理所有类型的错误而不管HTTP状态代码?

时间:2012-08-30 13:25:56

标签: php zend-framework

我们多年来一直在运行Zend Framework电子商务网站。它没有100%使用MVC结构,但我们尝试将其推向“更好”的编码结构,因为我们在网站上执行新的升级等等。最近我们也对该网站进行了一些重大更改。由于有多个开发人员,这个问题有点难以跟踪,但我写这里是为了获得任何帮助或建议。

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

<?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(来自上面的默认开关案例)通过发送。

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

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)中是否存在“stores”并适当地加载内容。内容加载正常,但错误500仍然存在(在测试站点上)。因此我的问题是:

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

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

  3. 更新

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

    $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的任何帮助将非常感谢!

1 个答案:

答案 0 :(得分:2)

你是对的。同样令人沮丧的是(我知道那种感觉,兄弟!)

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

定义哪种类型的错误

正如您所看到的,我已经调整了我的ErrorController方式以“设置”HTTP状态代码的方式,它也将更改页面的“标题”信息。例如,在第一次调整中。我正在检查路由/控制器/操作,如果没有找到,则设置404,记录事件并渲染脚本!

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

}

使用它:):)

享受生活!

快乐的编码! :)