pear簡介:用pear來寫你的下一個php程式
內容:
什麼是pear
為什麼要使用pear?
pear能為我帶來什麼好處?
pear的編碼規則
開始使用pear
總結
相關資源
作者簡介
潘凡(night sailer) (nightsailer@hothotmail.Lhotmail.com已經是php的老手了,寫了很多非常棒的程式碼。但是,如果你現在要把它們加入到你現在的專案中去,是否有些吃力?你的朋友想使用你的程式碼作為他的專案中的一個模組,但是你發現你們使用了截然不同的編碼風格,讓他適應,甚至不如重寫一個!
請跟我來,使用pear標準編寫你的php程式吧,你的程式將會擁有更大的活力,你的程式和程式碼將會很方便地和其他高手的程式碼融合在一起,pear就像cpan對於perl一樣,會讓php產生更高的能量。
什麼是pear
pear是php擴展與應用程式庫(the php extension and application repository)的縮寫。它是一個php擴展及應用的一個代碼倉庫,簡單地說,pear就是php的cpan。
為什麼要使用pear?
php是一個非常優秀的腳本語言,簡潔、高效,隨著4.0的發布,越來越多的人使用它來進行動態網站的開發,可以說,php已經成為最優秀的internet開發語言之一,尤其對於需要能夠快速、有效率地開發中小規模的商業應用程式的網站開發人員,php是其首選的語言。但隨著php的應用的不斷增多,對於這些應用缺乏統一的標準和有效的管理,因此,php社群很難象perl社群的人們那樣方便的共享彼此的程式碼和應用,因為php缺乏像cpan那樣的統一的程式碼庫來分類管理應用的程式碼模組(熟悉perl的人都知道,cpan是一個巨大的perl的擴展模組倉庫,編寫的應用模組可以放在cpan下面的適當的分類目錄下面,其他的人可以很方便地復用,當然,你編寫應用模組時候也需要遵守其中的準則。
pear能為我帶來什麼好處?
1.如前所述,pear按照一定的分類來管理pear應用程式碼庫,你的pear程式碼可以組織到其中適當的目錄中,其他的人可以方便地檢索並分享到你的成果。
2.pear不僅僅是一個代碼倉庫,它同時也是一個標準,使用這個標準來書寫你的php代碼,將會增強你的程序的可讀性,復用性,減少出錯的幾率。
3.pear透過提供2個類別為你搭建了一個框架,實現了諸如析構函數,錯誤捕獲功能,你透過繼承就可以使用這些功能。
pear的編碼規則
pear的編碼規則包括縮進規則,控制結構,函數調用,函數定義,註釋,包含代碼,php標記,文件頭的註釋塊,cvs標記,url樣例,常量的命名這11方面。以下簡單介紹一下:
縮排規則:
pear中需要使用4個空格來縮排程式碼,且不使用tab。如果你使用vim,將下列設定放入你的~/.vimrc中:
set expandtab
set shiftwidth=4
set tabstop=4
如果,你使用emacs/xemacs,需要把indent-tabs-mode 設定成nil。
不過你像我一樣喜歡用(x)emacs編輯php文件,我強烈建議你安裝php-mode,這樣當你寫pear程式碼的時候,它會自動調整你的縮排風格,當然php-mode還有許多很優秀的特性,你可以從資源清單中的地方下載最新版的php-mode。
控制結構:
if ((條件1) && (條件2)) {
語句1;
}esleif ((條件3) || (條件4)) {
語句2;
}else {
語句3;
}
函數調用:
對於函數調用,函數名和左括號( 之間不應該有空格,對於函數參數,在分隔的逗號和下一個參數之間要有相同的空格分離,最後一個參數和右括號之間不能有空格。 param2,$param3);
此外,如果要將函數的回傳結果賦值,那麼在等號和所賦值的變數之間要有空格,同時,如果是一系列相關的賦值語句,你會加上適當的空格,使它們對齊,就像這樣:
$result1 = $foo($param1, $param2, $param3);
$var2 = $foo($param3);
$var3 = $foo($param4, $param5);
函數定義:
函數定義遵循"one true brace"習俗:
function connect(&$dsn, $persistent = false)
{
if (is_array($dsn)) {
$dsninfo = &$dsn;
} else
} $dsninfo = db::parsedsn($dsn);
}
if (!$dsninfo || !$dsninfo['phptype']) {
return $this->raiseerror();
}
return true;
}
如上所示,可選參數要在參數表的末端,並且總是盡量傳回有意義的函數值。
關於註解:
對於類別的線上文檔,應該能夠被phpdoc轉換,就像javadoc那樣。 phpdoc也是pear的應用程序,更詳細的介紹你可以去http://www.phpdoc.de/查看。除了類別的線上文檔,建議你應該使用非文檔性質的註解來詮釋你的程式碼,當你看到一段程式碼時想:哦,我想不需要在文檔裡去仔細描述它。那麼你最好給這段程式碼作一個簡單的註釋,這樣防止你會忘記它們是如何運作的。對於註解的形式,c的 /* */和c++的//都不錯,不過,不要使用perl或shell的#註解方式。
包含程式碼:
無論什麼時候,當你需要無條件包含進一個class文件,你必須使用requre_once;當你需要條件包含進一個class文件,你必須使用include_once;這樣可以保證你要包含的文件只會包含一次,而這2個語句共用同一個文件列表,所以你無須擔心二者會混淆,一旦require_once 包含了一個文件,include_once不會再重複包含相同的文件,反之亦然。
php程式碼標記:
任何時候都要使用定義你的php程式碼,而不要簡單地使用 ?>,這樣可以保證pear的相容性,也利於跨平台的移植。
文件頭的註解聲明:
所有需要包含在pear核心發布的php程式碼文件,在文件開始的時候,你必須加入以下的註解聲明:
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +---------------------------------------------- ------------------------+
// | php version 4.0 |
// +------------- -------------------------------------------------- -------+
// | copyright (c) 1997, 1998, 1999, 2000, 2001 the php group |
// +----------------- -------------------------------------------------- ---+
// | this source file is subject to version 2.0 of the php license, |
// | that is bundled with this package in the file license, and is |
// | available at through the worldilable- wide-web at |
// |http://www.php.net/license/2_02.txt. |
// | if you did not receive a copy of the php license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// |license@php.netso we can mail you a copy immediately. |
// +------------ -------------------------------------------------- --------+
// | authors: original author |
// | your name |
// +--------------------- -------------------------------------------------+
//
// $id$
對於不在pear核心代碼庫中的文件,建議你也在文件的開始處有這樣一個類似的註釋塊,標明版權,協議,作者等等。同時也在第一行加入vim的modeline,這樣在vim中能夠保持pear的程式碼風格。
cvs標記:
如上面所展示那樣,在每個文件中加入cvs的id標記,如果你編輯或修改的文件中沒有這個標記,那麼請加入,或者是替換原文件中相類似的表現形式(如"last modified"等等)
url樣本:
你可以參考rfc 2606,使用"http://www.example.com"作為所有的url樣本。
常數命名:
常數應該盡量使用大寫,為了方便理解,使用底線分割每個單字。同時,你應該常數所在的包名或是類別名稱作為前綴。例如,對於bug類別中常數應該以bug_開始。以上是pear的編碼規則,詳細的編碼規則可以參考pear中的coding_standdard檔案的說明。為了更好地理解這些編碼規則,你也可以參考一下現有pear核心模組的程式碼。
開始使用pear
pear
使用pear很簡單,你只需這樣定義你自己的pear:
require_once "pear.php";
class your_class_name extends pear{
你的類別定義...
當然,你需要遵守前面說的pear的編碼規則,之後你就可以在你的類別內部實現你要做的事情了。下面,我們展開討論一下,實際上pear為我們提供了2個預定義類:
pear:這是pear的基類,所有的pear擴展都要從它繼承派生出來。
pear_error:pear的錯誤處理的基類,你可以選擇派生出自己的錯誤處理的類別。
一般來說,你不應該直接創建pear的實例,而是要自己派生出一個新的類,然後再創建這個新類的實例。作為基底類,pear給我們提供了一些有用的功能,最主要的就是析構函數和錯誤處理
析構函數
php支援建構函數,但是並不支援析構函數,不過,php提供register_shutdown_function()這個函數,從而能夠在腳本終止前回呼註冊的函數,因此pear利用這個特性,提供了析構函數的模擬。假如你有一個pear的子類,叫做mypear,那麼在mypear類中,你可以定義一個函數,函數名是下劃線加上你的類名,_mypear(),這個函數就是這個類的析構函數。不過這個析構函式和c++中的析構函式不太一樣,它不會在物件被刪除的時候執行,而是在腳本結束的時候,畢竟這只是一個模擬。由於是使用了register_shutdown_function(),所以在你的析構函數裡,列印的資訊將不會回到瀏覽器中。此外,在你的建構子中,需要呼叫它的父類別的建構函數,因為php不會自動呼叫父類別的建構函數,而析構函數需要在pear的建構子中註冊,我們可以看看pear的原始碼:<br>function pear() {<br>if (method_exists($this, "_".get_class($this))) {<br>global $_pear_destructor_object_list;<br> }<br>if ($this->_debug) {<br>printf("pear constructor called, class=%sn",<br> get_class($this));<br>}<br>.....<br>function _pear_call_destructstruct( _pear_destructor_object_list;<br>if (is_array($_pear_destructor_object_list) && sizeof($_pear_destructor_object_list)) {<br>reset($_pear_destructor_object_list); list)) {<br>$destructor = "_ ".get_class($objref);<br>if (method_exists($objref, $destructor)) {<br>$objref->$destructor();<br>}<br>}<br>//已清除已註冊的物件列表,以防止已清除////////呼叫<br>$_pear_destructor_object_list = array();<br>}<br>}<br>....<br>register_shutdown_function("_pear_call_destructors");<br>
構件函數中,將檢查當前類別中是否有析構函數,如果有,那麼將把當前類別的引用放入一個全域列表中,在_pear_call_destructors中,則檢查這個全域列表中的每個元素是否存在相應的析構函數,如果有,則呼叫它,最後將全域列表清空。
在pear.php的最後一行程式碼,則呼叫register_shutdown_function("_pear_call_destructors"),註冊_pear_call_destructors,這樣,當腳本執行完畢的時候,php會回呼這個函式。使用析構函數,你可以在處理完用戶的請求,退出之前做一些必要的"善後"工作,典型的例子是,你可以關閉打開的文件,斷開數據庫的連接,將某些數據存入磁碟等等。
錯誤處理
pear中的錯誤物件的並沒有限定具體的輸出形式,它可以僅僅是捕獲錯誤,不給用戶返回太多的信息,也可以是去回調一個特殊錯誤處理函數,同時,即使輸出錯誤信息,它也強迫你必須要是html形式,你可以輸出xml,csv形式,或者是其他你自己定義的形式,你只需要從pear_error派生一個新的類,然後在適當的時候創建並"拋出"這個新類的對象就可以了。
簡單的錯誤處理:
在pear中,最簡單的錯誤處理是"拋出"這個錯誤,你只要簡單地創建並返回一個pear_error的對象就可以了。以下是一個簡單的範例:<br>function myconnect($host = "localhost", $port = 1080)<br>{<br>$fp = fsockopen($host, $port, $errno, $errstr);<br>if (!is_resource($fp)) {<br>return new pear_error($errstr, $errno);<br>}<br>return $fp;<br>}<br>$sock = myconnect();<br>if (pear}<br>$sock = myconnect();<br>if (peariserror($sock); {<br>print "connect error: ".$sock->getmessage()."<br>n"<br>}<br>
如上面程式碼所顯示的,在執行一段可能產生錯誤的程式碼後,你需要使用pear的iserror來偵測是否有錯誤,並且可以使用pear_error的getmessage來取得最近一次的錯誤訊息。注意:一定要在關鍵的地方使用使用pear::iserror
使用raiseerror
php4.0.5以後,pear多了2個函數:
seterrorhandling($mode, $options = null)
raiseerror($message = null, $ code = null, $mode = null,$options = null, $userinfo = null)
前者可以設定pear缺省的錯誤處理模式,後者是一個包裝函數,傳回一個pear_error的對象,直接建立並傳回pear_error的物件略有不同的是,如果省略$mode,$options等參數,它會使用缺省值來創建這個pear_error的對象,這些缺省值你可以使用seterrorhandling()來定制。
pear_error
pear_error是pear的錯誤物件的一個基類,和pear不同,一般來說,你可以直接建立pear_error的實例,建立方式:
$error = new pear_error($message, $code, $mode, $ options, $userinfo);
$message是你的錯誤訊息,$code是該錯誤的錯誤號碼,後3個參數是緊密聯繫的:
$mode:是這個錯誤的處理模式,可以下列常數:
pear_error_return :僅回傳該錯誤物件(缺省方式)
pear_error_print:在建置函數中列印這個錯誤訊息,但是目前程式會繼續運作。
pear_error_trigger:使用php的trigger_error() 觸發一個錯誤,如果你已經設定了錯誤處理函數,或者你把php的錯誤處理等級設定為e_user_error,那麼目前程式將會被終止。
pear_error_die:列印錯誤並退出,程式終止。
pear_error_callback:使用一個回呼函數或方法來處理目前錯誤,程式終止。
$options:這個參數只有在$mode是pear_error_trigger和pear_error_callback的時候才會起作用,如果是pear_error_trigger,$options必須是e_user_notice, e_user_warning 或 e_user_error這3個常數的一個,同一個常數中的值一致。如果$mode是pear_error_callback,$options可以是一個字串,內容是要回調的函數名,也可以是一個2元素的數組,分別是一個物件變量,和一個字串(標明要呼叫的方法)。
$userinfo:存放附加的使用者資訊,你可以把相關的偵錯資訊放在這裡。
pear_error中有一些常用的方法,這些方法在php文擋沒有描述,這裡一一列出:
int getmode:傳回目前的錯誤處理模式,整型。
string getmessage:傳回目前完整的錯誤訊息,字串。
mixed getcallback:傳回目前的回呼訊息,可能是所回呼的函數名,或是(對象,方法)的陣列。
int getcode:傳回整數的錯誤碼。
string gettype:傳回錯誤的型,也就是目前的類別名,字串。
string getuserinfo:傳回附加的使用者訊息,字串。
string getdebuginfo:內容同上。
string tostring:傳回目前物件的詳細字串描述,內容包括錯誤處理的模式,級別,錯誤訊息,錯誤代碼,相關回調函數等等。
總結
至此,對於pear的介紹就結束了。概括地說,如果你要做一個pear的擴充應用,需要這麼做:
require_once "pear.php"
使用class your_pear_extend extends pear{}定義你的新類別。
在你的類的構造函數中,調用父類pear的構造函數:
function your_pear_extend{
$this->pear();
...
}
如果需要,定義你的析構函數_your_pear_extend
如果需要,從pear_error派生出你自己的錯誤處理類別
設定你的錯誤處理模式,並在適當的時候觸發錯誤。
在執行可能產生錯誤的程式碼後,用pear::iserror($obj)捕捉對應的錯誤。
實現你自己的功能。
在最新的php4.05的pear核心發布裡,已經有不少優秀的應用模組了,例如:phpdoc,cache,html...當然,相對於cpan來說,pear只是剛起步,需要php社群的人們的共同努力,來完善它,增強它,php才會越來越強大。
相關資源
pear主頁
php主頁
phpdoc主頁,可以從你的pear應用程式原始碼產生類似javadoc的api文檔
php-mode for xemacs/emacs,為emacs/xemacs提供支援的語法支持,能夠很好地支持phppear程式碼風格
vim首頁,非常優秀的一個編輯器,對php的支援也很好