问题
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.
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;
}
}
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.
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();
}
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:
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.
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.
UPDATE
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
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!
回答1:
You are right. Same has been the frustration too (I know that feel, bro!)
Anyways, you can define what type of error should go where using Zend_Http*
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;
}
}
Use it :) :)
Enjoy Life!
Happy coding! :)
来源:https://stackoverflow.com/questions/12197946/why-my-site-is-always-using-the-errorcontroller-for-all-types-of-errors-irrespec