這一章節要介紹的是 Exception
會接續前一章節繼續作更詳細的補充!
而這一章節主要要介紹的是:
- try catch (會作更詳細的介紹)
- set_exception_handler (自定義錯誤處理方式)
- 自定義 Exception 類別
1. try catch
這邊會接續前一章節繼續介紹 try catch
首先在 catch 區塊的部分
裡面可以接的類型僅有 Exceptions 類別或是繼承 Exceptions 的子類別
如下所示
1 | try{ |
另外昨天有提過
可以使用多個 catch 去抓取不同的異常類型
但是!!!
如果今天有兩種不同的異常類型都想要使用同樣的對應方法的話
就可以使用 | 這個符號,去區隔多種異常類型
1 | class CommonException extends Exception{ |
2. set_exception_handler
第二小節要接續第一小節的部分
這一部分要介紹自定義異常處理
前面曾經提過
如果在 catch 的區塊沒有成功抓取到異常的話
會產生 Uncaught Exception 的錯誤訊息導致程式碼中斷
這時候除了更換抓取的異常類型之外,可以使用自定義錯誤訊息的方式來處理
換句話來說
使用 try catch 的話,catch 區塊可以捕捉在 try 區塊內所發生的對應的異常類型
而使用 set_exception_handler 則可以捕捉不在 try 區塊內所發生的異常類型
但是!!!
set_exception_handler 僅僅只是捕捉異常並按照自定義的去處理而已
它無法阻止程式碼的中斷
請參考下面的範例來加深理解吧~
1 | function exception_handler($exception) { |
你會發現在異常發生的下一行字串並沒有被印出來
在正常不使用 set_exception_handler 的情況下
若有異常發生的時候,會造成錯誤代碼 500 的無法顯示網頁
而使用 set_exception_handler 僅只是避免發生錯誤代碼 500 的異常網頁而已
並不能夠阻止網頁的中斷
因此在這種情況或是需要 debug 的時候,仍然會建議使用 try catch 會比較恰當喔~
set_exception_handler vs set_error_handler
這邊要額外整理一下…
關於前一章節提過的 set_error_handler 和這章提到的 set_exception_handler 有什麼差異~
1. 處理問題的類型
前一章節提到的 set_error_handler 主要是針對使用者在操作時候產生的非中斷錯誤
而本章提到的 set_exception_handler 是針對沒有被 catch 到的異常 (會使程式碼中斷)
在文字敘述上
我們以錯誤 (非中斷) 和 異常 (會中斷) 來區分兩者的差異
2. 測試使用的對應函式
當我們想要測試 set_error_handler 是否正常被呼叫時,我們可以使用 trigger_error 來幫助我們進行測試
而若要測試 set_exception_handler 的時候,則可以使用 throw new Exception .. 來幫助我們測試呼叫的結果
3. PHP 版本之間的小調整
針對 PHP 5 和 PHP 7 之間有一些小調整
不過大致上來說, set_error_handler 和 set_exception_handler 的功用都和上述說明的是相同的
唯一的調整在於 Fatal Error (會使得程式碼終止的致命性錯誤) 的部分
在 PHP 5 的版本中,只要發生 Fatal Error,就會將錯誤訊息顯示在畫面上,不會被任一 handler 管理
而到了 PHP 7 之後,Fatal Error 也可以被 set_exception_handler 給捕捉,所以可以使用 set_exception_handler 去避免將 Fatal Error 錯誤訊息顯示在畫面上的弊端
3. 自定義 Exception 類別
在一般使用 try catch 去抓取異常類型的時候
我們通常會使用 Exception 這個類別,因為它可以抓取所有可能產生的異常類型
換句話說,Exception 就是異常類型的基底類別,是 PHP 本來就預設存在的類別
也因此當我們想要自定義一個異常類別的時候,需要先繼承 Exception 這個類別
詳細的 Exception 類別在官方的文件中有正式的介紹
因此這邊就不再列出完整的 Exception 類別了~
底下會比較偏向如何繼承 Exception 去實做一個客製化的異常類別為主!
首先在官方的文件中有提到
在自定義 Exception 類別的時候,若有改寫建構元的時候,建議呼叫父類別的建構元,也就是 parent::__construct()
用來確保在 Exception 類別中的所有成員變數都有被賦值了
另外要注意!!!
在改寫建構元的時候,必需要傳入 Exception 類別建構元的所有參數
按照順序分別是
- $message: 異常的訊息
- $code: 自定義的錯誤代碼
- Exception $previous: 適用於巢狀異常 (也就是雙重的 try catch~),代表前一個異常類型
1 | class MyException extends Exception |
而我們也可以自定義錯誤訊息
只需要改寫 toString 方法即可
在前面的章節曾經提過,當類別被當成字串呼叫的情況下就會觸發 toString 這個魔術方法
如果使用 try catch 抓到自定義異常類別的時候,就會將我們自定的錯誤訊息顯示於畫面上
1 | class MyException extends Exception |
這樣就完成一個簡單的自定義錯誤類型了~
當然也可以作更多的客製化方法去處理異常的問題~