1. 使用set_error_handler 自定义错误处理函数说明
- 1.创建错误处理函数
- 2.设置不同级别调用函数
- 3.set_error_handler函数指定接管错误处理
set_error_handler 说明
mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
设置一个用户的函数(error_handler)来处理脚本中出现的错误。
本函数可以用你自己定义的方式来处理运行中的错误, 例如,在应用程序中严重错误发生时,或者在特定条件下触发了一个错误(使用 trigger_error()),你需要对数据/文件做清理回收。
重要的是要记住 error_types 里指定的错误类型都会绕过 PHP 标准错误处理程序, 除非回调函数返回了 FALSE。 error_reporting() 设置将不会起到作用而你的错误处理函数继续会被调用 —— 不过你仍然可以获取 error_reporting 的当前值,并做适当处理。 需要特别注意的是带 @ error-control operator 前缀的语句发生错误时,这个值会是 0。
同时注意,在需要时你有责任使用 die()。 如果错误处理程序返回了,脚本将会继续执行发生错误的后一行。
以下级别的错误不能由用户定义的函数来处理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT。
如果错误发生在脚本执行之前(比如文件上传时),将不会 调用自定义的错误处理程序因为它尚未在那时注册。
参数
error_handler
用户的函数需要接受两个参数:错误码和描述错误的 string。 另外有可能提供三个可选参数:发生错误的文件名、发生错误的行号 以及发生错误的上下文(一个指向错误发生时活动符号表的 array)。 该函数可以表示为:
handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )
errno
第一个参数 errno,包含了错误的级别,是一个 integer。
errstr
第二个参数 errstr,包含了错误的信息,是一个 string。
errfile
第三个参数是可选的,errfile, 包含了发生错误的文件名,是一个 string。
errline
第四个参数是一个可选项, errline, 包含了错误发生的行号,是一个 integer。
errcontext
第五个可选参数, errcontext, 是一个指向错误发生时活动符号表的 array。 也就是说,errcontext 会包含错误触发处作用域内所有变量的数组。 用户的错误处理程序不应该修改错误上下文(context)。
如果函数返回 FALSE,标准错误处理处理程序将会继续调用。
error_types
就像error_reporting 的 ini 设置能够控制错误的显示一样, 此参数能够用于屏蔽 error_handler 的触发。 如果没有该掩码, 无论 error_reporting 是如何设置的, error_handler 都会在每个错误发生时被调用。
2. set_error_handler的使用
header(‘content-type:text/html; charset=utf-8‘);
//开启所有的错误报告
error_reporting(-1);
function customError($errno, $errmsg, $errfile, $errline){
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}
switch ($errno) {
case E_USER_ERROR:
echo "<b>My ERROR</b> [$errno] $errmsg<br />".PHP_EOL;
echo " Fatal error on line $errline in file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />".PHP_EOL;
echo "Aborting...<br />\n";
// exit(1);
break;
case E_USER_WARNING:
echo "<b>My WARNING</b> [$errno] $errmsg<br />".PHP_EOL;
break;
case E_USER_NOTICE:
echo "<b>My NOTICE</b> [$errno] $errmsg<br />".PHP_EOL;
break;
default:
echo "Unknown error type: [$errno] $errmsg<br />".PHP_EOL;
break;
}
/* Don‘t execute PHP internal error handler */
return true;
}
set_error_handler(‘customError‘);
echo $test;
settype($var, ‘king‘);
// test();
trigger_error(‘出错了!‘, E_USER_ERROR);
echo ‘<hr>‘;
//回收错误接管
restore_error_handler();
echo $king;
echo ‘<hr>‘;
set_error_handler(‘customError‘, E_ALL&~E_NOTICE);
echo ‘<hr>‘;
settype($var, ‘king‘);
echo ‘continue...............‘;
3.自定义错误处理类
/**
* 自定义错误处理类
*/
class MyErrorHandler
{
public $msg=‘‘;
public $filename=‘‘;
public $line=0;
public $vars=array();
protected $_noticeLog = ‘/tmp/php_error.log‘;
function __construct($msg, $filename, $line, $vars)
{
$this->msg=$msg;
$this->filename=$filename;
$this->line=$line;
$this->vars=$vars;
}
/**
* [deal 自定义错误处理请求]
* @param [int] $errno [错误号]
* @param [string] $errmsg [错误描述]
* @param [string] $errfile [出错的文件]
* @param [int] $errline [出错的行号]
* @param [array] $vars [错误触发处作用域内所有变量的数组]
* @return [bool]
*/
public static function deal($errno, $errmsg, $errfile, $errline, $vars){
$self = new self($errmsg, $errfile, $errline, $vars);
switch ($errno) {
//致命级别的错误发邮件给管理员
case E_USER_ERROR:
return $self->dealError();
break;
case E_USER_WARNING:
case E_WARNING:
return $self->dealWarning();
break;
case E_USER_NOTICE:
case E_NOTICE:
return $self->dealNotice();
break;
default:
//交给php本身的错误机制处理
return false;
break;
}
}
public function get_debug_print_backtrace($traces_to_ignore = 1){
$traces = debug_backtrace();
$ret = array();
foreach($traces as $i => $call){
if ($i < $traces_to_ignore ) {
continue;
}
$object = ‘‘;
if (isset($call[‘class‘])) {
$object = $call[‘class‘].$call[‘type‘];
if (is_array($call[‘args‘])) {
foreach ($call[‘args‘] as &$arg) {
$this->get_arg($arg);
}
}
}
$ret[] = ‘#‘.str_pad($i - $traces_to_ignore, 3, ‘ ‘)
.$object.$call[‘function‘].‘(‘.implode(‘, ‘, $call[‘args‘])
.‘) called at [‘.$call[‘file‘].‘:‘.$call[‘line‘].‘]‘;
}
return implode("\n",$ret);
}
public function get_arg(&$arg) {
if (is_object($arg)) {
$arr = (array)$arg;
$args = array();
foreach($arr as $key => $value) {
if (strpos($key, chr(0)) !== false) {
$key = ‘‘; // Private variable found
}
$args[] = ‘[‘.$key.‘] => ‘.get_arg($value);
}
$arg = get_class($arg) . ‘ Object (‘.implode(‘,‘, $args).‘)‘;
}
}
/**
* [dealError 处理错误级别的错误]
* @return [type] [description]
*/
public function dealError(){
$backtrace=$this->get_debug_print_backtrace();
echo $backtrace; exit;
$errorMsg=<<<EOF
出现了致命错误,如下
产生错误的文件:{$this->filename}
产生错误的信息:{$this->msg}
产生错误的行号:{$this->line}
追踪信息:{$backtrace}
\n
EOF;
error_log($errorMsg, 1, ‘[email protected]‘);
exit(1);
}
/**
* [dealWarning 处理警告级别的错误]
* @return [bool]
*/
public function dealWarning(){
$errorMsg=<<<EOF
出现了警告错误,如下
产生警告的文件:{$this->filename}
产生警告的信息:{$this->msg}
产生警告的行号:{$this->line}
\n
EOF;
error_log($errorMsg, 1, ‘[email protected]‘);
}
/**
* [dealNotice 处理通知级别的错误]
* @return bool
*/
public function dealNotice(){
$datetime = date(‘Y-m-d H:i:s‘, time());
$errorMsg=<<<EOF
出现了通知错误,如下
产生通知的文件:{$this->filename}
产生通知的信息:{$this->msg}
产生通知的行号:{$this->line}
产生通知的时间:{$datetime}
\n
EOF;
return error_log($errorMsg, 3, $this->_noticeLog);
}
}
error_reporting(-1);
set_error_handler(array(‘MyErrorHandler‘, ‘deal‘));
ini_set(‘display_errors‘, 0);
echo $var;
trigger_error(‘zhiming‘, E_USER_ERROR);
trigger_error(‘zhiming‘, E_USER_WARNING);
4.register_shutdown_function函数的使用
1.作用
1.通过register_shutdown_function函数,可以让我们设置一个当执行关闭时可以被调用的另一个函数。
2.当我们的脚本执行完成或意外死掉导致PHP执行即将关闭时,我们的这个函数将会被调用
2.使用场景
1.页面强制被停止
2.程序代码意外终止或超时
3.注意点
1.在register_shutdown_function之前不能有die() exit()等终止函数
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-13 01:33:23