php異常處理的深入

引出

如果你調一個類,調用時數據驗證時報了個錯,你會以什么方式返回

數組,布爾值?

數組這個可以帶錯誤原因回來,那布爾值呢?

返回了個 false, 報錯時把錯誤放在類變量里?
還是專門用一個獲取錯誤的方法進行獲取?

上面說的情況是代碼完全沒有問題的情況。
那如果是一些第三方的工具包,你又怎么知道他里面的執行會不會導致整個系統崩潰。

你說本地運行是沒問題的,環境這種東西不好說。

所以我們就用到了 異常 這個東西

下面是我們需要了解的問題

什么時候拋異常?怎么接異常?異常要怎么處理?他的使用場景又是什么?

基礎知識

  1. 基礎操作

    try ... catch()
    throw

  2. 錯誤級別

    致命錯誤 E_ERROR,
    語法錯誤 E_PARSE,
    警告錯誤 E_WARNING,
    通知錯誤 E_NOTICE

  3. php異常處理類

預定義異常

    * ErrorException (extends Exception)

SPL異常類

    * LogicException (extends Exception)      // 表示程序邏輯中的錯誤的異常。這種異常應該直接在代碼中的修復* BadFunctionCallException            // 回調調用未定義的函數或缺少一些參數時會拋出該異常* BadMethodCallException          // 回調方法是一個未定義的方法或缺失一些參數時會拋出該異常* DomainException                     // 值不遵守定義的有效數據域時會拋出該異常* InvalidArgumentException            // 參數不是預期類型時會拋出該異常* LengthException                     // 長度無效時會拋出該異常* OutOfRangeException                 // 請求非法索引時引發的異常,這應該在編譯時就檢測到的錯誤* RuntimeException (extends Exception)    // 在運行時發生的錯誤會拋出該異常* OutOfBoundsException                // 值不是有效鍵時會拋出該異常,這表示在編譯時無法檢測到的錯誤* OverflowException                   // 在向完整容器中添加元素時引發的異常* RangeException                      // 在程序執行期間為指示范圍錯誤而引發的異常。通常這意味著除了/overflow以外還有一個算術錯誤。這是運行時的DomainException版本* UnderflowException                  // 在空容器上執行無效操作(如刪除元素)時引發的異常* UnexpectedValueException            // 值與一組值不匹配時會拋出該異常。通常,當一個函數調用另一個函數并期望返回值為某種類型或值(不包括算術或緩沖區相關錯誤)時,就會發生這種情況
  1. 異常處理相關函數
    error_reporting // 設置報告的錯誤級別register_shutdown_function // 注冊一個會在php中止時執行的函數set_error_handler // 設置用戶自定義的錯誤處理函數set_exception_handler // 設置用戶自定義的異常處理函數error_get_last // 獲取最后發生的錯誤

使用場景

  1. 系統

    主要抓的是無法預測的錯誤,統一返回,沒有使用 try...catch 接收的異常直接跳進設置的方法中

<?phpnamespace App\Exception;use Exception;/*** 異常句柄(入口)類*/
class Handler
{// 默認錯誤處理public static function errorHandler($errno, $errstr, $errfile = '', $errline = 0){}// 默認異常處理public static function exceptionHandler($ex){try {throw $ex;} catch (Order $e) {echo "訂單異常";} catch (Goods $e) {echo "商品異常";} catch (User $e) {echo "用戶異常";} catch (Exception $e) {echo "其他異常";}}// 致命錯誤處理public static function fatalErrorHandler(){if ($e = error_get_last()) {print_r($e);}}
}/*** 訂單異常*/
class Order extends Exception
{
}/*** 商品異常*/
class Goods extends Exception
{
}/*** 用戶異常*/
class User extends Exception
{
}
<?php
// 入口文件中error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);register_shutdown_function(array('App\\Exception\\Handler', 'fatalErrorHandler'));set_error_handler(array('App\\Exception\\Handler', 'errorHandler'));set_exception_handler(array('App\\Exception\\Handler', 'exceptionHandler'));
  1. 工具

    定義自定義的異常,一有錯誤直接拋出。使用工具的程序只需通過 Exception 接收異常即可, 所有異常都通過這個進行處理的

<?phpnamespace Testlin\Db\Exception;use Exception;interface ExceptionInterface
{
}class Db extends Exception implements ExceptionInterface
{
}class Pdo extends Db
{
}
?><?php
namespace Testlin\Db;use Exception;
use Testlin\Db\Exception\Pdo;class Db
{protected $db;public function __construct($config){$this->db = new PDO($config);if ($this->db == false) {throw new Pdo("連接失敗");}}
}?>

文章例子

  1. 工具包例子
  2. 項目例子

FQA

1、為什么要定自定義異常類, 系統不是已經給了很多選擇,而且很多 composer 包里都只是繼承一下。

答:其實自定義異常是為了用區分異常顆粒度的,比如

我定了 訂單異常,商品異常,用戶異常 類,但是 訂單里的異常多種多樣,比如訂單支付異常,訂單生成異常。

* RuntimeException (extends Exception)* Order* Paymen* Created* Goods* User* Withdraw

當項目拋出異常時

<?phptry {$param = []; // 操作那個方法時傳的參數throw App\Exception\Order\Payment::forParam('執行xxx操作異常', $param);} catch (Exception $e) {// 相關操作get_class($e); // 當前異常類 App\Exception\Order\Payment}

通過異常類名,我們可以知道是訂單支付異常。這里可以代替錯誤號,而且更清晰明了

2、為什么有一些 composer 包里的自定義異常,有的有很多方法。有什么用處嗎?

作用1:格式化異常

比如:拋出的異常提示是 "id=xx 的用戶不存在",我們會有以下兩種寫法

<?php// 普通操作
$id = 1;
throw new Payment("id={$id} 的用戶不存在");// 格式化異常
use App\Exception\Order;class Payment extends Order
{public static function forId($id){return new self(sprintf('id=%s 的用戶不存在',$id));}
}$id = 1;
throw Payment::forId($id);

作用2:組件級別的異常

<?phpnamespace Testlin\Db\Exception;use Exception;interface ExceptionInterface
{
}class Mysqli extends Exception impements ExceptionInterface
{
}class Pdo extends Exception impements ExceptionInterface
{
}try {throw new Testlin\Db\Exception\Mysqli('sql 執行失敗');
} catch (Testlin\Db\Exception\ExceptionInterface $e) {// 這里取得的異常只會是繼承這個接口的異常// 可以只針對這個工具包進行處理
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/281795.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/281795.shtml
英文地址,請注明出處:http://en.pswp.cn/news/281795.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# 跨平臺的支付類庫ICanPay

隨著微軟的開源&#xff0c;越來越多的項目支持跨平臺&#xff0c;但是各種支付平臺提供的類庫&#xff0c;又老又不支持跨平臺&#xff0c;吐槽下&#xff0c;尤其是微信&#xff0c;還有好多坑&#xff0c;于是ICanPay誕生了&#xff0c;今天就來講ICanPay是什么&#xff0c;…

.NET CORE 下收發郵件之 MAILKIT

背景利用代碼發送郵件在工作中還是比較常見的&#xff0c;相信大家都用過SmtpClient來處理發送郵件的操作&#xff0c;不過這個類以及被標記已過時&#xff0c;所以介紹一個微軟推薦的庫MailKit來處理。MailKit開源地址&#xff1a;https://github.com/jstedfast/MailKit需要郵…

【20181026T2】**圖【最小瓶頸路+非旋Treap+啟發式合并】

題面 【錯解】 最大最小&#xff1f;最小生成樹嘛 蛤&#xff1f;還要求和&#xff1f; 點分治&#xff1f; 不可做啊 寫了個MST暴力LCA&#xff0c;30pts&#xff0c;140多行 事后發現30分是給dijkstra的 woc 【正解】 樹上計數問題&#xff1a;①并查集②啟發式合并③點分治 …

java實現關鍵詞云_Java synchronized 關鍵詞詳細說明

Java synchronized 關鍵詞詳細說明外置專業技能點系統進程和進程的定義進程建立方法進程的情況情況變換線程安全的定義synchronized 關鍵詞的幾類使用方法裝飾非靜態數據組員方式synchronized public void sync(){}裝飾靜態數據組員方式synchronized public static void sync()…

損失函數(Loss function) 和 代價函數(Cost function)

1損失函數和代價函數的區別&#xff1a; 損失函數(Loss function)&#xff1a;指單個訓練樣本進行預測的結果與實際結果的誤差。 代價函數(Cost function)&#xff1a;整個訓練集&#xff0c;所有樣本誤差總和(所有損失函數總和)的平均值。&#xff08;這一步體現在propagate()…

Hadoop/HDFS命令

Hadoop中文手冊&#xff1a;http://hadoop.apache.org/docs/r1.0.4/cn/commands_manual.html 英文手冊&#xff1a;http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/CommandsManual.html Hadoop fs命令 hadoop fs: 該命令可以用于其他文件系統&#x…

《Node.js 入門系列》—— 一些簡單的排錯方法(一)

目錄 TypeError: undefined is not a functionTypeError: Cannot read property xxx of undefined 或者 TypeError: Cannot read property xxx of null檢查變量是未賦值檢查函數是否有返回值檢查變量是否引用了某個對象不存在的屬性檢查調用函數時是否未該傳遞參數俗話說“常在…

內置IOC容器ServiceCollection

.NetCore內置IOC容器ServiceCollection一、IOC介紹IOC&#xff1a;全名(Inversion of Control)-控制反轉IOC意味著我們將對象的創建控制權交給了外部容器&#xff0c;我們不管它是如何創建的&#xff0c;我們只需要知道&#xff0c;當我們想要某個實例時&#xff0c;我們可以直…

java中 有沒有方法將瀏覽器標簽欄去掉_用JS去掉IE窗口的標題欄,工具欄,地址欄...

前言:經常上網的朋友可能會到過這樣一些網站&#xff0c;一進入首頁立刻會彈出一個窗口&#xff0c;或者按一個連接或按鈕彈出&#xff0c;通常在這個窗口里會顯示一些注意事項、版權信息 、警告、歡迎光顧之類的話或者作者想要特別提示的信息。其實制作這樣的頁面效果非常的容…

React+Redux仿Web追書神器

引言 由于 10 月份做的 React Native 項目沒有使用到 Redux 等庫&#xff0c;寫了一段時間想深入學習 React&#xff0c;有個想法想做個 demo 練手下&#xff0c;那時候其實還沒想好要做哪一個類型的&#xff0c;也看了些動漫的&#xff0c;小說閱讀&#xff0c;聚合資源的開源…

【算法】LeetCode算法題-Maximum Subarray

這是悅樂書的第154次更新&#xff0c;第156篇原創 01 看題和準備 今天介紹的是LeetCode算法題中Easy級別的第13題&#xff08;順位題號是53&#xff09;。給定一個整數數組nums&#xff0c;找出一個最大和&#xff0c;此和是由數組中索引連續的元素組成&#xff0c;至少包含一個…

windows配置solr5.5.2(不通過tomcat,使用內置jetty)

一、windows下配置solr5.5.2(不通過tomcat,使用內置jetty) 第一步&#xff1a;安裝Jdk1.7 Solr5.5好像只支持Jdk1.7及以上的版本&#xff0c;沒親測&#xff0c;solr6.0是只支持jdk1.8及以上的&#xff0c;下圖為啟動solr時的截圖&#xff1a; 如何在windows環境下配置jdk及驗證…

java起源英文_Abbreviation 英文詞組縮寫(來源:南陽理工大學ACM)java

As we know, we often use a short sequence of characters in place of some words with a very long name. For example, ACM is an abbreviation of “Association for Computing Machinery”. Now we are using an acronymic method to get the abbreviation. An acronym i…

【C# Personal Handbook】運行環境

一、CLR、CLI、CTS、CLS、BCL、FCL簡介CLI&#xff08;公共語言基礎&#xff09;CLI是微軟公司向ECMA提交的一份語言和數據格式規范&#xff0c;CLR是目前為止唯一一個公共語言基礎的實現版本。CLI包括了公共類型系統&#xff08;CTS&#xff09;、公共中間語言&#xff08;CIL…

如何完善自己的知識結構

★領域 &#xff08;本來想用“學科”這個詞&#xff0c;后來覺得“學科”的范疇還是偏小&#xff0c;就改用“領域”&#xff09;  按照傳統的習慣&#xff0c;通常會把知識歸類到不同的領域&#xff08;比如&#xff1a;文學、數學、計算機、烹調、等等&#xff09;。 ◇領…

MATLAB編程與應用系列-關于MATLAB編程入門教程的總體編寫安排

本系列教程來源于出版設計《基于MATLAB編程基礎與典型應用書籍》&#xff0c;如涉及版權問題&#xff0c;請聯系&#xff1a;156204968qq.com。 出版社&#xff1a;人民郵電出版社&#xff0c; 頁數&#xff1a;525。 本系列教程目前基于MATLABR2006a&#xff0c;可能對于更高級…

python語言特性-------python2.7教程學習【廖雪峰版】(一)

開始學習廖雪峰的py2.7教程&#xff1a; 2017年6月5日12:54:28 筆記&#xff1a; 廖雪峰python2.7教程1.用任何編程語言來開發程序&#xff0c;都是為了讓計算機干活。 2.Python是一種相當高級的語言。代碼少還不好&#xff1f;代碼少的代價是運行速度慢。3.用Python可以做什么…

java調c++代碼_Java中調用C++代碼的實現 | 學步園

JNI為 Java Native Interface 即Java本地接口&#xff0c;使用此種方式可以對C/C代碼進行調用&#xff0c;其在本質上是對C/C生成的動態庫進行調用而不是直接對C/C代碼進行調用Java代碼如下&#xff1a;public class TestJNI{//JNI在本質上是調用C/C的動態庫來實現的&#xff…

jeesite1.X 集成多數據源

2019獨角獸企業重金招聘Python工程師標準>>> 網上看了幾個例子&#xff0c;都是相同數據源的動態切換&#xff0c;如果不是同一種數據庫類型&#xff0c;分頁查詢就出問題。經過研究解決問題。 jeesite.properties配置多數數據源地址,這里以mysql5.7和sqlserver2008…

k8s HPA(HorizontalPodAutoscaler)-自動水平伸縮

Horizontal Pod Autoscaling in Kubernetes寫在前面我們平時部署web服務&#xff0c;當服務壓力大撐不住的時候&#xff0c;我們會加機器(加錢)&#xff1b;一般沒有上容器編排是手動加的&#xff0c;臨時加的機器&#xff0c;臨時部署的服務還要改Nginx的配置&#xff0c;最后…