亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP中異常處理的一些方法整理

2020-03-22 18:20:25
字體:
來源:轉載
供稿:網友
每一個新的功能添加到PHP運行時會創建一個指數隨機數,通過這樣的方式開發者可以使用和甚至濫用這個新特性。然而,直到一些好的和壞的使用情況陸續出現開發者們才達成了共識。當這些新案例不斷浮現,我們終于可以辨別出什么是最好或最壞的做法。異常處理在PHP中的確無論如何都不算是一個新的特征。但在本文中,我們將討論在PHP 5.3中基于異常處理的兩個新的特點。第一個是嵌套異常第二是一套SPL(現在的PHP運行機制的一個核心擴展)的擴展的新的異常類型。這兩個新特性,這本書里都能找到最佳實踐值得各位去詳細研究。
特別要注意:這些特性中的一些已經存在于低于5.3的PHP版本之中,或者至少能夠在低于5.3的版本之中被實現. 而當本文提到 PHP 5.3, 并不是嚴責意義上的 PHP 運行時版本. 相反,它意味著代碼庫和項目是采用 PHP 5.3 作為最低版本的,但同時也是在新的發展階段出現的所有最佳實踐. 這個發展階段所凸顯的是特定的幾個像Zend Framework, Symfony, Doctrine 以及 PEAR 這樣的項目所進行的“2.0”嘗試.背景PHP 5.2 只有一個異常類 Exception。按照 Zend Framework / PEAR 的開發標準, 這個類是你的庫中所有異常類的基類。如果你創建一個名叫 MyCompany 的庫,按 Zend Framework / PEAR 的標準, 庫中所有的代碼文件都會以 MyCompany_ 開頭。要是你想給庫創建自己的異?;? MyCompany_Exception, 那就用該類繼承 Exception,然后再由組件(component )繼承和拋出該異常類。比如你有一個組件 MyCompany_Foo,你可以給它創建一個用在該組件內部的異常基類 MyCompany_Foo_Exception。這些異常能被捕捉 MyCompany_Foo_Exception,MyCompany_Exception 或 Exception 的代碼捉到。 對于庫中其他用到該組件的代碼來說,這是個三層的異常(或更多,取決于 MyCompany_Foo_Exception 的子類有幾層 ), 他們可以根據自己的需要處理這些異常。
在php5中,基本異常類已經支持嵌套的特性了。什么是嵌套呢?嵌套是一種能力可以去捕獲特殊異常,或者捕獲參照原始異常而創建的一個新的異常對象。這將會允許caller屬性在更公開的類型的開銷庫中出現的兩種異常類上得到體現,當然也會在具有原始異常行為的異常類上體現。為什么這些特性很有用?通常,通過使用其他代碼來拋出自己的類型的異常是最有效的代碼。這些代碼可能是使用適配器模式封裝的提供一些適應性更強強的函數的第三方代碼庫的代碼,或利用一些PHP擴展來拋出異常的簡單代碼。
例如,在組件 Zend_Db 中, 它使用了適配器模式來封裝特定的 PHP 擴展,來創建一個數據庫抽象層. 在一個適配器中, Zend_Db 封裝了 PDO, 而 PDO 會拋出它自己的異常 PDOException, Zend_Db 需要捕獲這些特定于 PDO 的異常,并讓它們以可預期且類型已知的 Zend_Db_Exception 重新被拋出. 這樣就給了開發者保證, Zend_Db 將總是拋出 Zend_Db_Exception 類型的異常(因此可以被捕獲), 而他們同時也可以在需要的時候訪問到最開始被拋出的 PDOException.下面的示例展示了一個虛構的數據庫適配器可能如何去實現嵌入式的異常:

html' target='_blank'>class MyCompany_Database * @var PDO object setup during construction protected $_pdoResource = null; * @throws MyCompany_Database_Exception * @return int public function executeQuery($sql) try { $numRows = $this- _pdoResource- exec($sql); } catch (PDOException $e) { throw new MyCompany_Database_Exception('Query was unexecutable', null, $e); return $numRows;為了使用嵌入式的異常,你就得調用被捕獲異常的getPrevious()方法:

// $sql and $connectionParameters assumedtry { $db = new MyCompany_Database('PDO', $connectionParams); $db- executeQuery($sql);} catch (MyCompany_Database_Exception $e) { echo 'General Error: ' . $e- getMessage() . "/n"; $pdoException = $e- getPrevious(); echo 'PDO Specific error: ' . $pdoException- getMessage() . "/n";大多數最近被實現的PHP擴展都擁有OO(面向對象)接口. 因此,這些API傾向于拋出異常,而不是發生錯誤終止。PHP中能夠拋出異常的擴展,稍微列舉出幾個就包括有PDO, DOM, Mysqli, Phar, Soap 以及 SQLite.新特性:新核心異常類型在PHP 5.3開發中,我們展示了一些有趣的新異常類型。這些異常在PHP 5.2.x中已經存在,但最近還沒到“重新評估”異常的最佳實踐,現在他們會顯得更加引人注目。他們在SPL擴展中得以應用,并在手冊中列出(這里)由于這些新的異常類型是PHP核心的一部分,也是SPL的一部分,它們可以被任何用PHP 5.3(及以上)運行代碼的人使用。雖然在編寫應用程序層的代碼時,看起來不那么重要,但在我們寫或者使用代碼庫時,使用這些新異常類型變得更加重要
那么為什么新異常是普通類型?以前,開發者試圖通過在異常消息提醒中放入更多的內容來賦予異常更多的含義。雖然這樣做是可行的,但是它有幾個缺點。一是你無法捕獲基于消息的異常。這可是一個問題,如果你知道一組代碼是同樣的異常類型與不同的提示消息對應不同異常情況下,處理起來的難度將相當的大。例如,一個認證類,在對$auth- authenticate();;它拋出異常的相同類型的(假設是異常),但不同的消息對應兩個具體的故障:產生故障原因是認證服務器不能達到但是相同的異常類型卻提示失敗的驗證消息不同。在這種情況下(注意,使用異常可能不是處理認證響應最好的方式),這將需要用字符串來解析消息從而處理這兩種不同的情況。
這個問題的解決辦法顯然是通過某種方式對異常進行編碼,這樣就可以在需要辨別如何對這種異常環境做出反應的時候能夠更加容易的查詢到。第一個反應庫是使用異?;惖?code屬性。另一個是通過創建可以被拋出且能描述自身行為的子類或者新的異常類。這兩種方法具有相同的明顯的缺點。兩者都沒有呈現出想這樣的最好的例子。兩者都不被認為是一個標準,因此每個試圖復制這兩種解決方案的項目都會有小的變化,這就迫使使用這需要回到文檔以了解所創建的庫中已經有的具體解決方案。現在通過使用SPL的新的類型方法,也稱作php標準庫;開發者就可以以同樣的方式在他們的項目中,并且復用這些項目的新的最佳的方法已經出現。
第二個缺點是使用詳細信息的做法使得理解這些異常情況對那些非英語或英語能力有限的開發者來說十分困難。這可能會使的開發者在試圖理解異常信息的含義的過程十分的緩慢。許多開發者也會寫關于異常的文章,因為還未出現一個統一的整合過的標準所要有同這些開發者數量相同的不同的版本來描述異常消息所描述的情況。所以我如何去使用它們,就用這些讓人無語的密密麻麻的細節描述?現在在SPL中有總共13個新的異常類型。其中兩個可被視為基類:邏輯異常和運行時異常;兩種都繼承php異常類。其余的方法在邏輯上可以被拆分為3組:動態調用組,邏輯組和運行時組。動態調用組包含異常 BadFunctionCallException和BadMethodCallException,BadMethodCallException是BadFunctionCallException(LogicException的子類)的子類,這意味著這些異??梢员黄渲苯宇愋停ㄗg者注:就是異常自身的類型,大家都知道異常有很多種)、LogicException,或者Exception抓到(譯者注:就是catch)你應該在什么時候使用這些?通常,你應該在由一個無法處理的__call()方法產生的情況,或者回調無法不是一個有效的函數(簡單說,當某些東西并非is_callable())時使用。例如:

// OO variantclass Foo public function __call($method, $args) switch ($method) { case 'doBar': /* ... */ break; default: throw new BadMethodCallException('Method ' . $method . ' is not callable by this object');// procedural variantfunction foo($bar, $baz) { $func = 'do' . $baz; if (!is_callable($func)) { throw new BadFunctionCallException('Function ' . $func . ' is not callable');一個直接的例子,在__call時call_user_func()。這組異常在開發各種API動態方法的調用、函數調用時非常有用,例如這是一個可以被SOAP和XML-RPC客戶端/服務端能夠發送和解釋的請求。
第二組是邏輯(logic )組。這組由DomainException、InvalidArgumentException、LengthException、OutOfRangeException組成。這些異常也是LogicException的子類,當然也是PHP的Exception的子類。在有狀態不定,或者錯誤的方法/函數的參數時使用這些異常。為了更好地理解這一點,我們先看看最后一組異常最后一組是運行時(runtime )組。它由OutOfBoundsException、OverflowException、RangeException、UnderflowException、UnexpectedValueExceptio組成。這些異常也是RuntimeException的子類,當然也是PHP的Exception的子類。在“運行時”(runtime)的函數、方法發生異常時,這些異常(運行時組)會被調用
邏輯組和運行時組如何一起工作?如果你看看對象的剖析,通常是發生的是兩者之一。首先,對象將跟蹤并改變狀態。這意味著對象通常是不做任何事情。它可能會傳遞結構給它,它可能會通過setter和getter設置一些東西(譯者注:例如$this- foo='foo'),或者,它可能會引用其他對象。第二,當對象不跟蹤或改變狀態,這代表正在操作——做它該做的事。這是對象的運行時(runtime)。例如,在對象的一生中,它可能被創建,設置一些東西,那么它可能會被setFoo($foo),setBar($bar)。在這些時候,任何類型的LogicException應該被提高。此外,當對象內的方法被帶參數調用時,例如$object- doSomething($someVariation);在前幾行檢查$someVariation變量時,可能拋出一個LogicException。完成檢查$someVariation后,它繼續做它該做的doSomething(),這時被認為是它的“運行時”(runtime),在這段代碼中,可能拋出RuntimeExcpetions異常。
要理解得更好,我們來看看這個概念在代碼中的運用:

class Foo protected $number = 0; protected $bar = null; public function __construct($options) /** 本方法拋出LogicException異常 **/ public function setNumber($number) /** 本方法拋出LogicException異常 **/ public function setBar(Bar $bar) /** 本方法拋出LogicException異常 **/ public function doSomething($differentNumber) if ($differentNumber != $expectedCondition) { /** 在這里,拋出LogicException異常 **/ * 在這里,本方法拋出RuntimeException異常現在理解了這一概念,那么,對代碼庫的使用者來說,這是做什么的呢?使用者可以隨時確定對象的異常狀態,他們可以用異常的具體的類型來捕獲(catch)異常,例如InvalidArgumentException或LengthException,至少也是LogicException。通過這種級別的精度調整,和類型的多樣,他們可以用LogicException捕獲最小的異常,但也可以通過實際的異常類型獲得更好的理解。同樣的概念也適用于運行時的異常,可以拋出更多的特定類型的異常,并且不論是特定或非特定類型的異常,都可以被捕獲(catch)。它可以給使用者提供更詳細的情況和精確度。下面是一個關于SPL異常的表,您可能會有興趣類庫代碼中的最佳實踐PHP 5.3 帶來了新的異常類型, 同時也帶給我們新的最佳實踐. 除了將某些特定的異常(如: InvalidArgumentException, RuntimeException)標準化外, 捕捉組件級的異常, 也很重要. 關于這方面, ZF2 wiki 和 PEAR2 wiki 上面有深入的探討.簡而言之, 除了上面提到的各種最佳實踐, 我們還應該用 Marker Interface 來創建一個組件級的異常基類. 通過創建組件級的 Marker Interface, 用在組件內部的異常既能繼承 SPL 的異常類型, 也能在運行時被各種代碼捕捉. 我們來看下列代碼:

// usage of bracket syntax for brevitynamespace MyCompany/Component { interface Exception class UnexpectedValueException extends /UnexpectedValueException implements Exception class Component public static function doSomething() if ($somethingExceptionalHappens) { throw new UnexpectedValueException('Something bad happened');如果調用上面代碼中的 MyCompany/Component/Component::doSomething() 函數, doSomething() 拋出的異??梢援斪飨铝挟惓n愋筒蹲? PHP 的 Exception, SPL 的 UnexpectedValueException, SPL 的 RuntimeException, 該組件的MyCompany/Component/UnexpectedValueException, 或該組件的 MyCompany/Component/Exception. 這為捕捉你的類庫組件中的異常提供了極大的便利. 此外, 通過分析異常的類型, 我們也能看出某個異常的含義.
PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美成人精品激情在线观看| 91手机视频在线观看| 一区二区欧美日韩视频| 久久99精品国产99久久6尤物| 久久五月天综合| 91精品国产91久久久久久不卡| 热99久久精品| 992tv成人免费影院| 欧美激情久久久久| 91精品久久久久久久久久久久久久| 精品久久久久久中文字幕| 亚洲天堂免费观看| 亚洲护士老师的毛茸茸最新章节| 国产精品2018| 欧美视频一区二区三区…| 欧美精品xxx| 中国日韩欧美久久久久久久久| 亚洲欧美在线一区二区| 国产精品爽爽爽爽爽爽在线观看| 国产99久久精品一区二区永久免费| 45www国产精品网站| 欧美日韩999| 欧美大成色www永久网站婷| 欧美激情啊啊啊| 国产精品日日摸夜夜添夜夜av| 亚洲精品第一国产综合精品| 国产精品免费视频xxxx| 欧美性生交xxxxxdddd| 欧美疯狂xxxx大交乱88av| 欧美在线观看视频| 久久久久久999| 成人综合网网址| 久精品免费视频| 国产精品69久久久久| 国产精品aaa| 国产免费成人av| 亚洲精品999| 亚洲国产第一页| 久久99热精品这里久久精品| 国产精品旅馆在线| 亚洲成年人在线| 欧美成年人网站| 国产成人精品一区| 亚洲三级 欧美三级| 亚洲欧美综合图区| 欧美日韩日本国产| 成人免费xxxxx在线观看| 中文字幕亚洲欧美日韩高清| 国产精品丝袜白浆摸在线| 国产精品成人va在线观看| 欧美日韩亚洲一区二区三区| 亚洲第一精品久久忘忧草社区| 欧美激情久久久| 国产成人啪精品视频免费网| 中文字幕精品国产| 伊人青青综合网站| 欧美xxxx做受欧美.88| 日韩成人中文字幕| 日韩国产高清视频在线| 亚洲国产精品专区久久| 久久黄色av网站| 欧美日韩国产精品一区二区三区四区| 九九热在线精品视频| 日韩在线免费高清视频| 成人444kkkk在线观看| 久久成人精品电影| 91精品国产精品| 欧美亚洲第一页| 伊人av综合网| 国产偷国产偷亚洲清高网站| 国产精品黄色影片导航在线观看| 欧美另类交人妖| 国产成人精品一区二区三区| 国外成人免费在线播放| 欧美在线观看www| www.久久久久久.com| 欧美激情一级欧美精品| 久久久免费av| 国产精品成人一区| 在线一区二区日韩| 久久精品在线播放| 国产精品久久久久久久久久久久| 国产精品亚发布| 成人激情视频免费在线| 久久久精品影院| 神马国产精品影院av| 国产精品美女免费视频| 中文字幕亚洲第一| 亚洲欧美综合图区| 色噜噜狠狠色综合网图区| 国产在线一区二区三区| 日韩美女视频在线观看| 久久精彩免费视频| 久久久久久国产三级电影| 国产精品日韩精品| 欧美又大又硬又粗bbbbb| 成人黄色av播放免费| 日韩美女福利视频| 国产精品久久97| 欧美精品免费播放| 国产成人一区二区三区电影| 亚洲综合中文字幕在线| 日本国产一区二区三区| 大桥未久av一区二区三区| 日韩欧美综合在线视频| 国产精品精品久久久久久| 亚洲综合中文字幕在线观看| 日韩av免费在线观看| 亚洲天堂成人在线视频| 国产精品∨欧美精品v日韩精品| 亚洲自拍在线观看| 欧美成人午夜免费视在线看片| 91嫩草在线视频| 亚洲系列中文字幕| 91夜夜揉人人捏人人添红杏| 最新中文字幕亚洲| 欧美黑人性猛交| 久久久999精品| 91免费福利视频| 国产成人精品一区二区在线| 精品一区二区三区电影| 国产精品网红直播| 国产一区二区色| 国内精品视频久久| 综合激情国产一区| 欧美最猛性xxxxx免费| 国产精品成人在线| www日韩中文字幕在线看| 日韩av第一页| 中文字幕亚洲欧美日韩在线不卡| 成人xxxxx| 亚洲免费伊人电影在线观看av| 91网站在线免费观看| 57pao国产精品一区| 中文字幕自拍vr一区二区三区| 国产不卡av在线| 国产99久久久欧美黑人| 亚洲精品视频中文字幕| 欧美性20hd另类| 亚洲国产精品久久| 国产亚洲精品久久久久动| 欧美诱惑福利视频| 久久97久久97精品免视看| 97香蕉超级碰碰久久免费软件| 97视频在线观看免费高清完整版在线观看| 国产精品综合久久久| 亚洲最大在线视频| 日韩欧美国产激情| 伊人久久综合97精品| 亚洲电影免费观看高清| 久久成人精品视频| 中文字幕在线看视频国产欧美| 精品丝袜一区二区三区| 国模吧一区二区| 精品视频偷偷看在线观看| 亚洲精品久久久久久久久久久| 亚洲有声小说3d| 国产xxx69麻豆国语对白| 91精品视频在线免费观看| 欧美人与物videos| 狠狠综合久久av一区二区小说| 最近2019年中文视频免费在线观看| 亚洲香蕉伊综合在人在线视看| 久久九九国产精品怡红院|