搜尋

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
使用數據庫存儲會話的優點是什麼?使用數據庫存儲會話的優點是什麼?Apr 24, 2025 am 12:16 AM

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

您如何在PHP中實現自定義會話處理?您如何在PHP中實現自定義會話處理?Apr 24, 2025 am 12:16 AM

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

什麼是會話ID?什麼是會話ID?Apr 24, 2025 am 12:13 AM

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

您如何在無狀態環境(例如API)中處理會議?您如何在無狀態環境(例如API)中處理會議?Apr 24, 2025 am 12:12 AM

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。

您如何防止與會議有關的跨站點腳本(XSS)攻擊?您如何防止與會議有關的跨站點腳本(XSS)攻擊?Apr 23, 2025 am 12:16 AM

要保護應用免受與會話相關的XSS攻擊,需採取以下措施:1.設置HttpOnly和Secure標誌保護會話cookie。 2.對所有用戶輸入進行輸出編碼。 3.實施內容安全策略(CSP)限制腳本來源。通過這些策略,可以有效防護會話相關的XSS攻擊,確保用戶數據安全。

您如何優化PHP會話性能?您如何優化PHP會話性能?Apr 23, 2025 am 12:13 AM

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显著提升应用在高并发环境下的效率。

什麼是session.gc_maxlifetime配置設置?什麼是session.gc_maxlifetime配置設置?Apr 23, 2025 am 12:10 AM

theSession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceisesneededeededeedeedeededto toavoidperformance andunununununexpectedLogOgouts.3)

您如何在PHP中配置會話名?您如何在PHP中配置會話名?Apr 23, 2025 am 12:08 AM

在PHP中,可以使用session_name()函數配置會話名稱。具體步驟如下:1.使用session_name()函數設置會話名稱,例如session_name("my_session")。 2.在設置會話名稱後,調用session_start()啟動會話。配置會話名稱可以避免多應用間的會話數據衝突,並增強安全性,但需注意會話名稱的唯一性、安全性、長度和設置時機。

See all articles

熱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

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

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

記事本++7.3.1

記事本++7.3.1

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

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中