首頁 後端開發 php教程 PHP主|例外

PHP主|例外

Feb 25, 2025 am 08:30 AM

PHP Master | Exceptional Exceptions

核心要點

  • PHP 異常是一種特殊的類,可以拋出和捕獲,表示意外事件。與不可恢復的錯誤不同,異常旨在由調用代碼處理,並沿執行鏈向上冒泡,直到被捕獲。
  • PHP 錯誤和異常的區別在於:錯誤是不可恢復的,發生在主執行循環中,表示代碼或環境穩定性存在問題;而異常是可恢復的,可能發生在主執行循環之外,並且不表示系統不穩定。
  • 不是所有非成功的情況都需要拋出異常。只有在確實無法繼續執行時才應拋出異常。這意味著一個不屬於普通操作或標準的動作,一個異常,與正常和預期情況有所偏差。
  • 拋出一般的 Exception 等同於說存在“問題”,而代碼無法知道發生了什麼。相反,應始終拋出自定義異常,以告知調用代碼當前情況,從而對發生的情況進行細粒度控制。
  • 全局捕獲塊是最高級別的捕獲塊,必須捕獲所有冒泡到該級別的異常。它應該是生產代碼中唯一的一般異常處理程序。其他處理程序必須是特定的,並且僅限於它知道如何處理和負責的異常。

PHP 5 引入了異常處理機制,這是一種特殊的類,可以拋出和捕獲(與引發的錯誤相反),表示意外事件。與錯誤不同,異常旨在由調用代碼處理,並沿執行鏈向上冒泡,直到被捕獲。一旦拋出異常,當前作用域中的代碼將停止執行(因此,throw 語句之後的任何行都不會執行),控制權將返回到第一個匹配的異常處理程序(捕獲塊、配置的異常處理程序或語言提供的異常處理程序)。只有當異常被捕獲時,代碼執行才會從那裡繼續。本文並非旨在從入門級別講解異常,而是就如何更好地使用異常提供一些建議。如果您以前從未使用過異常,您可能需要查閱PHP 手冊,或閱讀我的朋友們編寫的《PHP Master:編寫尖端代碼》一書,該書出色地講解了編寫現代、合理的PHP 代碼所需的一切知識。

錯誤並非異常

您可能已經了解了異常,但您可能想知道 PHP 錯誤和(自定義)異常之間的區別。邏輯實際上很簡單:錯誤是不可恢復的,發生在主執行循環中,並且表示環境的穩定性。例如,如果您嘗試將標量值作為數組訪問而引發了 E_NOTICE,則表示您的代碼存在問題。無法保證繼續執行是安全的。無法在執行期間糾正該條件。如果由於解析器發現意外的 T_IF 而引發了 E_PARSE,那麼您就會明白這如何影響事物的穩定性。另一方面,異常是可恢復的,可以(並且通常會)發生在主執行循環之外,並且不會指示系統的穩定性。它是一個組件說:“我無法使用給定的輸入完成您的請求,因此您可以隨意處理該信息。”如果庫拋出LengthException,則表示傳遞的值過長或過短,因此它無法使用當前值完成給定的指令。這並不意味著您的環境不穩定,只是意味著您的代碼必須通過填充或截斷來調整值的長度。您的代碼可以捕獲此異常,更新值,然後重試。

並非所有異常都是例外情況

這是最難回答的問題之一:究竟什麼情況需要拋出異常?當然,您的異常必須符合上一段中的三個規則。當遇到損壞的內存時拋出異常是非常糟糕的做法。您的代碼應該改為引發錯誤,以便 PHP 能夠盡快中止,因為事實證明,環境不安全以繼續執行。但是,即使錯誤是不必要的,也不是所有非成功的情況都需要異常。也就是說:並非所有不成功的情況都是例外情況。 “異常”這個詞指的是不屬於普通操作或標準的動作,一個異常,與正常和預期情況有所偏差。一位前同事曾經在晚餐時告訴我他們公司使用的 XML/RPC 服務的設計情況,該服務是所有面向公眾的操作的支柱。架構師隨後了解了異常以及它們在指示非成功狀態方面的便利性。該支柱除了其他功能外,還提供了單點登錄功能。 Web 應用程序不會直接訪問數據庫,而是查詢 XML/RPC 服務,然後該服務將根據為所有 Web 應用程序提供服務的集中式數據存儲進行回复。當提供有效的憑據時,將返回成功狀態。當出現問題時,將拋出異常,並顯示一條消息,指示失敗的原因。易於捕獲,您可以以醒目的、閃亮的錯誤消息向用戶顯示該消息。但是,用戶提供不正確的用戶名和/或密碼真的偏離了預期嗎?在我的項目中,我處理的用戶並不完美,他們會打錯字或忘記事情。獲取不正確的憑據是非常常見的,甚至比有效的憑據更常見。驗證憑據是登錄系統的預期行為,因此在這種情況下,XML/RPC 服務應返回一個狀態,指示驗證的成功與否。儘管憑據未通過,但驗證過程本身仍然成功執行。如果驗證過程未正確執行,則說明還有其他問題。也許數據存儲不可訪問,或者其他什麼原因。登錄系統無法連接到其數據存儲的情況非常不常見,因為它無法在沒有數據存儲的情況下運行。因此,這需要拋出異常。注意:有些人可能會爭辯說,登錄系統無法連接到數據存儲是環境不穩定的標誌,因此應該引發錯誤。但是,登錄系統不負責為數據存儲引發錯誤。相反,如果數據存儲連接器/包裝器認為有必要,則應引發錯誤。一般來說,您可以將異常視為開發人員必須介入、查看情況並進行處理的情況。發生異常場景的代碼本身無法做到這一點。這可能是開發人員已經查看過代碼,並且他們處理它的方式是在它發生時讓它發生。不要開始將所有異常都通過郵件發送給網絡運營中心;他們不會感激的!處理您可以並且應該處理的內容,並且只有在確實無法繼續執行時才拋出異常。

“問題”

幾年前,當我徒步旅行穿過歐洲時,我在希臘的一個火車站偶然發現了一個令人難忘的景象。其中一個儲物櫃區域看起來像炸彈爆炸了一樣,門散落在地上,一半掛在鉸鏈上,或者被砸碎了。我後來了解到他們正在拆除儲物櫃區域,但值得注意的是,他們是如何向客戶傳達此區域已停用的。在中央部分貼了很多膠帶,上面貼著一張紙,上面寫著“問題”兩個字。從技術上講,這是完全正確的。儲物櫃顯然出了問題,並且情況已通過向客戶傳達來處理。您可能會覺得它很有趣,但實際上您在代碼中經常會看到這種情況。如果您只拋出 Exception,那麼您基本上就是在說“問題”,而代碼無法知道發生了什麼。雖然 Exception 是每個異常的基類,但您可以使用您自己的類型擴展它。在 SPL 庫中可以找到更廣泛的異常集合,但這遠非極限。查看 Zend Framework 或 Symfony 等主要的 PHP 框架,您會發現它們幾乎為每種不同的情況都使用自定義異常。編寫所有這些文件以便可以動態加載它們並維護所有不同類型有點麻煩,但這為框架和該框架的使用者提供了對發生情況的細粒度控制。如果只拋出 Exception,那麼您只能確定某些事情不對勁,您不妨放棄。這意味著您使用異常的方式就像它們是錯誤一樣,將捕獲塊用作靜默操作符,並且只是放棄了有人可以以某種方式糾正這種情況的希望。

全局捕獲

如果使用非自定義異常和捕獲所有可能的異常是一個壞主意,那麼為什麼語言甚至允許這樣做呢?始終使用和捕獲特定異常的規則有一個例外,那就是全局捕獲規則。全局捕獲塊是最高級別的捕獲塊,必須捕獲所有冒泡到該級別的異常。 PHP 本身包含一個(您是否見過“致命錯誤:未捕獲的異常在……”消息?),但您可以使用自定義處理程序覆蓋它以作為後備。您可以使用 set_exception_handler() 函數設置此處理程序,因此您可以隨意這樣做,然後向您的 PHPMD 規則集中添加一條規則,禁止類似於“catch (Exception $e) {”之類的行。這是唯一一個應該在生產代碼中找到的一般異常處理程序的原因,它捕獲尚未捕獲的 Exception 類的每個實例。其他處理程序必須是特定的,並且僅限於它知道如何處理和負責的異常。在這裡謹慎行事,讓一個可處理的異常冒泡一次(然後在代碼中修復它)肯定比捕獲太多並充當靜默操作符要好得多。

總結

總而言之,只有當您的代碼無法使用給定的輸入完成請求的指令時才拋出異常,始終拋出自定義異常,該異常實際上會告訴調用代碼當前情況,並且如果您調用其他代碼,則只捕獲您可以並且應該處理的異常。這將使您的組件更少像黑盒(自定義異常),並減少集成您的組件的開發人員必須更改您的代碼的可能性(不要捕獲您不應該捕獲的異常)。我們總是告訴我們的客戶/管理人員要具體,但我們也應該具體!

(圖片來自 Fotolia)

關於 PHP 異常處理的常見問題

  • PHP 異常處理的目的是什麼?

PHP 異常處理是一種強大的機制,允許開發人員管理程序執行期間可能發生的錯誤和異常情況。它提供了一種將控制從程序的一個部分轉移到另一個部分的方法。 PHP 異常處理用於在發生指定錯誤時更改代碼執行的正常流程。這可以使代碼更易於閱讀和管理,因為它將錯誤處理代碼與主程序邏輯分開。

  • PHP 中的 try-catch 塊是如何工作的?

在 PHP 中,try-catch 塊用於處理異常。 try 塊包含可能拋出異常的代碼,而 catch 塊包含如果 try 塊中拋出異常將執行的代碼。如果 try 塊中拋出異常,則腳本停止運行,控制權將傳遞給與拋出的異常類型匹配的第一個 catch 塊。

  • finally 塊在 PHP 異常處理中的作用是什麼?

PHP 異常處理中的 finally 塊用於確保始終執行一段代碼,無論是否拋出異常。這對於清理活動(例如關閉文件或數據庫連接)非常有用,無論操作成功還是失敗都應執行這些活動。

  • 如何在 PHP 中創建自定義異常?

在 PHP 中,您可以通過擴展內置的 Exception 類來創建自定義異常。這允許您向異常添加自定義功能,或創建特定於應用程序域的異常。要創建自定義異常,您可以定義一個擴展 Exception 的新類,然後添加所需的任何自定義方法或屬性。

  • PHP 中異常和錯誤有什麼區別?

在 PHP 中,錯誤是一個嚴重的問題,會阻止腳本運行,而異常是一個改變正常執行流程的條件。錯誤通常是由語法錯誤或調用未定義函數等原因引起的。另一方面,異常通常用於處理對程序並非致命但需要特殊處理的條件。

  • 如何在 PHP 中處理多個異常?

在 PHP 中,您可以使用多個 catch 塊來處理多個異常。每個 catch 塊處理特定類型的異常。當拋出異常時,將按代碼中出現的順序檢查 catch 塊。將執行第一個能夠處理拋出的異常類型的 catch 塊。

  • 我可以在 PHP 中重新拋出異常嗎?

是的,您可以在 PHP 中重新拋出異常。如果您想以某種方式處理異常,但又想讓更高級別的異常處理程序捕獲它,這將非常有用。要重新拋出異常,只需在 catch 塊中使用 throw 語句即可。

  • 如何在 PHP 中記錄異常?

在 PHP 中,您可以通過在 catch 塊中使用 error_log 函數來記錄異常。這允許您將有關異常的信息(包括其消息和堆棧跟踪)記錄到指定的日誌文件中。

  • PHP 中的 PDOException 是什麼?

PDOException 是一種異常,當 PDO 操作中發生錯誤時會拋出該異常。 PDO(PHP 數據對象)是一個數據庫抽象層,它為訪問 PHP 中的數據庫提供一致的接口。 PDOException 提供有關錯誤的信息,包括 SQLSTATE 錯誤代碼和數據庫驅動程序的錯誤消息。

  • 如何在 PHP 中處理未捕獲的異常?

在 PHP 中,您可以通過定義自定義異常處理程序函數,然後使用 set_exception_handler 函數將其設置為默認異常處理程序來處理未捕獲的異常。每當拋出未被 try-catch 塊捕獲的異常時,都會調用此函數。

以上是PHP主|例外的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

PHP 8.1中的枚舉(枚舉)是什麼? PHP 8.1中的枚舉(枚舉)是什麼? Apr 03, 2025 am 12:05 AM

PHP8.1中的枚舉功能通過定義命名常量增強了代碼的清晰度和類型安全性。 1)枚舉可以是整數、字符串或對象,提高了代碼可讀性和類型安全性。 2)枚舉基於類,支持面向對象特性,如遍歷和反射。 3)枚舉可用於比較和賦值,確保類型安全。 4)枚舉支持添加方法,實現複雜邏輯。 5)嚴格類型檢查和錯誤處理可避免常見錯誤。 6)枚舉減少魔法值,提升可維護性,但需注意性能優化。

會話如何劫持工作,如何在PHP中減輕它? 會話如何劫持工作,如何在PHP中減輕它? Apr 06, 2025 am 12:02 AM

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

描述紮實的原則及其如何應用於PHP的開發。 描述紮實的原則及其如何應用於PHP的開發。 Apr 03, 2025 am 12:04 AM

SOLID原則在PHP開發中的應用包括:1.單一職責原則(SRP):每個類只負責一個功能。 2.開閉原則(OCP):通過擴展而非修改實現變化。 3.里氏替換原則(LSP):子類可替換基類而不影響程序正確性。 4.接口隔離原則(ISP):使用細粒度接口避免依賴不使用的方法。 5.依賴倒置原則(DIP):高低層次模塊都依賴於抽象,通過依賴注入實現。

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是REST API設計原理? 什麼是REST API設計原理? Apr 04, 2025 am 12:01 AM

RESTAPI設計原則包括資源定義、URI設計、HTTP方法使用、狀態碼使用、版本控制和HATEOAS。 1.資源應使用名詞表示並保持層次結構。 2.HTTP方法應符合其語義,如GET用於獲取資源。 3.狀態碼應正確使用,如404表示資源不存在。 4.版本控制可通過URI或頭部實現。 5.HATEOAS通過響應中的鏈接引導客戶端操作。

您如何在PHP中有效處理異常(嘗試,捕捉,最後,投擲)? 您如何在PHP中有效處理異常(嘗試,捕捉,最後,投擲)? Apr 05, 2025 am 12:03 AM

在PHP中,異常處理通過try,catch,finally,和throw關鍵字實現。 1)try塊包圍可能拋出異常的代碼;2)catch塊處理異常;3)finally塊確保代碼始終執行;4)throw用於手動拋出異常。這些機制幫助提升代碼的健壯性和可維護性。

PHP中的匿名類是什麼?您何時可以使用它們? PHP中的匿名類是什麼?您何時可以使用它們? Apr 04, 2025 am 12:02 AM

匿名類在PHP中的主要作用是創建一次性使用的對象。 1.匿名類允許在代碼中直接定義沒有名字的類,適用於臨時需求。 2.它們可以繼承類或實現接口,增加靈活性。 3.使用時需注意性能和代碼可讀性,避免重複定義相同的匿名類。

See all articles