Zend framework-PHP致命错误的错误页面
在使用Zend 1框架的PHPWebapp上,如果代码抛出异常,我会得到一个很好的错误页面以及我的品牌等等 如果代码遇到PHP致命错误(例如,当对象引用意外为空时“非对象上的方法调用”),那么我只会得到一个Apache500错误页面 在后一种情况下,如何获得一个好的错误页面 我尝试过的事情:Zend framework-PHP致命错误的错误页面,php,zend-framework,error-handling,fatal-error,Php,Zend Framework,Error Handling,Fatal Error,在使用Zend 1框架的PHPWebapp上,如果代码抛出异常,我会得到一个很好的错误页面以及我的品牌等等 如果代码遇到PHP致命错误(例如,当对象引用意外为空时“非对象上的方法调用”),那么我只会得到一个Apache500错误页面 在后一种情况下,如何获得一个好的错误页面 我尝试过的事情: 如果设置了PHPINI“display_errors”,那么我只会得到明文形式的致命错误消息 如果没有设置“display_errors”,那么我将获得Apache默认的500错误页面 在这种情况下,Ap
- 如果设置了PHPINI“display_errors”,那么我只会得到明文形式的致命错误消息
- 如果没有设置“display_errors”,那么我将获得Apache默认的500错误页面
- 在这种情况下,Apache“ErrorDocument”指令似乎被忽略
/**
* Sets up a register_shutdown_function hook to give a nice error page when a
* PHP fatal error is encountered.
*/
protected function _initFatalErrorCatcher()
{
register_shutdown_function(array($this, 'onApplicationShutdown'));
}
public function onApplicationShutdown()
{
$error = error_get_last();
$wasFatal = ($error && ($error['type'] === E_ERROR) || ($error['type'] === E_USER_ERROR));
if ($wasFatal)
{
$frontController = Zend_Controller_Front::getInstance();
$errorHandler = $frontController->getPlugin('Zend_Controller_Plugin_ErrorHandler');
$request = $frontController->getRequest();
$response = $frontController->getResponse();
// Add the fatal exception to the response in a format that ErrorHandler will understand
$response->setException(new Exception(
"Fatal error: $error[message] at $error[file]:$error[line]",
$error['type']));
// Call ErrorHandler->_handleError which will forward to the Error controller
$handleErrorMethod = new ReflectionMethod('Zend_Controller_Plugin_ErrorHandler', '_handleError');
$handleErrorMethod->setAccessible(true);
$handleErrorMethod->invoke($errorHandler, $request);
// Discard any view output from before the fatal
ob_end_clean();
// Now display the error controller:
$frontController->dispatch($request, $response);
}
}
您需要一个自定义路由器类来帮助:
class My_Router_Rewrite extends Zend_Controller_Router_Rewrite
{
public function route(Zend_Controller_Request_Abstract $request)
{
// If the ErrorHandler plugin has stashed the error in a request param, then
// it will have already dealt with routing (see Bootstrap::onApplicationShutdown())
// (Note that this param cannot be spoofed, since any user-supplied params
// will be strings, not objects)
if (is_object($request->getParam('error_handler'))) {
return $request;
} else {
return parent::route($request);
}
}
}
(确保该类已在引导中注册为您的路由器)一种类似于以前的解决方案,但无需重写路由器 在Bootstrap.php中:
public function __construct($application) {
parent::__construct($application);
// handle PHP errors
Core_Error_Handler::set();
}
Core/Error/Handler.php类:
class Core_Error_Handler {
public static function handle() {
if(!$error = error_get_last()) {
return;
}
$frontController = Zend_Controller_Front::getInstance();
$request = $frontController->getRequest();
$response = $frontController->getResponse();
$response->setException(new Exception("Fatal error: $error[message] at $error[file]:$error[line]",$error['type']));
// this clean what is before the error
ob_end_clean();
$frontController->dispatch($request, $response);
}
public static function set(){
register_shutdown_function(array(__CLASS__, 'handle'));
}
}
这不是你需要的吗
Zend\u Controller\u Plugin\u ErrorHandler
处理500个错误fineNo,“Zend\u Controller\u Plugin\u ErrorHandler提供了一个插件,用于处理应用程序引发的异常”(我的重点)。我已经有了这个插件(默认包括在内),它只处理异常。如果没有上面显示的代码,它不会处理致命错误(例如对象引用意外为空时的“非对象上的方法调用”)。我明白了,但您的代码不应该带有错误,因此“尼斯”错误页永远不会被看到,您应该只在开发过程中得到纯文本错误:)lol——谁需要错误处理;记住不要犯任何错误。