欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

用PHP即时捕捉PHP中的错误并发送email通知的实现代码

程序员文章站 2023-01-05 22:06:49
开发php的朋友都知道,其实最担心的就是程序中出现一些异常或错误,这些状况如果输出到用户的萤幕会把用户给吓坏,甚至为此丢了工作,如果不输出到萤幕就得想办法记录到日志中,但是...
开发php的朋友都知道,其实最担心的就是程序中出现一些异常或错误,这些状况如果输出到用户的萤幕会把用户给吓坏,甚至为此丢了工作,如果不输出到萤幕就得想办法记录到日志中,但是似乎不是每个人都有查看错误日志的习惯,爲了解决这个尴尬的问题,所以我写了这段代码,其用意就是当我们写的php程式出错的时候把错误内容捕捉出来然后发到我们的email内.

先看效果:
用PHP即时捕捉PHP中的错误并发送email通知的实现代码

复制代码 代码如下:

define('sys_debug',false);
if(sys_debug) {
ini_set('display_errors','on');
error_reporting(e_all);//上线后使用该设定error_reporting(e_error | e_warning | e_parse);
}else{
ini_set('display_errors','off');
error_reporting(0);
}

//错误捕捉
register_shutdown_function('fun::error');

class fun{

/**
通用出错处理
参数:
要输出的内容,是否终止执行程序
说明:
有传值时该函式可以用来输出自定义的错误内容
另外还可以配合register_shutdown_function实现自动抓取错误内容,并将抓取的错误内容发送到email内
register_shutdown_function的机制是程序执行完毕或中途出错时调用函数
如果是自动抓取错误时被调用,则会取得最后一次出错的内容,如果发现没有错误内容则跳出
返回:
内容会被直接输出至萤幕或email内
用法:
fun::error('错误内容');
fun::error('错误内容',false);
/**/
public static function error($m='',$e=true){
$errtpl='<head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body><table cellspacing="0" cellpadding="0" border="0"><tr><td style="padding:5px;background-color:#f57900;font-size:13px;border:1px solid #444;color:#222;">{$m}</td></tr></table>';

$m=trim($m);
if($m!='') {//手工调用
$m=' <b>注意:</b> '.$m;
echo strtr($errtpl,array('{$m}'=>$m));unset($errtpl);
if($e===true) {die();}
return ;
}else{//程式执行完毕自动抓取错误时调用
$m=error_get_last();//取得最后产生的错误
if(!is_array($m) or count($m)<4) {unset($m);return ;}
if(!file_exists($m['file'])) {unset($m);return ;}

//取得5行出错关键代码,如果取不到内容,说明出错档桉不存在
$e=array_slice(file($m['file']),($m['line']-4),5);
if(!is_array($e)) {unset($m,$e);return ;}

$e['m']='';
for($i=0;$i<5;$i++) {
$e[$i]=isset($e[$i]) ? $e[$i] : '';
$e['m'].='  ';
$e['m'].=($i==3) ? '<b>'.(($m['line']-3)+($i+1)).'</b>' : (($m['line']-3)+($i+1));
$e['m'].=': '.htmlspecialchars($e[$i],ent_quotes,'utf-8').'<br>';
}
$e=&$e['m'];

$m='<b>自动捕捉到有错误产生!</b><br><br><b>错误描述:</b><br>  <b>'.$m['file'].'</b>的第<b>'.$m['line'].'</b>行出现了类型为<b>'.$m['type'].'</b>的错误:<br>  '.$m['message'].'<br><br><b>关键代码:</b><br>'.$e.'<br>'.self::now('y-m-d h:i:s',time()).'<br>';

$m=strtr($errtpl,array('{$m}'=>$m));unset($errtpl);

$g=seft::getg('sys','config');
if(!self::mail2($g['spe'],'警告: '.$g['tit'].' 出现 php 程式错误!',$m) and sys_debug===true){
throw new exception('警告: '.$g['tit'].' 出现 php 程式错误!<br><br>'.$m);
}
if(sys_debug) {echo $m;}
unset($e,$m,$g);
die();
}
}
/**
发送电邮
参数:
收件人,邮件标题(不可有换行符),邮件内容(行与行之间必须用\n分隔,每行不可超过70个字符)
说明:
调用php内置函式mail发送电邮
返回:
返回布尔值
用法:
$issend=fun::mail2($email,$tit,$msg);
/**/
public static function mail2($to,$tit,$msg) {
if(filter_var($to,filter_validate_email)==''){
throw new exception('电邮地址错误!');
}

$tit='=?utf-8?b?'.base64_encode($tit).'?=';
$msg = str_replace("\n.","\n..",$msg); //windows如果在一行开头发现一个句号则会被删掉,要避免此问题将单个句号替换成两个句号

return mail($to,$tit,$msg,'from:'.seft::getg('config/sys/mal')."\n".'content-type:text/html;charset=utf-8');
}
}