細(xì)看PEAR的錯(cuò)誤處理
Jun 21, 2016 am 09:14 AM錯(cuò)誤|錯(cuò)誤處理
PEAR提供了強(qiáng)大的錯(cuò)誤處理機(jī)制。這篇文章向你展示如何從這個(gè)系統(tǒng)中獲益。
許多程序已經(jīng)使用了PEAR的包。許多PHP程序員或多或少的熟悉了PEAR中的錯(cuò)誤處理。但是這個(gè)機(jī)制并不局限于PEAR的包——所有人都能在他們的類和程序中使用這些方法。
這篇文章被分為兩個(gè)部分:首先我們將看看類中用于錯(cuò)誤處理的函數(shù),然后我們將看看如何基于PEAR錯(cuò)誤處理機(jī)制來處理錯(cuò)誤。
我們的例子類稱為cvs2db,它把數(shù)據(jù)從CSV文件插入到數(shù)據(jù)庫的表中。因?yàn)閿?shù)據(jù)可能是手寫的,他們的數(shù)據(jù)應(yīng)該在插入之前先得到驗(yàn)證——落實(shí)postcode。函數(shù)import()完成讀入,檢查和插入的工作;它返回?fù)p壞的記錄數(shù)目。如果返回的值大于0,出錯(cuò)的記錄集能夠使用exportUnvalid()寫入到新的CSV文件中。典型的用法是這樣的:
$cd = new csv2db();
$dsn = 'mysql://root@localhost/csv2db';
if( 0 import("./dat.csv", $dsn, 'address')) {
$cd->exportUnvalid("./dat2.csv");
}
?>
可能的錯(cuò)誤包括:
要導(dǎo)入的CSV文件不存在,
連接到數(shù)據(jù)庫失敗,
記錄集損壞,以及CSV導(dǎo)出文件無法創(chuàng)建。
在提供錯(cuò)誤信息的經(jīng)典解決方案中你可能寫這樣的代碼:
$cd = new csv2db();
$dsn = 'mysql://root@localhost/csv2db';
$result = $cd->import("./dat.csv", $dsn, 'address')
switch($result) {
case FILE_NOT_OPENED:
...
break;
case DATABASE_ERROR:
...
break;
default:
if(0 $cd->exportUnvalid("./dat2.csv");
} else {
echo 'every thing ok!'
}
}
?>
這對(duì)于短的腳本來說是可接受的也是常用的辦法——但是對(duì)于錯(cuò)誤處理經(jīng)常受到關(guān)注的大程序來說不是這樣。傳統(tǒng)的可能性強(qiáng)迫類的作者做最終的決定!在大部分情況下,這個(gè)決定根據(jù)的是那時(shí)對(duì)類的調(diào)用而不是基于長(zhǎng)期的使用和可重用代碼的思想。一個(gè)靈活的錯(cuò)誤處理機(jī)制是可重用代碼的重要部分,PEAR Error API 就是這樣的一種受到良好測(cè)試的機(jī)制。
用戶眼中的類
除了那兩個(gè)函數(shù)之外,類提供了一套錯(cuò)誤處理函數(shù)和一個(gè)自己的錯(cuò)誤對(duì)象稱為DB2CVS_Error,它有一個(gè)特殊的本地化的錯(cuò)誤信息的特性功能。
現(xiàn)在我將向你展示如何在錯(cuò)誤發(fā)生時(shí)控制類的行為。
局部和全局錯(cuò)誤處理
你用setErrorHandling()管理錯(cuò)誤處理;這個(gè)函數(shù)需要兩個(gè)參數(shù):第一個(gè)是錯(cuò)誤模式,而第二個(gè)(可選的)參數(shù)是錯(cuò)誤模式特定的選項(xiàng)。例如 setErrorHandling(PEAR_ERROR_PRINT, 'This error occurred %s') 還有 setErrorHandling(PEAR_ERROR_TRIGGER, E_USER_WARNING)。
這個(gè)函數(shù)的調(diào)用方式是一般行為中最重要的:靜態(tài)還是實(shí)體。在類cvs2db中,我們能兩者都用來設(shè)置錯(cuò)誤處理,所有這些調(diào)用有相同的結(jié)構(gòu)——為類設(shè)置錯(cuò)誤模式:
// per instance
$cd = new csv2db();
$cd->setErrorHandling(PEAR_ERROR_DIE):
// static
CVS2DB::setErrorHandling(PEAR_ERROR_DIE);
PEAR::setErrorHandling(PEAR_ERROR_DIE);
如果兩者給出同樣的結(jié)果,區(qū)別在哪?實(shí)體調(diào)用僅僅為那個(gè)類設(shè)置而靜態(tài)調(diào)用對(duì)于所有使用PEAR_Error或者從那個(gè)類派生的所有類起作用。這個(gè)也作用于第一個(gè)靜態(tài)命令CVS2DB::setErrorHandling(PEAR_ERROR_DIE)——雖然它看上去僅僅影響了cvs2db類。
總結(jié):作為一個(gè)實(shí)體函數(shù)使用命令意味著僅僅為這個(gè)實(shí)體(局部)設(shè)置錯(cuò)誤模式,而作為靜態(tài)函數(shù)來調(diào)用就是為整個(gè)腳本設(shè)置錯(cuò)誤模式(全局)。
setErrorHandling() 和 raiseError()
兩個(gè)函數(shù)都能夠被靜態(tài)調(diào)用和作為實(shí)體的函數(shù)調(diào)用。記住怎樣的一個(gè)組合使得他們?nèi)绾位ハ嘤绊懙暮苤匾?br>
基本上是:setErrorHandling()的靜態(tài)調(diào)用僅僅影響raiseError()的靜態(tài)調(diào)用——setErrorHandling()作為實(shí)體函數(shù)僅僅影響raiseError()作為靜態(tài)函數(shù)調(diào)用。在類csv2db中,使用csv2db::setErrorHandling()來設(shè)置錯(cuò)誤模式是不可行的,因?yàn)槲覀兪褂?this->raiseError(...)。解決這個(gè)聞天有一點(diǎn)小技巧——改寫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,...);
}
這樣,我們映射實(shí)體調(diào)用到靜態(tài)上,如果你用錯(cuò)誤模式調(diào)用raiseError(),然后這個(gè)模式將會(huì)覆蓋這些設(shè)置——這里是指的是全局的設(shè)置。
你應(yīng)當(dāng)當(dāng)心錯(cuò)誤是如何被類拋出的,如果你不小心,這可能導(dǎo)致不可預(yù)期的副作用。
錯(cuò)誤的模式
對(duì)錯(cuò)誤模式的了解對(duì)于使用PEAR的錯(cuò)誤處理來說是重要的。PEAR錯(cuò)誤處理讓用戶能夠決定怎么去做——注意:下文中術(shù)語用戶指的的是實(shí)際使用PEAR_Error程序的開發(fā)者而不是瀏覽腳本結(jié)果或者網(wǎng)頁的用戶。我將詳細(xì)展示可能的錯(cuò)誤模式。
PEAR_ERROR_DIE——將這個(gè)模式開啟,程序?qū)⒔K結(jié)并且將打印錯(cuò)誤信息??蛇x的,你能定義一個(gè)printf()式的字符串,它能夠用于產(chǎn)生信息;首先'%s'在字符串中將替代儲(chǔ)存在錯(cuò)誤對(duì)象中的錯(cuò)誤信息。
PEAR_ERROR_PRINT——僅僅打印錯(cuò)誤信息,包括用于PEAR_ERROR_DIE的同樣的可選用的字符串。
PEAR_ERROR_RETURN——當(dāng)錯(cuò)誤發(fā)生時(shí)的一般行為;你能用類提供isError()函數(shù)或者PEAR::isError()檢查錯(cuò)誤。
$db->setErrorhandling(PEAR_ERROR_RETURN)
if(!csv2db::isError(0 import("./dat.csv", $dsn, 'address'))) {
if(!csv2db::isError($cd->exportUnvalid("./dat2.csv")) {
} else {
// handle error
}
} else {
// handle error
}
PEAR_ERROR_TRIGGER——這兒函數(shù)向PHP運(yùn)行時(shí)錯(cuò)誤行為一樣。你必須定義哪種錯(cuò)誤應(yīng)該發(fā)生:E_USER_NOTICE,E_USER_WARNING或者E_USER_ERROR。他們直接和PHP本身產(chǎn)生的信息相對(duì)應(yīng)。請(qǐng)注意,在錯(cuò)誤信息中錯(cuò)誤發(fā)生的那行(xxx on line yy)指的是在PEAR.php中調(diào)用trigger_error的那行——而不是錯(cuò)誤直接發(fā)生的那行。
PEAR_ERROR_CALLBACK——這是只在一個(gè)地方處理錯(cuò)誤并且讓你得代碼不用考慮錯(cuò)誤處理的最佳方式。它需要一個(gè)函數(shù)或者類函數(shù)來捕獲錯(cuò)誤,你能寫一個(gè)listing 2中展示的那樣的腳本,其中可以看到類相關(guān)錯(cuò)誤對(duì)象的好處:import()函數(shù)拋出一個(gè)CSV2DB_Error給基于CSV的錯(cuò)誤和一個(gè)DB_Error對(duì)象給相關(guān)于數(shù)據(jù)庫訪問的錯(cuò)誤。
Listing 2
$cd = new csv2db();
$cd->setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError');
$dsn = 'mysql://root@localhost/csv2db';
if( 0 import("./dat.csv", $dsn, 'address')) {
$cd->exportUnvalid("./dat2.csv");
}
function handleError($error) {
if(DB::isError($error) {
// handle database error
}
if(csv2db::isError($error) {
switch($error->getCode()) {
case FILE_NOT_OPENED :
...
break;
case CORRUPTED_RECORD :
...
break;
}
}
}
單個(gè)的錯(cuò)誤處理
我們有兩種可能的錯(cuò)誤:我們能夠忽略的錯(cuò)誤(損壞的記錄),以及使得程序無法運(yùn)行的錯(cuò)誤(找不到文件或者打不開數(shù)據(jù)庫)。如果你在shell腳本中使用類,你可以讓腳本終止于第二類錯(cuò)誤。
自然的,你可以寫 $cd->setErrorHandling(PEAR_ERROR_DIE)——但是這可能在如果損壞的記錄錯(cuò)誤發(fā)生時(shí)導(dǎo)致問題。在這樣的情況下你需要對(duì)某個(gè)錯(cuò)誤停用或者替換錯(cuò)誤處理辦法的可能。解決辦法時(shí)expectError(),如果你傳遞一個(gè)錯(cuò)誤代碼給這個(gè)函數(shù),指定錯(cuò)誤的錯(cuò)誤模式將被單獨(dú)于缺省錯(cuò)誤模式地設(shè)置為PEAR_ERROR_RETURN。
expectError()函數(shù)把傳遞來的錯(cuò)誤代碼儲(chǔ)存在棧中,使用popExpected()移出最后傳遞的錯(cuò)誤代碼。自從PHP 4.3之后你還能使用delExpect()了;這個(gè)函數(shù)從棧中刪除了指定錯(cuò)誤代碼的匹配,你不需要關(guān)心位置了。
在實(shí)際使用中,是這樣的:
$cd->setErrorHandling(PEAR_ERROR_DIE);
...
$cd->expectError(CORRUPTED_RECORD);
$cd->import(...);
$cd->popExpect();
pushErrorHandling() 和 popErrorHandling() 用起來差不多;他們能夠暫時(shí)的控制錯(cuò)誤處理。例如:如果在 exportUnvalid() 中的文件不能打開,你想要忽略錯(cuò)誤:
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$cd->exportUnvalid("./dat2.csv");
PEAR::popErrorHandling();
注意調(diào)用方法的區(qū)別!expectError()/popExpect()必須作為實(shí)體函數(shù)來調(diào)用——pushErrorHandling和popErrorHandling可以靜態(tài)調(diào)用。如果作為實(shí)體函數(shù),那么他們僅僅影響那個(gè)實(shí)體。
用戶有很多可能性,這是否又意味著程序員要做很多的工作呢?是,是因?yàn)槟阋萺eturn false做更多的事情;否,是因?yàn)镻EAR Error API給你完成了很多工作。
一些關(guān)于錯(cuò)誤處理的思考
作為好的程序員,你不應(yīng)該從你的類的用戶眼中遮掩起確切的錯(cuò)誤原因。這阻止了簡(jiǎn)單的return false的用法;還要注意也可能被PHP自動(dòng)型別轉(zhuǎn)換為0——這對(duì)于import()函數(shù)來說意味著所有的記錄都已經(jīng)被正確插入了!簡(jiǎn)單地終止腳本?,可能對(duì)于簡(jiǎn)單地PHP shell腳本來說這是可以接受地,但是對(duì)于一個(gè)web程序來說是一個(gè)壞的選擇!而且,在記錄損壞的情況,錯(cuò)誤是能夠被忽略的。什么不trigger_error()?這是一個(gè)可能的選擇,但是有兩個(gè)缺點(diǎn):類的行為取決于php.ini的設(shè)置,而且對(duì)于類來說這種行為不常見??赡苄阅軌蛐枰妙~外的函數(shù)找出錯(cuò)誤狀態(tài)。即使是所有類都提供了非標(biāo)準(zhǔn)的函數(shù)名,這還是有問題的,而且類的用戶看上去會(huì)忘記那樣的函數(shù)調(diào)用——正如郵件列表和新聞組中顯示的那樣。怎么辦?讓用戶決定PEAR錯(cuò)誤處理API。PEAR錯(cuò)誤系統(tǒng)被廣泛知道并且許多類已經(jīng)使用了PEAR類;因而我們無論如何必須用PEAR錯(cuò)誤處理機(jī)制——為什么不建立在其上呢?這避免了前面提到的問題并且給用戶提供了很大的可能性??纯碙isting 1,它展示了csv2db類和它的錯(cuò)誤對(duì)象的實(shí)現(xiàn)。它可能是有些讓人嚇到,但是我們將一行行地瀏覽源代碼。
Listing 1
require_once 'PEAR.php';
require_once 'DB.php';
define("FILE_NOT_OPENED", 10);
define("CORRUPTED_RECORD", 20);
class csv2db extends PEAR{
var $records=array();
var $unvalid=array();
function csv2db() {
$this->PEAR("CSV2DB_Error");
}
function import($file, $dsn, $table) {
$this->PEAR("CSV2DB_Error");
if($fp=@fopen($file, 'r')) {
while($data=fgetcsv($fp, 1024,';')) {
$this->records[]=$data;
}
fclose($fp);
} else {
return $this->raiseError(null, FILE_NOT_OPENED);
}
$unvalidCount=0;
$storeMode = $GLOBALS['_PEAR_default_error_mode'];
$storeOpts = $GLOBALS['_PEAR_default_error_options'];
$GLOBALS['_PEAR_default_error_mode'] = $this->_default_error_mode;
$GLOBALS['_PEAR_default_error_options'] = $this->_default_error_options;
$db = DB::connect($dsn);
$GLOBALS['_PEAR_default_error_mode']= $storeMode;
$GLOBALS['_PEAR_default_error_options'] = $storeOpts;
if(!DB::isError($db)) {
$db->setErrorHandling($this->_default_error_mode,
$this->_default_error_options);
$qp = $db->prepare("INSERT INTO $table VALUES (?, ?, ?, ?)");
foreach( $this->records as $record) {
if(preg_match('/d{5}/',$record[2])) {
$db->execute($qp, $record);
} else {
$unvalidCount++;
$this->unvalid[]=$record;
$this->raiseError(corrupted record, CORRUPTED_RECORD);
}
}
$db->disconnect();
} else {
return $db;
}
return $unvalidCount;
}
function exportUnvalid($file) {
if($fp=@fopen($file, "w")) {
foreach($this->unvalid as $data) {
fwrite($fp, implode(';', $data)."n", 1024);
}
fclose($fp);
} else {
return $this->raiseError(null,FILE_NOT_OPENED);
}
}
function isError($data) {
return (bool)(is_object($data) &&
(get_class($data) == 'CSV2DB_Error' ||
is_subclass_of($data, 'CSV2DB_Error')));
}
}
class CSV2DB_Error extends PEAR_Error {
var $msgs = array(
FILE_NOT_OPENED =>
array( 'de' =>"Datei konnte nicht ge?ffnet werden",
'en' => "File couldn't be opened"),
CORRUPTED_RECORD =>
array( 'de' =>"fehlerhafter Datensatz",
'en' => "corrupted record")
);
function CSV2DB_Error($message=null, $code = null, $mode = null,
$level = null, $debuginfo = null) {
$this->PEAR_Error(null, $code, $mode, $level, $debuginfo);
}
function getMessage($lang = "en") {
return $this->msgs[$this->code][$lang];
}
}
?>
自己的錯(cuò)誤對(duì)象
有一個(gè)自己的錯(cuò)誤類總是好的,雖然它可能對(duì)于這么一個(gè)小的類來說是太大的額外負(fù)擔(dān)——但是這個(gè)類僅僅是一個(gè)例子并且你從如果沒有錯(cuò)誤對(duì)象需要很多代碼來實(shí)現(xiàn)的特性那兒獲益良多。好處是:首先錯(cuò)誤是直接賦給類的;以及本地化變得更加容易。
類必須從PEAR_Error繼承而來,為的是保持我們的實(shí)現(xiàn)簡(jiǎn)單,否則PEAR::isError()將不能正常工作。
實(shí)現(xiàn)包含了構(gòu)造函數(shù),其中沒有改變地把參數(shù)傳遞給了PEAR_Error地構(gòu)造函數(shù)。
改寫getMessage()函數(shù)是提供本地化錯(cuò)誤信息地關(guān)鍵。錯(cuò)誤定西被定義為類的變量并且將取決于語言動(dòng)態(tài)的賦值。這也將幫助消息聚集于一處——而不是把他們分散于整個(gè)主要類的源代碼中。
實(shí)現(xiàn)PEAR錯(cuò)誤處理
你在文章的第一部分看到了我們的類提供了一堆函數(shù)——但是他們中的僅僅有四個(gè)是直接實(shí)現(xiàn)的。所有的相關(guān)函數(shù)的錯(cuò)誤處理是由PEAR基類提供的。為了從所有那些錯(cuò)誤處理特性中獲益,我們必須讓cvs2db類從PEAR基類繼承,也就是:class csv2db extends PEAR。
在前面的錯(cuò)誤對(duì)象段落中,我從對(duì)isError()的解釋開始。覆蓋這個(gè)方法不是必要的,雖然它確實(shí)使得我們能夠直接檢查我們的錯(cuò)誤類,并且使得錯(cuò)誤跟蹤更加精確并且可能節(jié)約了幾毫秒。
類的構(gòu)造函數(shù)僅僅只是用錯(cuò)誤類名稱最為參數(shù)調(diào)用了父類的構(gòu)造函數(shù)。這個(gè)調(diào)用注冊(cè)了我們的錯(cuò)誤對(duì)象并且確保了我們的錯(cuò)誤類在每次觸發(fā)錯(cuò)誤的時(shí)候被使用。
raiseError
在import()和exportUnvalid()的函數(shù)體中對(duì)raiseError()的使用是值得注意的。這是創(chuàng)建錯(cuò)誤的關(guān)鍵函數(shù);PEAR提供兩個(gè)函數(shù)用于這個(gè)目的:raiseError() 和 throwError()。后一個(gè)自從PHP 4.3開始存活在并且是raiseError()的一個(gè)簡(jiǎn)化變體,兩者行為是一致的;它們的參數(shù)在段落 'raiseError 和 throwError' 中描述。
raiseError 和 throwError
原型:
&raiseError( $message, $code, $mode, $options, $userinfo, $errorclass, $skipmessage)
&throwError( $message, $code, $userinfo)
Parameter Description
$message (string) The error message
$code (int) The error number
$mode (constant) Error mode
$options (mixed) Error mode specific parameters
$userinfo (mixed) additional data (ie. Debug information)
$errorclass (string) A class name
可選的你能夠把已經(jīng)存在的錯(cuò)誤對(duì)象傳遞給這些函數(shù):
&raiseError($error_object)
&throwError($error_object)
如果你從源代碼比較這兩個(gè)函數(shù)的參數(shù)表你將看到類并沒有設(shè)置message參數(shù)——這是不必須的因?yàn)槲覀冊(cè)阱e(cuò)誤類中用 getMessage() 函數(shù)賦給錯(cuò)誤信息。而且,調(diào)用PEAR構(gòu)造函數(shù)來引入你的錯(cuò)誤類也是不必要的,你可以在對(duì) raiseError() 調(diào)用中指定錯(cuò)誤類。在腦子中記住這個(gè)選項(xiàng)!例如,如果你的類提供了靜態(tài)函數(shù)或者多于一個(gè)錯(cuò)誤對(duì)象,你不能給你的類像我們?cè)赾sv2db中做得那樣全局地設(shè)置它們。
raiseError() 和 throwError() 能夠被靜態(tài)地調(diào)用以及像 setErrorHandling() 那樣作為實(shí)體函數(shù)來調(diào)用。當(dāng)你作不作靜態(tài)調(diào)用地時(shí)候做正確地決定是重要的——它直接影響了用戶如何用setErrorHandling()來錯(cuò)作我們的類。留意 setErrorHandling() 和 raiseError(),這將避免你和你的用戶的頭疼。
從類的這個(gè)部分能夠看到全局和局部的錯(cuò)誤設(shè)置和觸發(fā)的負(fù)面影響。
$storeMode = $GLOBALS['_PEAR_default_error_mode'];
$storeOpts = $GLOBALS['_PEAR_default_error_options'];
$GLOBALS['_PEAR_default_error_mode'] = $this->_default_error_mode;
$GLOBALS['_PEAR_default_error_options'] = $this->_default_error_options;
$db = DB::connect($dsn);
$GLOBALS['_PEAR_default_error_mode'] = $storeMode;
$GLOBALS['_PEAR_default_error_options'] = $storeOpts;
首先,全局的錯(cuò)誤模式被保存了,然后全局的錯(cuò)誤模式設(shè)置給了局部的錯(cuò)誤模式并且最后幾行,原來的錯(cuò)誤模式被還原了。為什么?Connect()是一個(gè)靜態(tài)函數(shù)!它必須使用PEAR::raiseError()。因而假如我們不保存并且還原設(shè)置,我們會(huì)遇到問題:看看listing 3——如果類在import()函數(shù)不能連接到數(shù)據(jù)庫的時(shí)候會(huì)發(fā)生什么?因?yàn)閷?duì)raiseError()的靜態(tài)調(diào)用受到全局錯(cuò)誤模式的影響,而不是局部的$cd->setErrorHandling(...)的影響,腳本終止執(zhí)行 。實(shí)際上push和popErrorHandling()就是設(shè)計(jì)來用于這樣的任務(wù)的——但是PHP中一個(gè)現(xiàn)下的bug看上去不幸的組織了它很好的工作。
強(qiáng)制$db對(duì)象使用我們的錯(cuò)誤模式是更舒服的方式,它支持完整的PEAR Error API,這使得代碼能這樣寫:$db->setErrorHandling($this->_default_error_mode, $this->_default_error_options)。兩個(gè)實(shí)體變量都是由PEAR_Error類提供的。
那行$this->raiseError(corrupted record, CORRUPTED_RECORD)看上去值得注意——而且缺失的返回看上去不順眼。原因是:我們不想在發(fā)現(xiàn)損壞的記錄時(shí)中止函數(shù)執(zhí)行。你能把這個(gè)和觸發(fā)一個(gè)警告進(jìn)行比照。唯一的限制時(shí)模式PEAR_ERROR_RETURN沒有工作。
Listing 3
...
PEAR::setErrorHandling(PEAR_ERROR_DIE)
$cd = new csv2db();
$cd->setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError');
$dsn = 'mysql://root@localhost/csv2db';
if( 0 import("./dat.csv", $dsn, 'address')) {
$cd->exportUnvalid("./dat2.csv");
}
$db = DB::connect($dsn);
$db->query(...);
...
function handleError($error) {
if(DB::isError($error) {
// handle database error
}
if(csv2db::isError($error) {
switch($error->getCode()) {
case FILE_NOT_OPENED :
...
break;
case CORRUPTED_RECORD :
...
break;
}
}
}
?>
PEAR錯(cuò)誤處理和PHP 5
因?yàn)槲覀兪褂煤瘮?shù)來創(chuàng)建錯(cuò)誤,我們沒有考慮在PHP 5中的try/catch/throw機(jī)制;raiseMethod和throwError將為你完成這些!對(duì)于PHP 5,函數(shù)能夠?yàn)槟愕念愅该鞯卣{(diào)用拋出PEAR_Error()——錯(cuò)誤模式PEAR_ERROR_EXCEPTION能夠用于這個(gè)目的。一下的代碼應(yīng)該能夠在不改變類的情況下用于PHP5中:
$i = new csv2db();
$dsn = 'mysql://root@localhost/csv2db';
try {
if( 0 import("./dat.csv", $dsn, 'address')) {
$i->exportUnvalid("./dat2.csv");
}
}
catch CSV2DB_Error {
// fetch the error
}
?>
結(jié)論
我希望你大概了解了PEAR錯(cuò)誤處理,它提供了排除和處理錯(cuò)誤的強(qiáng)大機(jī)制。看看PEAR手冊(cè)[1]的代碼部分并且找出這些函數(shù)提供的好處。
Alexander Merz (alexmerz at php dot net) 是PEAR手冊(cè)的編輯并且以自由創(chuàng)作者和作家為職業(yè)。

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Solution to "0271: real time clock error" that cannot boot: 1. Press F1, and in the interface that appears, move the option bar to the third item "Date/Time"; 2. Manually change the system time to the current one time; 3. Press F10 and select yes in the pop-up dialog box; 4. Re-open the notebook to boot normally.

Solve the "error:incompletetypeisnotallowed" problem in C++ code. During the C++ programming process, you sometimes encounter some compilation errors. One of the common errors is "error:incompletetypeisnotallowed". This error is usually caused by operating on an incomplete type. This article will explain the cause of this error and provide several solutions. firstly, I

PHP is a popular web development language that has been used for a long time. The PDO (PHP Data Object) class integrated in PHP is a common way for us to interact with the database during the development of web applications. However, a problem that some PHP developers often encounter is that when using the PDO class to interact with the database, they receive an error like this: PHPFatalerror:CalltoundefinedmethodPDO::prep

It is very common to use axios in Vue applications. axios is a Promise-based HTTP client that can be used in browsers and Node.js. During the development process, the error message "Uncaught(inpromise)Error: Requestfailedwithstatuscode500" sometimes appears. For developers, this error message may be difficult to understand and solve. This article will explore this

Solve the "error:expectedinitializerbefore'datatype'" problem in C++ code. In C++ programming, sometimes we encounter some compilation errors when writing code. One of the common errors is "error:expectedinitializerbefore'datatype'". This error usually occurs in a variable declaration or function definition and may cause the program to fail to compile correctly or

When writing web applications using PHP, a MySQL database is often used to store data. PHP provides a way to interact with the MySQL database called MySQLi. However, sometimes when using MySQLi, you will encounter an error message, as shown below: PHPFatalerror:Calltoundefinedfunctionmysqli_connect() This error message means that PHP cannot find my

How to solve PHPWarning:fopen():failedtoopenstream:Nosuchfileordirectory In the process of using PHP development, we often encounter some file operation problems, one of which is "PHPWarning:fopen():failedtoopenstream:Nosuchfileordirectory"

When using PHP for web application development, you will often need to use a database. When using a database, error messages are very common. Among them, PHPFatalerror: Calltoamemberfunctionfetch() is a relatively common error that occurs when using PDO to query the database. So, what causes this error and how to solve it? This article will explain it in detail for you. 1. Cause of error
