最後更新:2016-06-01
來源:互聯網
上載者:User
關鍵字
處理
錯誤
函數
調用
我們
一個
PEAR
模式
使用
PEAR提供了強大的錯誤處理機制。這篇文章向你展示如何從這個系統中獲益。
許多程式已經使用了PEAR的包。許多PHP程式員或多或少的熟悉了PEAR中的錯誤處理。但是這個機制並不局限於PEAR的包——所有人都能在他們的類和程式中使用這些方法。
這篇文章被分為兩個部分:首先我們將看看類中用於錯誤處理的函數,然後我們將看看如何基於PEAR錯誤處理機制來處理錯誤。
我們的例子類稱為cvs2db,它把資料從CSV檔案插入到資料庫的表中。因為資料可能是手寫的,他們的資料應該在插入之前先得到驗證——落實postcode。函數import()完成讀入,檢查和插入的工作;它返回損壞的記錄數目。如果返回的值大於0,出錯的記錄集能夠使用exportUnvalid()寫入到新的CSV檔案中。典型的用法是這樣的:
import("./dat.csv", $dsn, 'address')) {$cd->exportUnvalid("./dat2.csv");}?>
可能的錯誤包括:
要匯入的CSV檔案不存在,
串連到資料庫失敗,
記錄集損壞,以及CSV匯出檔案無法建立。
在提供錯誤資訊的經典解決方案中你可能寫這樣的代碼:
import("./dat.csv", $dsn, 'address')switch($result) {case FILE_NOT_OPENED:...break;case DATABASE_ERROR:...break;default:if(0 < $result) {$cd->exportUnvalid("./dat2.csv");} else {echo 'every thing ok!'}}?>
這對於短的指令碼來說是可接受的也是常用的辦法——但是對於錯誤處理經常受到關注的大程式來說不是這樣。傳統的可能性強迫類的作者做最終的決定!在大部分情況下,這個決定根據的是那時對類的調用而不是基於長期的使用和可重用代碼的思想。一個靈活的錯誤處理機制是可重用代碼的重要部分,PEAR Error API 就是這樣的一種受到良好測試的機制。
使用者眼中的類
除了那兩個函數之外,類提供了一套錯誤處理函數和一個自己的錯誤對象稱為DB2CVS_Error,它有一個特殊的本地化的錯誤資訊的特性功能。
現在我將向你展示如何在錯誤發生時控制類的行為。
局部和全域錯誤處理
你用setErrorHandling()管理錯誤處理;這個函數需要兩個參數:第一個是錯誤模式,而第二個(可選的)參數是錯誤模式特定的選項。例如 setErrorHandling(PEAR_ERROR_PRINT, 'This error occurred %s') 還有 setErrorHandling(PEAR_ERROR_TRIGGER, E_USER_WARNING)。
這個函數的調用方式是一般行為中最重要的:靜態還是實體。在類cvs2db中,我們能兩者都用來設定錯誤處理,所有這些調用有相同的結構——為類設定錯誤模式:
// per instance$cd = new csv2db();$cd->setErrorHandling(PEAR_ERROR_DIE):// staticCVS2DB::setErrorHandling(PEAR_ERROR_DIE);PEAR::setErrorHandling(PEAR_ERROR_DIE);
如果兩者給出同樣的結果,區別在哪?實體調用僅僅為那個類設定而靜態調用對於所有使用PEAR_Error或者從那個類派生的所有類起作用。這個也作用於第一個靜態命令CVS2DB::setErrorHandling(PEAR_ERROR_DIE)——雖然它看上去僅僅影響了cvs2db類。
總結:作為一個實體函數使用命令意味著僅僅為這個實體(局部)設定錯誤模式,而作為靜態函數來調用就是為整個指令碼設定錯誤模式(全域)。
setErrorHandling() 和 raiseError()
兩個函數都能夠被靜態調用和作為實體的函數調用。記住怎樣的一個組合使得他們如何互相影響的很重要。
基本上是: setErrorHandling()的靜態調用僅僅影響raiseError()的靜態調用——setErrorHandling()作為實體函數僅僅影響raiseError()作為靜態函數調用。在類csv2db中,使用csv2db::setErrorHandling()來設定錯誤模式是不可行的,因為我們使用$this->raiseError(...)。解決這個聞天有一點小技巧——改寫raiseError():
function raiseError(...,$mode=null, $options=null,...) {if($mode==null && $this->_default_error_mode!=null) {$mode = $this->_default_error_mode;$options = $this->_default_error_options;}return PEAR::raiseError(...,$mode, $options,...);}
這樣,我們映射實體調用到靜態上,如果你用錯誤模式調用raiseError(),然後這個模式將會覆蓋這些設定——這裡是指的是全域的設定。
你應噹噹心錯誤是如何被類拋出的,如果你不小心,這可能導致不可預期的副作用。