用PHP即時(shí)捕捉PHP中的錯(cuò)誤并發(fā)送email通知的實(shí)現(xiàn)代碼
更新時(shí)間:2013年01月19日 21:02:05 作者:
這段代碼,其用意就是當(dāng)我們寫的php程式出錯(cuò)的時(shí)候把錯(cuò)誤內(nèi)容捕捉出來然后發(fā)到我們的email內(nèi),方便我們排錯(cuò)
開發(fā)PHP的朋友都知道,其實(shí)最擔(dān)心的就是程序中出現(xiàn)一些異?;蝈e(cuò)誤,這些狀況如果輸出到用戶的螢?zāi)粫延脩艚o嚇壞,甚至為此丟了工作,如果不輸出到螢?zāi)痪偷孟朕k法記錄到日志中,但是似乎不是每個(gè)人都有查看錯(cuò)誤日志的習(xí)慣,爲(wèi)了解決這個(gè)尷尬的問題,所以我寫了這段代碼,其用意就是當(dāng)我們寫的php程式出錯(cuò)的時(shí)候把錯(cuò)誤內(nèi)容捕捉出來然后發(fā)到我們的email內(nèi).
先看效果:

Define('SYS_DEBUG',false);
IF(SYS_DEBUG) {
ini_set('display_errors','on');
Error_reporting(E_ALL);//上線后使用該設(shè)定Error_reporting(E_ERROR | E_WARNING | E_PARSE);
}Else{
ini_set('display_errors','off');
Error_reporting(0);
}
//錯(cuò)誤捕捉
Register_shutdown_function('Fun::Error');
Class Fun{
/**
通用出錯(cuò)處理
參數(shù):
要輸出的內(nèi)容,是否終止執(zhí)行程序
說明:
有傳值時(shí)該函式可以用來輸出自定義的錯(cuò)誤內(nèi)容
另外還可以配合Register_shutdown_function實(shí)現(xiàn)自動(dòng)抓取錯(cuò)誤內(nèi)容,并將抓取的錯(cuò)誤內(nèi)容發(fā)送到Email內(nèi)
Register_shutdown_function的機(jī)制是程序執(zhí)行完畢或中途出錯(cuò)時(shí)調(diào)用函數(shù)
如果是自動(dòng)抓取錯(cuò)誤時(shí)被調(diào)用,則會取得最后一次出錯(cuò)的內(nèi)容,如果發(fā)現(xiàn)沒有錯(cuò)誤內(nèi)容則跳出
返回:
內(nèi)容會被直接輸出至螢?zāi)换駿mail內(nèi)
用法:
Fun::Error('錯(cuò)誤內(nèi)容');
Fun::Error('錯(cuò)誤內(nèi)容',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!='') {//手工調(diào)用
$M=' <b>注意:</b> '.$M;
Echo Strtr($ErrTpl,Array('{$M}'=>$M));unSet($ErrTpl);
IF($E===True) {Die();}
Return ;
}Else{//程式執(zhí)行完畢自動(dòng)抓取錯(cuò)誤時(shí)調(diào)用
$M=error_get_last();//取得最后產(chǎn)生的錯(cuò)誤
IF(!Is_array($M) Or Count($M)<4) {Unset($M);Return ;}
IF(!File_Exists($M['file'])) {Unset($M);Return ;}
//取得5行出錯(cuò)關(guān)鍵代碼,如果取不到內(nèi)容,說明出錯(cuò)檔桉不存在
$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>自動(dòng)捕捉到有錯(cuò)誤產(chǎn)生!</b><br><br><b>錯(cuò)誤描述:</b><br> <b>'.$M['file'].'</b>的第<b>'.$M['line'].'</b>行出現(xiàn)了類型為<b>'.$M['type'].'</b>的錯(cuò)誤:<br> '.$M['message'].'<br><br><b>關(guān)鍵代碼:</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'].' 出現(xiàn) PHP 程式錯(cuò)誤!',$M) And SYS_DEBUG===True){
throw new Exception('警告: '.$G['Tit'].' 出現(xiàn) PHP 程式錯(cuò)誤!<br><br>'.$M);
}
IF(SYS_DEBUG) {Echo $M;}
unSet($E,$M,$G);
Die();
}
}
/**
發(fā)送電郵
參數(shù):
收件人,郵件標(biāo)題(不可有換行符),郵件內(nèi)容(行與行之間必須用\n分隔,每行不可超過70個(gè)字符)
說明:
調(diào)用PHP內(nèi)置函式Mail發(fā)送電郵
返回:
返回布爾值
用法:
$IsSend=Fun::Mail2($email,$tit,$msg);
/**/
Public Static Function Mail2($to,$tit,$msg) {
IF(Filter_var($to,FILTER_VALIDATE_EMAIL)==''){
throw new Exception('電郵地址錯(cuò)誤!');
}
$tit='=?UTF-8?B?'.Base64_Encode($tit).'?=';
$msg = str_replace("\n.","\n..",$msg); //Windows如果在一行開頭發(fā)現(xiàn)一個(gè)句號則會被刪掉,要避免此問題將單個(gè)句號替換成兩個(gè)句號
Return Mail($to,$tit,$msg,'From:'.seft::getG('config/SYS/Mal')."\n".'Content-Type:text/html;charset=utf-8');
}
}
先看效果:

復(fù)制代碼 代碼如下:
Define('SYS_DEBUG',false);
IF(SYS_DEBUG) {
ini_set('display_errors','on');
Error_reporting(E_ALL);//上線后使用該設(shè)定Error_reporting(E_ERROR | E_WARNING | E_PARSE);
}Else{
ini_set('display_errors','off');
Error_reporting(0);
}
//錯(cuò)誤捕捉
Register_shutdown_function('Fun::Error');
Class Fun{
/**
通用出錯(cuò)處理
參數(shù):
要輸出的內(nèi)容,是否終止執(zhí)行程序
說明:
有傳值時(shí)該函式可以用來輸出自定義的錯(cuò)誤內(nèi)容
另外還可以配合Register_shutdown_function實(shí)現(xiàn)自動(dòng)抓取錯(cuò)誤內(nèi)容,并將抓取的錯(cuò)誤內(nèi)容發(fā)送到Email內(nèi)
Register_shutdown_function的機(jī)制是程序執(zhí)行完畢或中途出錯(cuò)時(shí)調(diào)用函數(shù)
如果是自動(dòng)抓取錯(cuò)誤時(shí)被調(diào)用,則會取得最后一次出錯(cuò)的內(nèi)容,如果發(fā)現(xiàn)沒有錯(cuò)誤內(nèi)容則跳出
返回:
內(nèi)容會被直接輸出至螢?zāi)换駿mail內(nèi)
用法:
Fun::Error('錯(cuò)誤內(nèi)容');
Fun::Error('錯(cuò)誤內(nèi)容',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!='') {//手工調(diào)用
$M=' <b>注意:</b> '.$M;
Echo Strtr($ErrTpl,Array('{$M}'=>$M));unSet($ErrTpl);
IF($E===True) {Die();}
Return ;
}Else{//程式執(zhí)行完畢自動(dòng)抓取錯(cuò)誤時(shí)調(diào)用
$M=error_get_last();//取得最后產(chǎn)生的錯(cuò)誤
IF(!Is_array($M) Or Count($M)<4) {Unset($M);Return ;}
IF(!File_Exists($M['file'])) {Unset($M);Return ;}
//取得5行出錯(cuò)關(guān)鍵代碼,如果取不到內(nèi)容,說明出錯(cuò)檔桉不存在
$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>自動(dòng)捕捉到有錯(cuò)誤產(chǎn)生!</b><br><br><b>錯(cuò)誤描述:</b><br> <b>'.$M['file'].'</b>的第<b>'.$M['line'].'</b>行出現(xiàn)了類型為<b>'.$M['type'].'</b>的錯(cuò)誤:<br> '.$M['message'].'<br><br><b>關(guān)鍵代碼:</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'].' 出現(xiàn) PHP 程式錯(cuò)誤!',$M) And SYS_DEBUG===True){
throw new Exception('警告: '.$G['Tit'].' 出現(xiàn) PHP 程式錯(cuò)誤!<br><br>'.$M);
}
IF(SYS_DEBUG) {Echo $M;}
unSet($E,$M,$G);
Die();
}
}
/**
發(fā)送電郵
參數(shù):
收件人,郵件標(biāo)題(不可有換行符),郵件內(nèi)容(行與行之間必須用\n分隔,每行不可超過70個(gè)字符)
說明:
調(diào)用PHP內(nèi)置函式Mail發(fā)送電郵
返回:
返回布爾值
用法:
$IsSend=Fun::Mail2($email,$tit,$msg);
/**/
Public Static Function Mail2($to,$tit,$msg) {
IF(Filter_var($to,FILTER_VALIDATE_EMAIL)==''){
throw new Exception('電郵地址錯(cuò)誤!');
}
$tit='=?UTF-8?B?'.Base64_Encode($tit).'?=';
$msg = str_replace("\n.","\n..",$msg); //Windows如果在一行開頭發(fā)現(xiàn)一個(gè)句號則會被刪掉,要避免此問題將單個(gè)句號替換成兩個(gè)句號
Return Mail($to,$tit,$msg,'From:'.seft::getG('config/SYS/Mal')."\n".'Content-Type:text/html;charset=utf-8');
}
}
相關(guān)文章
PHP中empty,isset,is_null用法和區(qū)別
最近在閱讀項(xiàng)目的源碼,發(fā)現(xiàn)源碼中就對empty、isset和is_null函數(shù)(語言特性)亂用,有的地方很明顯的就挖坑了。不能正確的去理解這些東西,就很可能給后續(xù)的開發(fā)挖坑了。2017-02-02
PHP調(diào)用MySQL的存儲過程的實(shí)現(xiàn)代碼
MySQL好像從5.0開始才引入存儲過程,反正以前做應(yīng)用的時(shí)候從沒碰過,不過現(xiàn)在因?yàn)橹饕鲀?nèi)部系統(tǒng)2008-08-08
PHP實(shí)現(xiàn)逐行刪除文件右側(cè)空格的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)逐行刪除文件右側(cè)空格的方法,涉及php針對文件的打開、逐行讀取、rtrim函數(shù)刪除右側(cè)空格及文件保存等技巧,需要的朋友可以參考下2015-12-12
Thinkphp3.2.3整合phpqrcode生成帶logo的二維碼
這篇文章主要為大家詳細(xì)介紹了Thinkphp3.2.3整合phpqrcode生成帶logo的二維碼的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下2016-07-07
PHP函數(shù)實(shí)現(xiàn)分頁含文本分頁和數(shù)字分頁
分頁功能是經(jīng)常使用的一個(gè)功能,因此用PHP實(shí)現(xiàn)分頁,文本分頁和數(shù)字分頁,對其以函數(shù)形式進(jìn)行了封裝2014-10-10

