PHP7錯誤和異常處理實例分享

小云云
發布: 2023-03-21 09:24:02
原創
2428 人瀏覽過

錯誤和異常的異同

"錯誤"和"異常"的概念十分相似,很容易混淆,"錯誤"和"異常"都表明了項目出了問題,都會提供相關的信息,並且都有錯誤類型。然而,"異常機制"是在"錯誤機制"後才出現的,"異常"是避免"錯誤"的不足。比較重要的一點就是因為"錯誤"的資訊不豐富,我們見過最多的函數說明就是: 成功時候返回***, 錯誤的時候返回FALSE, 然而一個函數出錯的原因可能有多種, 出錯的種類更有多種. 一個簡單的FALSE, 並不能把具體的錯誤訊息告訴呼叫者.

PHP中將程式碼自身異常(一般是環境或語法非法所致)成為錯誤,將運行中出現的邏輯錯誤稱為異常(Exception)錯誤是沒法通過程式碼處理的,而異常則可以透過try/catch處理.

異常

異常是Exception類別的對象,在遇到無法修復的狀況時拋出,出現問題時,異常用於主動出擊,委託職責,異常還可用於防守,預測潛在的問題,減輕其影響。

Exception物件有兩個主要的屬性:一個是訊息,另一個是數字程式碼。我們分別可以用getCode()和getMessage()來取得這兩個屬性。如下:

<?php 
$exception = new Exception("figthing!!!",100);
$code = $exception->getCode();//100
$message = $exception->getMessage();//fight.....
登入後複製

拋出例外

當一個例外被拋出後程式碼會立即停止執行,其後的程式碼將不會繼續執行,PHP 會嘗試尋找符合的"catch"代碼塊。如果一個異常沒有被捕獲,而且又沒用使用set_exception_handler()作相應的處理的話,那麼 PHP 將會產生一個嚴重的錯誤,並且輸出未能捕獲異常(Uncaught Exception ...)的提示信息。

throw new Exception("this is a exception");//使用throw抛出异常
登入後複製

捕獲異常

我們應該捕獲拋出的異常並且使用優雅的方式處理。攔截並處理異常的方式是,把可能拋出異常的程式碼放到try/catch區塊中。並且如果使用多個catch攔截多個異常的時候,只會運行其中一個,如果PHP沒有找到合適的catch塊,異常會向上冒泡,直到PHP腳本由於致命錯誤而終止運行。如下:

try {
	throw new Exception("Error Processing Request");
	$pdo = new PDO("mysql://host=wrong_host;dbname=wrong_name");
} catch (PDOException $e) {
	echo "pdo error!";
} catch(Exception $e){
	echo "exception!";
}finally{
    echo "end!";//finally是在捕获到任何类型的异常后都会运行的一段代码
}
登入後複製
运行结果:exception!end!
登入後複製

異常處理程序

那麼我們應該如何捕捉每個可能拋出的例外呢? PHP允許我們註冊一個全域異常處理程序,捕獲所有未被捕獲的異常。異常處理程序使用set_exception_handler()函式註冊(這裡使用匿名函式)。

set_exception_handler(function (Exception $e)
{
	echo "我自己定义的异常处理".$e->getMessage();
});
throw new Exception("this is a exception");
//运行结果:我自己定义的异常处理this is a exception
登入後複製

錯誤

除了異常之外,PHP還提供了用於報告錯誤的函數。 PHP能觸發不同類型的錯誤,例如致命錯誤、執行階段錯誤、編譯時錯誤、啟動錯誤、使用者觸發的錯誤。可以在php.ini中設定錯誤報告方式(這裡不做多的解釋)

下面列舉一些錯誤報告層級:

值          常量                     说明1           E_ERROR             报告导致脚本终止运行的致命错误2   
        E_WARNING           报告运行时的警告类错误(脚本不会终止运行)4           E_PARSE        
             报告编译时的语法解析错误8           E_NOTICE            报告通知类错误,脚本可能会产生错误32767 
                  E_ALL               报告所有的可能出现的错误(不同的PHP版本,常量E_ALL的值也可能不同)
登入後複製

無論如何都必須遵守以下幾條規則:

  • 一定要讓PHP報告錯誤

  • 在開發環境中要顯示錯誤

  • 在生產環境中不能顯示錯誤

  • 在開發環境與生產環境中都要記錄錯誤

錯誤處理程序

與異常處理程序一樣,我們也可以使用set_error_handler()註冊全域錯誤處理程序,使用自己的邏輯方式攔截並處理PHP錯誤。我們要在錯誤處理程序中呼叫die()或exit()函數。如果不調用,PHP腳本會從出錯的地方繼續向下執行。如下:

set_error_handler(function ($errno,$errstr,$errfile,$errline)//常用的四个参数
{
	echo "错误等级:".$errno."<br>错误信息:".$errstr."<br>错误的文件名:".$errfile."<br>错误的行号:".$errline;
	exit();
});
trigger_error("this is a error");//自行触发的错误
echo &#39;正常&#39;;
登入後複製

運行結果:
錯誤等級:1024
錯誤訊息:this is a error
錯誤的檔案名稱:/Users/toby/Desktop/www/Exception.php
錯誤的行號:33

相關的還有一個函數register_shutdown_function()---是一個會在php中止時執行的函數。 (有興趣的可以自行查詢一下)

錯誤轉換為異常

我們可以把PHP錯誤轉換為異常(並不是所有的錯誤都可以轉換,只能轉換php.ini文件中error_reporting指令設定的錯誤),使用處理異常的現有流程處理錯誤。這裡我們使用set_error_handler()函數將錯誤訊息託管至ErrorException(它是Exception的子類別),進而交給現有的例外系統處理。如下:

set_exception_handler(function (Exception $e)
{
	echo "我自己定义的异常处理".$e->getMessage();
});
set_error_handler(function ($errno, $errstr, $errfile, $errline )
{
	throw new ErrorException($errstr, 0, $errno, $errfile, $errline);//转换为异常
});
trigger_error("this is a error");//自行触发错误
登入後複製

運行結果:我自己定義的例外處理this is a error

PHP7的錯誤異常處理

PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。

这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获。如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。

Error 类并非继承自 Exception 类,所以不能用 catch (Exception $e) { ... } 来捕获 Error。你可以用 catch (Error $e) { ... },或者通过注册异常处理函数( set_exception_handler())来捕获 Error。

$a=1;
try {
$a->abc();//未定义此对象
} catch (Exception $e) {
	echo "error";
} catch (Error $e) {
	echo $e->getCode();
}
登入後複製

运行结果:0

PHP7 中出现了 Throwable 接口,该接口由 Error 和 Exception 实现,用户不能直接实现 Throwable 接口,而只能通过继承 Exception 来实现接口

try {
// Code that may throw an Exception or Error.
} catch (Throwable $t) {
// Executed only in PHP 7, will not match in PHP 5.x
} catch (Exception $e) {
// Executed only in PHP 5.x, will not be reached in PHP 7
}
登入後複製

注意实际项目中,在开发环境中我们可以使用Whoops组件,在生产环境中我们可以使用Monolog组件。

相关推荐:

PHP错误处理方法实例

php错误处理和日志记录

PHP异常处理和错误处理方法分享

以上是PHP7錯誤和異常處理實例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!