PHP最佳實踐之異常和錯誤

異常

1).異常是Exception類的對象,在遇到沒法修復的情況時拋出,例如遠程API沒有響應或者數據庫查詢失敗再或者是沒法知足程序運行的前置條件。出現問題的時候異經常使用於主動出擊,委託職責;異常還能夠用於防守,預測潛在的問題來減輕影響。
2).Exception對象和其餘的PHP對象同樣,使用new關鍵字實例化。php

<?php
$exception = new Exception('userId cannot be null', 100);

第一個參數是消息,第二個參數是數字代碼。數字代碼是可選的,用於爲指定的異常提供上下文。咱們可使用公開的實例方法getCodegetMessage來得到異常對象的兩個屬性。
3).假如遇到了異常狀況,或者在當前的條件下沒法操做,咱們須要拋出異常。mysql

<?php
throw new Exception('Something went wrong.Time for lunch!');

4).咱們必須拋出Exception類或者他的子類,PHP內置的異常類和其子類以下:git

  • Exception
  • ErrorException
    PHP標準庫提供了下述額外的Exception子類,擴展了PHP內置的異常類。
  • LogicExceptiongithub

    • BadFunctionCallExceptionweb

      • BadMethodCallException
    • DomainException
    • InvalidArgumentException
    • LengthException
    • OutOfBoundsException
  • RuntimeExceptionsql

    • OutOfBoundsException
    • OverflowException
    • RangeException
    • UnderflowException
    • UnexpectedValueException

5).捕獲異常。預測和捕獲並處理異常是咱們本身的責任,由於未捕獲的異常可能會致使PHP應用終止運行,顯示錯誤信息。攔截並處理潛在異常的方式是,把可能拋出異常的代碼放在在try/catch塊中。數據庫

try {
    $pdo = new PDO('mysql://host=wrong_host;dbname=wrong_name');
} catch (PDOException $e) {
    $code = $e->getCode();
    $message = $e->getMessage();
    echo 'Something went wrong.Check back soon, please';
    exit;
}

還能夠連續拋出多個異常函數

try {
  throw new Exception('Not a PDO exception');
  $pdo = new PDO('mysql://host=wrong_host;dbname=wrong_name');
} catch (PDOException $e) {
    echo 'Caught PDO exception';
} catch (Exception $e) {
    //處理其餘異常
    echo 'Caught generic exception';
} finally {
    //這裏的代碼始終都會執行
    echo 'Always do this';
}

捕獲某種異常的時候只會容許其中一個catch塊,若是PHP沒有找到適用的catch塊,異常會向上冒泡,直到PHP腳本因爲致命的錯誤而終止。
6).異常處理程序。咱們可使用一個全局的異常處理程序,來捕獲全部未被捕獲的異常。異常捕獲程序都必須接受一個了類型爲Exception的參數,異常捕獲程序使用set_exception_handler()函數註冊。oop

<?php
set_exception_handler(function (Exception $e) {
    //處理並記錄異常
});

//你的代碼
...

//還原成以前的異常處理程序
restore_exception_handler();
錯誤

1).咱們可使用error_reporting()函數或者在php.ini文件中使用error_reporting指令告訴PHP報告或者忽略那些錯誤。這兩種都是使用E_*常量來肯定。
2)錯誤報告方式四原則:優化

  • 必定要讓PHP報告錯誤
  • 在開發環境中要顯示錯誤
  • 再生產環境中不能顯示錯誤
  • 在開發和生產環境中都要記錄錯誤

3)一種php.ini配置的例子:
開發環境:

;顯示錯誤
display_startup_errors = On
display_errors = On
;報告全部錯誤
error_reporting = -1
; 記錄錯誤
log_errors = On

生產環境:

;不顯示錯誤
display_startup_errors = Off
display_errors = Off
;除了注意事項外,報告全部錯誤
error_reporting = E_ALL & ~E_NOTICE
; 記錄錯誤
log_errors = On

4).註冊全局的錯誤處理程序:set_error_handler()函數。

<?php
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    //處理錯誤
    //$errno表示錯誤等級對應E_*常量
    //$errcontext是一個省略的參數,高級調試纔用到
});

5.一個簡單的全局錯誤處理程序的例子:

set_error_handler(function($errno, $errstr, $errfile, $errline) {
   if (!(error_reporting() & $errno)) {
    //error_reporting指令沒有設置這個錯誤,因此忽略
    return;  
  }
  throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

//其餘代碼

//還原成以前的錯誤處理程序
restore_error_handler();
相關處理組件
  • 開發環境: filp/whoops
  • 生產環境: monolog/monolog

專題系列

PHP專題系列目錄地址:https://github.com/xx19941215/webBlogPHP專題系列預計寫二十篇左右,主要總結咱們平常PHP開發中容易忽略的基礎知識和現代PHP開發中關於規範、部署、優化的一些實戰性建議,同時還有對Javascript語言特色的深刻研究。

相關文章
相關標籤/搜索