開發PHP的朋友都知道,其實最擔心的就是程序中出現一些異常或錯誤,這些狀況如果輸出到用戶的螢幕會把用戶給嚇壞,甚至為此丟了工作,如果不輸出到螢幕就得想辦法記錄到日誌中,但是似乎不是每個人都有查看錯誤日誌的習慣,爲了解決這個尷尬的問題,所以我寫了這段代碼,其用意就是當我們寫的php程式出錯的時候把錯誤內容捕捉出來然後發到我們的email內.
先看效果:
<span>Define</span>('SYS_DEBUG',<span>false</span><span>); </span><span>IF</span><span>(SYS_DEBUG) { </span><span>ini_set</span>('display_errors','on'<span>); </span><span>Error_reporting</span>(<span>E_ALL</span>);<span>//</span><span>上線后使用該設定Error_reporting(E_ERROR | E_WARNING | E_PARSE);</span> }<span>Else</span><span>{ </span><span>ini_set</span>('display_errors','off'<span>); </span><span>Error_reporting</span>(0<span>); } </span><span>//</span><span>錯誤捕捉</span> <span>Register_shutdown_function</span>('Fun::Error'<span>); </span><span>Class</span><span> Fun{ </span><span>/*</span><span>* 通用出錯處理 参数: 要輸出的內容,是否終止執行程序 說明: 有傳值時該函式可以用來輸出自定義的錯誤內容 另外還可以配合Register_shutdown_function實現自動抓取錯誤內容,並將抓取的錯誤內容發送到Email內 Register_shutdown_function的機制是程序執行完畢或中途出錯時調用函數 如果是自動抓取錯誤時被調用,則會取得最後一次出錯的內容,如果發現沒有錯誤內容則跳出 返回: 內容會被直接輸出至螢幕或Email內 用法: Fun::Error('錯誤內容'); Fun::Error('錯誤內容',False); /*</span><span>*/</span> <span>Public</span> <span>Static</span> <span>Function</span> Error(<span>$M</span>='',<span>$E</span>=<span>True</span><span>){ </span><span>$ErrTpl</span>='<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body><table cellspacing="0" cellpadding="0" border="0"><tr><td>; </span><span>$M</span>=<span>Trim</span>(<span>$M</span><span>); </span><span>IF</span>(<span>$M</span>!='') {<span>//</span><span>手工調用</span> <span>$M</span>=' <b>注意:</b> '.<span>$M</span><span>; </span><span>Echo</span> <span>Strtr</span>(<span>$ErrTpl</span>,<span>Array</span>('{$M}'=><span>$M</span>));<span>unSet</span>(<span>$ErrTpl</span><span>); </span><span>IF</span>(<span>$E</span>===<span>True</span>) {<span>Die</span><span>();} </span><span>Return</span><span> ; }</span><span>Else</span>{<span>//</span><span>程式執行完畢自動抓取錯誤時調用</span> <span>$M</span>=error_get_last();<span>//</span><span>取得最後產生的錯誤</span> <span>IF</span>(!<span>Is_array</span>(<span>$M</span>) Or <span>Count</span>(<span>$M</span>)<4) {<span>Unset</span>(<span>$M</span>);<span>Return</span><span> ;} </span><span>IF</span>(!<span>File_Exists</span>(<span>$M</span>['file'])) {<span>Unset</span>(<span>$M</span>);<span>Return</span><span> ;} </span><span>//</span><span>取得5行出錯關鍵代碼,如果取不到內容,說明出錯檔案不存在</span> <span>$E</span>=<span>Array_slice</span>(<span>File</span>(<span>$M</span>['file']),(<span>$M</span>['line']-4),5<span>); </span><span>IF</span>(!<span>Is_array</span>(<span>$E</span>)) {<span>Unset</span>(<span>$M</span>,<span>$E</span>);<span>Return</span><span> ;} </span><span>$E</span>['M']=''<span>; </span><span>For</span>(<span>$i</span>=0;<span>$i</span><5;<span>$i</span>++<span>) { </span><span>$E</span>[<span>$i</span>]=<span>isSet</span>(<span>$E</span>[<span>$i</span>]) ? <span>$E</span>[<span>$i</span>] : ''<span>; </span><span>$E</span>['M'].=' '<span>; </span><span>$E</span>['M'].=(<span>$i</span>==3) ? '<b>'.((<span>$M</span>['line']-3)+(<span>$i</span>+1)).'</b>' : ((<span>$M</span>['line']-3)+(<span>$i</span>+1<span>)); </span><span>$E</span>['M'].=': '.<span>Htmlspecialchars</span>(<span>$E</span>[<span>$i</span>],ENT_QUOTES,'UTF-8').'<br>'<span>; } </span><span>$E</span>=&<span>$E</span>['M'<span>]; </span><span>$M</span>='<b>自動捕捉到有錯誤產生!</b><br><br><b>錯誤描述:</b><br> <b>'.<span>$M</span>['file'].'</b>的第<b>'.<span>$M</span>['line'].'</b>行出現了類型為<b>'.<span>$M</span>['type'].'</b>的錯誤:<br> '.<span>$M</span>['message'].'<br><br><b>關鍵代碼:</b><br>'.<span>$E</span>.'<br>'.self::now('Y-m-d H:i:s',<span>time</span>()).'<br>'<span>; </span><span>$M</span>=<span>Strtr</span>(<span>$ErrTpl</span>,<span>Array</span>('{$M}'=><span>$M</span>));<span>unSet</span>(<span>$ErrTpl</span><span>); </span><span>$G</span>=seft::getG('SYS','config'<span>); </span><span>IF</span>(!self::Mail2(<span>$G</span>['Spe'],'警告: '.<span>$G</span>['Tit'].' 出現 PHP 程式錯誤!',<span>$M</span>) And SYS_DEBUG===<span>True</span><span>){ </span><span>throw</span> <span>new</span> <span>Exception</span>('警告: '.<span>$G</span>['Tit'].' 出現 PHP 程式錯誤!<br><br>'.<span>$M</span><span>); } </span><span>IF</span>(SYS_DEBUG) {<span>Echo</span> <span>$M</span><span>;} </span><span>unSet</span>(<span>$E</span>,<span>$M</span>,<span>$G</span><span>); </span><span>Die</span><span>(); } } </span><span>/*</span><span>* 发送電郵 参数: 收件人,郵件標題(不可有換行符),郵件內容(行與行之間必須用\n分隔,每行不可超過70個字符) 說明: 調用PHP內置函式Mail發送電郵 返回: 返回布爾值 用法: $IsSend=Fun::Mail2($email,$tit,$msg); /*</span><span>*/</span> <span>Public</span> <span>Static</span> <span>Function</span> Mail2(<span>$to</span>,<span>$tit</span>,<span>$msg</span><span>) { </span><span>IF</span>(Filter_var(<span>$to</span>,FILTER_VALIDATE_EMAIL)==''<span>){ </span><span>throw</span> <span>new</span> <span>Exception</span>('電郵地址錯誤!'<span>); } </span><span>$tit</span>='=?UTF-8?B?'.<span>Base64_Encode</span>(<span>$tit</span>).'?='<span>; </span><span>$msg</span> = <span>str_replace</span>("\n.","\n..",<span>$msg</span>); <span>//</span><span>Windows如果在一行开头发现一个句号则会被删掉,要避免此问题将单个句号替换成两个句号</span> <span>Return</span> <span>Mail</span>(<span>$to</span>,<span>$tit</span>,<span>$msg</span>,'From:'.seft::getG('config/SYS/Mal')."\n".'Content-Type:text/html;charset=utf-8'<span>); } }</span>