一、PHP中错误模块简介
PHP错误与异常是两个不同的概念
1.1 错误类型
- 语法错误,如少分号
- 环境错误,如权限、打开文件失败、数据库服务器不可用
- 逻辑错误,如a==b 写成了a=b
1.2 PHP常见错误级别
-
Depracated
最低级别的错误 (deprecated不建议,不推荐,如老版本的正则ereg()
函数换掉即可,并不影响PHP的执行) -
Notice
通知级别的错误(语法不恰当导致的,不影响PHP的正常运行,如打印一个未定义的变量,所以我们一开始就要养成良好的书写规范) -
Warning
警告级别的错误(必须修改代码) -
Fatal error
致命级别的错误,程序会停止
-
Parse error
语法解析错误,在代码运行前检查,将无法执行代码
-
E_USER_相关的错误
由用户定义的错误,手动抛出错误时会用到
1.3 如何设置错误级别
1.3.1 php.ini配置文件
error_reporting=E_ALL & ~E_NOTICE # 显示所有但不显示提醒错误
display_errors = Off|On # 是否显示错误,线上后关闭提高用户体验
1.3.2 动态设置
error_reporting() # 专业php错误处理设置函数,动态设置错误级别
error_reporting(0) # 不显示所有错误,但是解析parse语法错误会显示
error_reporting(-1) # 显示所有错误
Error_reporting(E_ALL|~E_WARING) # 除了警告错误以外的错误级别都报告
1.3.3 运行时设置配置选项的值
ini_set(option,value)
ini_set(error_reporting,0)
ini_set(error_reporting,-1)
ini_set(error_reporting,E_ALL)
ini_set(display_errors,0)
ini_set(display_errors,OFF/0)
error_reporting(-1);
14. trigger_error手动触发错发
@
错误抑制符,放在行首不显示该行错误
手动抛出自定义错误信息:trigger_error('错误提示内容',E_USER_NOTICE)
错误级别:
E_USER_NOTICE # 继续执行(通知级别)
E_USER_WARNING # 继续执行(警告错误)
E_USER_ERROR # 程序不再执行(致命错误)
二、处理PHP中的错误
2.1 将错误日志保存在指定文件中
ini_set('display_errors','off') # 不显示错误给用户
ini_set("error_log","c:\error.log");
error_reporting(-1); # 显示所有错误
2.2 错误日志保存在系统日志中
ini_set("error_log", 'syslog')
2.3 将错误日志发送到邮件
error_log("this is a errormsg",1,[email protected]);
三、自定义错误处理器
3.1 set_error_handler自定义错误处理
set_error_handler("自定义函数名",'错误级别(选填)') # 设置一个用户定义的错误处理函数
restore_error_handler(); # 回收(取消自定义错误函数接管php系统错误)
3.2 自定义错误处理器
class MyErrorHandler{
//错误信息
public $message = '';
//错误文件
public $filename = '';
//错误行号
public $line = 0;
//额外信息
public $vars = array();
protected $_noticelog = 'G:\notice\noticeLog.log';
public function __construct($message, $filename, $line, $vars)
{
$this->message = $message;
$this->filename = $filename;
$this->line = $line;
$this->vars = $vars;
}
//根据不同错误级别对应不同操作
//遵循handler错误处理原则,errno:错误代码,line:错误行号
public static function deal($errno,$errmsg,$filename,$line,$vars)
{
$self = new self($errmsg,$filename,$line,$vars);
switch ($errno)
{
case E_USER_ERROR://致命级别
return $self->dealError();
break;
case E_USER_WARNING://警告级别
case E_WARNING:
return $self->dealWarning();
break;
case E_NOTICE://通知级别
case E_USER_NOTICE:
return $self->dealNotice();
break;
default:
return false;
}
}
/**
* 如何处理致命错误
*/
public function dealError()
{
//开启内存缓冲
ob_start();
//回溯上一条信息
debug_print_backtrace();
$backtrace = ob_get_flush();
$errorMsg = <<filename}
产生错误的信息:{$this->message}
产生错误的行号:{$this->line}
追踪信息:{$backtrace}
EOF;
// error_log($errorMsg,1,'[email protected]');
error_log($errorMsg,3,$this->_noticelog);
exit(1);
}
/**
* 如何处理警告错误
*/
public function dealWarning()
{
$errorMsg = <<filename}
产生警告的信息:{$this->message}
产生警告的行号:{$this->line}
EOF;
// return error_log($errorMsg,1,'[email protected]');
return error_log($errorMsg,3,$this->_noticelog);
}
/**
* 如何处理通知错误
*/
public function dealNotice()
{
$datetime = date('Y-m-d H:i:s',time());
$errorMsg = <<filename}
产生通知的信息:{$this->message}
产生通知的行号:{$this->line}
产生通知的时间:{$datetime}
EOF;
return error_log($errorMsg,3,$this->_noticelog);
}
}
3.3 错误处理器测试
require_once 'MyErrorHandler.php';
error_reporting(-1);
//使用MyErrorHandler类直接调用deal方法
/**
* set_error_handler(array(类名/new 类名,方法名));
* set_error_handler(函数名);
*/
set_error_handler(array('MyErrorHandler','deal'));
//通知级别错误
echo $test;
//警告级别错误
settype($var,'king');
//致命错误
//test();
//总结:手动抛出的信息会被显示在浏览器
trigger_error('我是手动抛出的致命错误',E_USER_ERROR);
//自定义错误处理器会继续执行一下代码,而手动抛出的错误信息不会继续执行
echo 'this is a test ';
3.4 register_shutdown_function函数使用
使用场景:
- 页面强制被停止
- 程序代码意外终止或超时
register_shutdown_function()
函数是从内存中调用
的,也就是PHP语句执行完之后(页面已不存在了)再调用这个函数,所以写路径的时候已经脱离这个脚本了,所以file_put_contents()
路径要用绝对路径
error_get_last # 得到最后产生的错误
注意:如果在register_shutdown_function()
之前有die/exit
则不会被执行