在使用 laravel 框架(或者其他框架)的时候,我们都知道在抛出异常报错的时候,其实这个异常并不像我们平时使用 throw new Exception('程序异常'); 抛出的页面那么难看,另外,在抛出异常后,框架会做异常日志记录。
切记,在执行完毕 set_exception_handler后,记得使用 restore_exception_handler 函数将异常处理还原
// 注册全局异常处理程序
set_exception_handler(function (Exception $e) {
// 处理并记录异常
});
// 注册其他的异常处理程序...
// 还原成之前的全局异常处理程序
restore_exception_handler();
demo-注意行号
打印结果
注意
所有的报错类都是集成 Exception 类的。所以,你如果需要打印错误信息,行号等信息,是可以直接调用 public 方法的。我在 demo 中是打印的报错对象
在实际应用中,我们可以根据是否已经打开 debug 等配置,来决定怎么处理报错,并且可以在抛出报错之前可以将报错存入日志
class Exception implements Throwable {
protected $message;
protected $code;
protected $file;
protected $line;
/**
* Clone the exception
* Tries to clone the Exception, which results in Fatal error.
* @link https://php.net/manual/en/exception.clone.php
* @return void
* @since 5.1.0
*/
final private function __clone() { }
/**
* Construct the exception. Note: The message is NOT binary safe.
* @link https://php.net/manual/en/exception.construct.php
* @param string $message [optional] The Exception message to throw.
* @param int $code [optional] The Exception code.
* @param Throwable $previous [optional] The previous throwable used for the exception chaining.
* @since 5.1.0
*/
public function __construct($message = "", $code = 0, Throwable $previous = null) { }
/**
* Gets the Exception message
* @link https://php.net/manual/en/exception.getmessage.php
* @return string the Exception message as a string.
* @since 5.1.0
*/
final public function getMessage() { }
/**
* Gets the Exception code
* @link https://php.net/manual/en/exception.getcode.php
* @return mixed|int the exception code as integer in
* Exception but possibly as other type in
* Exception descendants (for example as
* string in PDOException).
* @since 5.1.0
*/
final public function getCode() { }
/**
* Gets the file in which the exception occurred
* @link https://php.net/manual/en/exception.getfile.php
* @return string the filename in which the exception was created.
* @since 5.1.0
*/
final public function getFile() { }
/**
* Gets the line in which the exception occurred
* @link https://php.net/manual/en/exception.getline.php
* @return int the line number where the exception was created.
* @since 5.1.0
*/
final public function getLine() { }
/**
* Gets the stack trace
* @link https://php.net/manual/en/exception.gettrace.php
* @return array the Exception stack trace as an array.
* @since 5.1.0
*/
final public function getTrace() { }
/**
* Returns previous Exception
* @link https://php.net/manual/en/exception.getprevious.php
* @return Exception the previous Exception if available
* or null otherwise.
* @since 5.3.0
*/
final public function getPrevious() { }
/**
* Gets the stack trace as a string
* @link https://php.net/manual/en/exception.gettraceasstring.php
* @return string the Exception stack trace as a string.
* @since 5.1.0
*/
final public function getTraceAsString() { }
/**
* String representation of the exception
* @link https://php.net/manual/en/exception.tostring.php
* @return string the string representation of the exception.
* @since 5.1.0
*/
public function __toString() { }
public function __wakeup() { }
}
报错处理
set_error_handler(//error handler function
function ($errno, $errstr, $errfile, $errline) {
echo "错误编号: $errno
";
echo "错误信息: $errstr
";
echo "出错文件: $errfile
";
echo "出错行号: $errline
";
die;
});
echo $arr[1];
image.png
image.png
最后介绍如果在组件中想使用自己的报错处理的情况。这是 overtrue 介绍的一种方式
因为代码在不同的组件,不可能用 try...catch。我打算使用 set_exception_handler 注册一个全局异常处理器来做这事儿,但是,我这个只是一个开源组件,可能会被用户用到各种各样的环境中,所以,不能破坏原有框架或者用户自己定义的异常处理器,因为 set_exception_handler 会覆盖前面设置的,所以问题就卡住了。
class MyException extends Exception {}
set_exception_handler(function(Exception $e){
echo "Old handler:".$e->getMessage();
});
$lastHandler = set_exception_handler(function(Exception $e) use (&$lastHandler) {
if ($e instanceof MyException) {
echo "New handler:".$e->getMessage();
return;
}
if (is_callable($lastHandler)) {
return call_user_func_array($lastHandler, [$e]);
}
});
// throw new MyException("Exception two", 1);
throw new Exception("Exception two", 1);
讲解
首先我们要知道,如果你写多个 set_exception_handler 的话,执行报错的时候,会执行最后一个,而不会执行上面的。所以这个时候会执行
lastHandler 对应的是上面的 set_exception_handler ,$e 就是参数