錯誤
錯誤是寫程式中不可避免的,如何去發現定位錯誤及改正更是一門學問。今天跟大家聊聊php7之後的錯誤與異常。
錯誤的分類
一般錯誤分為語法錯誤、執行階段錯誤、邏輯錯誤。語法以及運行時錯誤很容易去排查,但邏輯錯誤就不是那麼簡單的了。鄙人在判斷的時候也有多次將比較運算==寫成了賦值運算=,像我這種就很難去發現。一般隨著經驗的豐富(踩坑踩多了),會越來越容易找到邏輯錯誤。
控制錯誤的輸出
一般建議開發階段開啟錯誤輸出方便及時發現錯誤,上線階段為了安全性及美觀建議關閉錯誤輸出。
php提供了一個參數display_errors用來控制錯誤向瀏覽器、cli的輸出。有兩種方式可以來修改它,透過修改php.ini檔案或使用ini_set函數來設定。下面展示使用ini_set來設定屏蔽錯誤輸出的程式碼。
<?php ini_set('display_errors', 0); echo $a; echo 0; date(); echo 1;
該程式會正常輸出01,但不會輸出錯誤訊息。
錯誤報告等級
一般分為4大類
parse語法錯誤
error致命錯誤
warning警告等級錯誤
notice注意等級錯誤
在php.ini設定檔中,有選項error_reporting,該選項用來控制輸出何種等級的錯誤。常見的有E_ALL、E_WARNING、E_NOTICE。
可以透過函數error_reporting()來動態控制錯誤等級的輸出。
# 输出所有级别错误 error_reporting(E_ALL); # 输出所有级别除了E_NOTICE error_reporting(E_ALL & ~E_NOTICE); # 输出所有级别除了E_NOTICE和E_WARNING error_reporting(E_ALL & ~(E_NOTICE | E_WARNING));
display_errors與error_reporting的區別
display_errors是用來控制錯誤是否輸出,而error_reporting是用來控制輸出何種等級的錯誤。通常他們會搭配使用
ini_set('display_errors', 0); // 关闭错误输出 error_reporting(E_ALL); // 输出所有级别的错误信息
上面的配置一般是上線階段,屏蔽所有的錯誤輸出,但是記錄錯誤到php的錯誤日誌裡。錯誤日誌的路徑是由選項error_log 決定的。
如果設定error_reporting為0值,則不輸出錯誤也不記錄錯誤日誌。
錯誤對於程式的影響
#當程式有語法錯誤時,程式是不會執行的。當有error層級的錯誤時,程式就會停止向下執行。 notice、及warning等級錯誤時不會影響程式的向下執行的。
error_reporting(E_ALL); // 输出所有级别的错误信息 echo $a; echo 0; date(); echo 1; new a; echo 2;
程式會輸出0和1,但不會輸出2。
使用者自訂錯誤
trigger_error()函數可以生產一個使用者層級的錯誤。錯誤級別有E_USER_ERROR 、E_USER_WARNING、E_USER_NOTICE 等
<?php trigger_error('这是notice级别错误', E_USER_NOTICE); trigger_error('warning错误', E_USER_WARNING); trigger_error('deprecated', E_USER_DEPRECATED); trigger_error('error错误', E_USER_ERROR);
自定義錯誤處理
set_error_handler — 設置用戶自定義的錯誤處理函數,該函數原型如下:
set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] ) : mixed
該函數首個參數是一個回呼函數,原型如下:
handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] ) : bool
error 錯誤等級
errstr 錯誤訊息
#errfile 發送錯誤的檔案
errline 錯誤出現的行號
以下層級的錯誤不能由使用者定義的函數來處理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,且大多數在set_error_handler() 位置所產生的函數所產生的函數。
<?php define('DEBUG', false); set_error_handler('error_handler'); if (DEBUG) { ini_set('display_errors', 'On'); } else { ini_set('display_errors', 'Off'); } function error_handler($errLevel, $errInfo, $errFile, $errLine) { echo "ErrorLevel:$errLevel: $errInfo In $errFile ON $errLine" . PHP_EOL; } echo $a;
異常
#异常和错误时有区别的,错误一般是指我们能控制的问题,比如变量名写错了,或者判断条件写的不错,导致死循环。而异常通常指那些难以控制的、意料外的错误,比如mysql连接不上,文件句柄打开失败等情况。
php的异常也是经典的try catch finally,但和一般的异常处理不一样的是,绝大部分的异常需要自行抛出。抛出异常使用throw关键字完成。php也支持捕获多个异常。
<?php class MyError extends Exception { public function printErr () { echo '出错啦'.PHP_EOL; } } class YourError extends Exception { public function printErr () { echo 'errors'.PHP_EOL; } } try { if (mt_rand(0,1)) { throw new MyError('错误'); } else { throw new YourError('错误'); } } catch (MyError $e) { $e->printErr(); } catch (YourError $e) { $e->printErr(); } finally { echo '不管有没有异常,我都会被执行'.PHP_EOL; }
php的异常如果没有捕获,则会报Fatal Error错误,程序不会继续向下执行。
PHP 7 错误处理
PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。 Error 和 Exception 都实现了 Throwable 接口
异常处理
设置默认的异常处理程序,有try/catch捕获的话这个异常函数就不会执行,反之就会执行异常处理函数,而且执行的话,脚本将不会继续执行。
php使用set_exception_handler来设置用户自定义的异常处理函数 ,函数原型如下:
set_exception_handler ( callable $exception_handler ) : callable
回调函数的原型如下:
handler ( Throwable $ex ) : void
下面,我们来写一个异常处理函数
<?php class MyError extends Exception { public function printErr () { echo '出错啦'.PHP_EOL; } } class YourError extends Exception { public function printErr () { echo 'errors'.PHP_EOL; } } try { if (mt_rand(0,1)) { throw new MyError('错误'); } else { throw new YourError('错误'); } } catch (MyError $e) { $e->printErr(); } catch (YourError $e) { $e->printErr(); } finally { echo '不管有没有异常,我都会被执行'.PHP_EOL; }
统一处理错误与异常
学完了错误与异常,知道如何去使用自定义错误处理和异常处理,现在我们就可以统一处理错误与异常了。
<?php class Errors { // 处理非致命错误 static function errorHandle($errLevel, $errInfo, $errFile, $errLine) { echo '错误:'.PHP_EOL; print_r(['file' => $errFile, 'level' => $errLevel, 'line' => $errLine, 'info' => $errInfo]); } // 处理致命错误及异常 static function exceptionHandle(Throwable $ex) { echo '异常:'.PHP_EOL; print_r(['file' => $ex->getFile(), 'level' => $ex->getCode(), 'line' => $ex->getLine(), 'info' => $ex->getMessage()]); } } set_error_handler(['Errors', 'errorHandle']); set_exception_handler(['Errors', 'exceptionHandle']);
以上是php7的錯誤與異常處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!