PHP 核心特性 - 錯誤處理

来源:https://www.cnblogs.com/a609251438/archive/2019/11/22/11914460.html
-Advertisement-
Play Games

錯誤與異常 錯誤,可以理解程式本身的錯誤,例如語法錯誤。而異常則更偏向於程式運行不符合預期或者不符合正常流程;對於 PHP 語言而言,處理錯誤和處理異常使用的機制完全不同,因此很容易讓人產生困惑。 例如,我們希望通過捕獲異常來處理除數為 0 的情況,但是在捕獲到異常之前,PHP 就觸發了錯誤。 1 ...


錯誤與異常

錯誤,可以理解程式本身的錯誤,例如語法錯誤。而異常則更偏向於程式運行不符合預期或者不符合正常流程;對於 PHP 語言而言,處理錯誤和處理異常使用的機制完全不同,因此很容易讓人產生困惑。

例如,我們希望通過捕獲異常來處理除數為 0 的情況,但是在捕獲到異常之前,PHP 就觸發了錯誤。

1 try {
2     $a = 5 / 0;
3 } catch (Exception $e) {
4     $e->getMessage();
5     $a = -1;  // 通過異常來處理 $a 為 0 的情況,但是實際上,捕獲不到該異常
6 }
7 
8 echo $a;
9 // PHP Warning:  Division by zero

 

也就是說,PHP 將除數為 0 的情況當成了錯誤而觸發,而不會自動拋出異常,因此沒法捕獲。類似的,在很多情況下,PHP 都沒辦法自動拋出異常。只能通過 if - else 語句判斷再結合 throw 方法來並手動拋出異常。

上述情況的發生,主要還是因為異常機制是 PHP 向面向對象演進後得到的產物。而在此之前 PHP 的報錯主要還是通過錯誤機制,因此,在很多情況下,PHP 的錯誤要比異常更有價值。不過 PHP7 開始統一這兩者,使錯誤也可以像異常那樣拋出(這部分內容將放在異常部分講解)。

 

錯誤級別

PHP 中的錯誤可理解為 使腳本不運行不正常的情況,根據錯誤級別從高到低可劃分為五類

  1. Parse error 或 Syntax Error - 語法解析錯誤,觸發該錯誤後,腳本完全無法運行;
  2. Fatal Error - 致命錯誤,觸發該錯誤後,後面的腳本無法繼續執行;
  3. Warning Error - 出現比較不恰當的地方,腳本可繼續執行;
  4. Notice Error - 出現不恰當的地方,但是程度比 Warning Error 低,腳本可繼續執行;
  5. Deprecated Error - 不推薦這麼使用,未來可能會廢棄,腳本可繼續執行;

預設情況下,PHP 觸發錯誤,並顯示錯誤的級別及對應的提示。

Parse Error 示例 - 語句結尾不寫分號

1 echo "abc"
2 // PHP Parse error:  syntax error, unexpected end of file, expecting ',' or ';

 

Fatal Error 示例 - 使用不存在的函數

1 echo "before\n";
2 foo();
3 echo "after"; // 本行無法繼續執行
4 // before
5 // PHP Fatal error:  Uncaught Error: Call to undefined function foo()

 

Warning Error 示例 - 引入不存在的文件

 1 $a = "foo";
 2 include('bar.php');
 3 echo $a; // 程式繼續執行
 4 // PHP Warning:  include(bar.php): failed to open stream: No such file or directory ...
 5 // foo
 6 Notice Error 示例 - 輸出不存在的變數
 7 
 8 echo $foo;
 9 echo 12345;
10 // PHP Notice:  Undefined variable: foo
11 // 12345

 

Deprecated Error 示例 - 在一些字元串函數中傳入數字而非字元串

1 strpos('12345', 3);
2 // PHP Deprecated:  strpos(): Non-string needles will be interpreted as strings in the future

 

除了預設觸發消息外,用戶也可以使用 set_error_handler 函數自定義錯誤處理,大多數錯誤類型都可以進行自定義處理,除了 E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING 外。

1 set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] ) : mixed

 

示例

 1 <?php
 2 // E_ALL - 處理全部錯誤類型
 3 set_error_handler('customError', E_ALL);
 4 
 5 /**
 6  * @param  int $errno 錯誤的級別
 7  * @param  string $errstr  錯誤的信息
 8  * @param  string $errfile 錯誤的文件名(可選)
 9  * @param  string $errline 錯誤發生的行號(可選)
10  */
11 function customError(int $errno, string $errstr, string $errfile, string $errline)
12 {
13     echo sprintf('錯誤消息為 %s', $errstr);
14 }
15 
16 $a = 5 / 0;  // 錯誤消息為 Division by zero

 

用戶也可以通過 trigger_error 函數來手動觸發一個用戶級別的錯誤(E_USER_ERRORE_USER_WARNINGE_USER_NOTICEE_USER_DEPRECATED)。

1 function division($a, $b) {
2     if($b == 0){
3         @trigger_error("0 不能作為除數", E_USER_NOTICE);
4         return -1;
5     }
6     return $a / $b;
7 }
8 
9 echo division(10, 0);

 

 

與錯誤有關的配置

一些錯誤處理相關的常用配置

  • error_reporting - 設置錯誤的報告級別
  • display_errors - 是否顯示錯誤
  • display_startup_error - 是否顯示 PHP 啟動過程中的顯示
  • log_errors - 設置是否將腳本運行的錯誤信息記錄到伺服器錯誤日誌或者 error_log 之中

《Modern PHP》提出了四個規則

  1. 一定要讓 PHP 報告錯誤;
  2. 在開發環境中要顯示錯誤;
  3. 在生產環境中不能顯示錯誤;
  4. 在開發環境和生產環境中都要記錄錯誤;

開發環境推薦配置

1 display_errors = On
2 display_startup_error = On
3 error_reporting = -1
4 log_errors = On

 

生產環境推薦配置

1 display_errors = Off
2 display_startup_error = Off
3 ; 報告 Notice 以外的所有錯誤
4 error_reporting = E_ALL & ~E_NOTICE
5 log_errors = On
6  

 

Symfony 編碼規範相關

異常和錯誤消息字元串必須使用 sprintf 來進行拼接;

throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));

當錯誤類型為 E_USER_DEPRECATED 時,需要添加 @

@trigger_error("foo", E_USER_DEPRECATED);

參考資料


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文分四個步驟來詳講如何用PyInstaller將py文件打包成exe文件 1. PyInstaller 簡介 2. PyInstaller 安裝 3. 將py文件打包成exe文件 4. PyInstaller打包常見問題 ...
  • 基於WEB的網上購物系統主要功能包括:前臺用戶登錄退出、註冊、線上購物、修改個人信息、後臺商品管理等等。本系統結構如下:(1)商品瀏覽模塊: 實現瀏覽最新商品 實現按商品名稱瀏覽商品 實現根據商品分類瀏覽商品(2)購物車: 登錄後可以將商品加入購物車,或從購物車移除商品(3)登錄、註冊: 購物前需要 ...
  • 1.LinkedHashSet 的概述和使用 llinkedHashSet 的特點: 是唯一能保證怎麼存就怎麼輸出的 set 集合,並且去重覆 1 LinkedHashSet<String> linkSet = new LinkedHashSet<>(); 2 /* LinkedHashSet可以保 ...
  • kafka 由於它自身的高性能發送與消費能力,而受到廣大企業的喜歡,所以我們就先看看kafka 一些源碼實現如下: 這段代碼摘抄的是,kafka源碼 生產者發送消息demo(kafka.examples.Producer) 裡面的一個片段,主要是涉及到兩個知識點,一個是非同步發送消息, 回調函數的實現 ...
  • 最近由於一些原因,接觸了一些房產中介,其中發現一些房產中介說起房產相關的東西來,是滔滔不絕,對於所在片區樓盤各個優略,性價比幾許之類的,爛熟於心。 說到樓盤一些動情之處,時而會陷入沉思,時而張牙舞爪。給人的感覺非常用心專業。額,說這些和代碼有什麼關係?其實我從這些中介的身上發現他們對於自己所從事 的 ...
  • 本文源碼: "GitHub·點這裡" || "GitEE·點這裡" 一、生活場景 1、場景描述 變色龍是爬行動物,是非常奇特的動物,它有適於樹棲生活的種種特征和行為,身體也會隨著環境的變化而變化出適應環境的顏色,非常神奇。下麵基於狀態模式對該變化過程進行描述。 2、代碼實現 二、狀態模式 1、基礎概 ...
  • Kafka的結構與RabbitMQ類似,消息生產者向Kafka伺服器發送消息,Kafka接收消息後,再投遞給消費者。 生產者的消費會被髮送到Topic中,Topic中保存著各類數據,每一條數據都使用鍵、值進行保存。 每一個Topic中都包含一個或多個物理分區(Partition),分區維護著消息... ...
  • 1.持久化 1.1 持久化簡介 持久化(Persistence),持久化是將程式數據在持久狀態和瞬時狀態間轉換的機制,即把數據(如記憶體中的對象)保存到可永久保存的存儲設備中(如磁碟)。 1.2 redis持久化 redis為記憶體資料庫,為了防止伺服器宕機以及伺服器進程退出後,伺服器數據丟失,Redi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...