對(duì)于一個(gè)開發(fā)人員,文檔總是最感到頭疼的事情之一。而且,很可能你對(duì)待文檔會(huì)采取截然不同的2種態(tài)度:
當(dāng)你使用別人的代碼庫(kù)的時(shí)候,最希望得到的是它的技術(shù)文檔,尤其是當(dāng)時(shí)間很緊,而你又不得不硬著頭皮去讀那些生澀的代碼的時(shí)候。
當(dāng)寫你自己的程序的時(shí)候,最不希望做的事情卻是給它編寫專門的技術(shù)文檔,你會(huì)以種種理由給自己開脫:我的代碼已經(jīng)足夠清晰了,完全不用再為它重新編寫文檔了……
也許是為了緩解這種矛盾,有很多工具可以幫助你,通過從源代碼中抽取相應(yīng)的注釋,可以自動(dòng)生成相應(yīng)的api文檔。java中的javadoc,perl中的pod2man。相比之下,php以前似乎缺乏相應(yīng)的工具,不過,隨著phpdoc的不斷完善,這種局面已經(jīng)大大改觀。
在第一篇pear的編碼規(guī)則中有一條,pear程序中的注釋應(yīng)該能夠被phpdoc轉(zhuǎn)換。由此可見,phpdoc在pear中的作用可不小。今天,我們將詳細(xì)討論phpdoc,這個(gè)優(yōu)秀的pear程序。
1. 什么是phpdoc
PHPDoc是PEAR下面的一個(gè)非常優(yōu)秀的模塊,它的目標(biāo)是實(shí)現(xiàn)類似javadoc的功能,可以為你的代碼快速生成具有相互參照,索引等功能的API文檔。如果你使用過javadoc生成的文檔(如jdk的文檔),你會(huì)非常清楚,如果你沒有用過,那么下面是一個(gè)phpdoc生成它自己的文檔頁面的截圖:
從圖上可以知道,phpdoc生成的文檔和JAVADOC很相似,它有多種的索引方式:
Packageindex:這是按照模塊來索引
Classtree:這是按照你的php類的繼承關(guān)系,可以生成一個(gè)樹狀的索引
Modulegroups:這是按照模塊劃分
Elementlist:這是你的所有元素(類,方法,過程/函數(shù),變量)的字母順序的索引
2. phpdoc的結(jié)構(gòu)及功能
由于phpdoc本身也是符合pear的應(yīng)用程序,我們首先了解一下它的結(jié)構(gòu)。phpdoc是全部采用OOP的思想來編寫的,這也是PEAR所推薦的方式,phpdoc的工作原理:
從設(shè)計(jì)上來說,phpdoc使用了2個(gè)超類:PhpdocObject和PhpdocError。這是整個(gè)PHPDOC的基本類,這種方式也是PEAR所推薦的,也就是說當(dāng)你編寫你自己的應(yīng)用框架的時(shí)候,最好能夠有一個(gè)基本的超類,而其他的子類或者是功能類都有一個(gè)共同的祖先。在掃描源代碼過程中,PHPDOC使用的是類似GREP的形式,并沒有象我們通常想的那樣,使用正則表達(dá)式來實(shí)現(xiàn),根據(jù)作者的解釋,他曾經(jīng)嘗試過使用正則表達(dá)式,但是資源的占用和處理速度都很難令人滿意,因此采用了這種非常規(guī)的形式,具體的實(shí)現(xiàn)有興趣的讀者可以參看源代碼。我認(rèn)為PHPDOC令人滿意的另一方面是其分析結(jié)果是以XML形式保存的,這樣就意味著其他的應(yīng)用程序很容易可以共享這個(gè)數(shù)據(jù),同時(shí)PHPDCO也提供了相應(yīng)的接口,你可以實(shí)現(xiàn)這個(gè)接口,把API文檔生成其他的形式,比如PDF,LATEX,WORD等等。目前,PHPDOC的分析結(jié)果可以以HTML形式表現(xiàn),以后可能會(huì)有更多的形式。即使是HTML形式,由于使用了模板機(jī)制(他使用了PEAR的IT和ITX模塊來實(shí)現(xiàn)),你可以很方便地定制成你自己需要的風(fēng)格,
3. PHPDoc基礎(chǔ)
PHPDoc是從你的源代碼的注釋中生成文檔,因此在給你的程序做注釋的過程,也就是你編制文檔的過程。
從這一點(diǎn)上講,PHPdoc促使你要養(yǎng)成良好的編程習(xí)慣,盡量使用規(guī)范,清晰文字為你的程序做注釋,同時(shí)多多少少也避免了事后編制文檔和文檔的更新不同步的一些問題。
編制符合PHPDoc規(guī)范的注釋是非常重要的,掌握了這一點(diǎn),基本上就可以利用PHPDoc為你工作了。
注釋在PHPDoc中分為文檔注釋和非文檔注釋
3.1 文檔注釋
文檔注釋實(shí)際上是一些特殊形式的多行注釋,一般是放在你需要注釋的特定的關(guān)鍵字(這些關(guān)鍵字是指將會(huì)被phpdoc分析的那些關(guān)鍵字,相關(guān)的關(guān)鍵字列表請(qǐng)參看后面第4節(jié)的說明)前面。下面是一個(gè)文檔注釋的例子:
|
<b>PhpdocObject</b>PhpdocObjectCommon base class of all phpdoc classes<b>private class PhpdocObject </b>Common base class of all phpdoc classesAs a kind of common base class PhpdocObject holdsconfiguration values (e.g. errorhandling) and debuggingmethods (e.g. introspection()). It does not have aconstructor,so you can always inheritig Phpdoc classes from |
3.2 非文檔性注釋
如果你的注釋沒有放在那些phpdoc指定的關(guān)鍵字前面,那么phpdoc認(rèn)為你所作的這些注釋是屬于非文檔注釋,將不會(huì)被phpdoc所分析,也不會(huì)出現(xiàn)在你產(chǎn)生的api文當(dāng)中。
3.3 如何書寫你的文檔性注釋
從3.1 我們可以看到,一個(gè)文檔性的注釋,是由3個(gè)部分組成的,分別是:功能簡(jiǎn)述區(qū),功能詳細(xì)說明區(qū),文檔標(biāo)記區(qū)。
首先,第一行是一個(gè)注釋開始的標(biāo)志"/**",然后是回車,從第2行開始就是功能簡(jiǎn)述區(qū),功能簡(jiǎn)述區(qū)是以縮進(jìn)的"*"開始的,在簡(jiǎn)述的正文和這個(gè)"*"號(hào)之間用空格分隔(注意,在文檔中,都是以*開始,并且這些*保持對(duì)齊的縮進(jìn)格式)。功能簡(jiǎn)述的正文一般是簡(jiǎn)明扼要地說明這個(gè)類,方法或者函數(shù)的功能,功能簡(jiǎn)述的正文在生成的文檔中將顯示在索引區(qū)。
在功能簡(jiǎn)述區(qū)后面是一個(gè)空的注釋行,用來分割簡(jiǎn)述區(qū)和詳細(xì)說明區(qū)。功能詳細(xì)說明區(qū)也是以縮進(jìn)的'*"來引導(dǎo)的,這部分主要是詳細(xì)說明你的API的功能,用途,如果可能,也可以有用法舉例等等。在這部分,你應(yīng)該著重闡明你的API函數(shù)或者方法的通常的用途,用法,并且指明是否是跨平臺(tái)的(如果涉及到),對(duì)于和平臺(tái)相關(guān)的信息,你要和那些通用的信息區(qū)別對(duì)待,通常的做法是另起一行,然后寫出在某個(gè)特定平臺(tái)上的注意事項(xiàng)或者是特別的信息,這些信息應(yīng)該足夠,以便你的讀者能夠編寫相應(yīng)的測(cè)試信息,比如邊界條件,參數(shù)范圍,斷點(diǎn)等等。
在功能詳細(xì)說明區(qū)后面,是空白的注釋行,然后是文檔標(biāo)記區(qū),你可以在這些書寫相關(guān)的文檔標(biāo)記(這些文檔標(biāo)記的用法請(qǐng)參考后面的第4節(jié)),指明一些技術(shù)上的細(xì)節(jié)信息,最主要的是調(diào)用參數(shù)類型,返回值極其類型,繼承關(guān)系,相關(guān)方法/函數(shù)等等。多個(gè)文檔標(biāo)記應(yīng)該使用相同的縮進(jìn),組成一個(gè)"標(biāo)記塊",便于閱讀和分析。
在文檔標(biāo)記區(qū)下面的一行就是注釋結(jié)束行"*/",注意,在注釋結(jié)束標(biāo)記*/后面應(yīng)該直接跟一個(gè)回車,不要另外附加其他的東西,否則可能造成PHPDOC分析出錯(cuò)。
以上就是書寫一個(gè)文檔性注釋的基本方法,下面我們討論一下書寫文檔時(shí)的規(guī)范和技巧。
3.4 文檔書寫指南
在你描述你的代碼的用途或者是功能的時(shí)候,最好能夠遵循大多數(shù)人的習(xí)慣,通俗地講就是"你告訴我的信息正是我想要知道的"。為此,這里將介紹一些書寫文檔注釋的技巧和規(guī)范,希望能夠?qū)δ阌兴鶐椭?
/** * 設(shè)置用戶記錄集 * * @param text 給定的表名 */ function set_user_record($table) { |
你從上面這段注釋中能夠知道什么?因此,這段注釋實(shí)際上是廢話,因?yàn)槟銖暮瘮?shù)名稱上是可以看出的,下面是改進(jìn)后的:
/** * 打開系統(tǒng)用戶表并設(shè)置為當(dāng)前用戶記錄集,此記錄集將用于隨后相關(guān)用戶數(shù)據(jù)更新操作的缺省記錄集。 |
4. PHPDoc關(guān)鍵字及文檔標(biāo)志
4.1 關(guān)鍵字
class 、function 、var 、include (include_once, require, require_once) 、define
在以上這些關(guān)鍵字前面所做的注釋,都被認(rèn)為是文檔性注釋。
4.2 文檔標(biāo)記
說明:使用范圍是指該標(biāo)記可以用來修飾的關(guān)鍵字,或其他文檔標(biāo)記@abstract 使用范圍:class, function, var
說明當(dāng)前類是一個(gè)抽象類。
注釋:從PHP語言角度來說,它并不象JAVA,C++那樣,支持抽象類這個(gè)概念。也沒有相應(yīng)的關(guān)鍵字來修飾某個(gè)類是抽象類。由于PHPDOC實(shí)際上大部分是借鑒了JAVADOC的做法,因此很多文檔標(biāo)記也是直接從JAVADOC中沿襲過來,如abstract,access,final等等。雖然這些特性沒有從語言級(jí)別得到支持,不過從使用者角度來遵循這些特性,仍是值得推薦的。
舉例:
/*** 這是一個(gè)繪五星圖案的抽象類.* @abstract*/class paint_start { /** * 繪制數(shù)量 * @abstract */ var $number; /** * 繪制五星圖案 * @abstract */ function paint() { ; }} |
指明這個(gè)變量、類、函數(shù)/方法的存取權(quán)限。如果你的函數(shù)是內(nèi)部使用,你應(yīng)該指明它為private,這樣的好處是,即使PHP不能阻止其他的人使用你的私有數(shù)據(jù),但是至少你向你的用戶傳達(dá)這樣的信息,這是一個(gè)私有的函數(shù),因此不保證在將來的版本中仍存在;對(duì)于使用者而言,表示為@private的數(shù)據(jù)和方法,你不應(yīng)該直接使用,即使你可以這樣做。
舉例:
/*** 這是一個(gè)繪五星圖案的抽象類.* @abstract* @access public*/class paint_start { /** * 繪制數(shù)量 * @abstract * @access private */ var $number; /** * 繪制五星圖案 * @abstract * @access public */ function paint() { ; }} |
指明作者信息,依次是作者姓名,email地址,其他的通訊信息。如果有多個(gè)作者,按照其先后次序,使用多個(gè)@author依次列出:
指出兄弟類、函數(shù)或者是變量.這些函數(shù)、類、變量等有相似的信息和并實(shí)現(xiàn)相同的功能。比如,調(diào)用和返回的參數(shù)的個(gè)數(shù)和類型相同,實(shí)現(xiàn)的功能也一樣。這種情況,你可以使用@brother 或者 @sister指明它的兄弟函數(shù),無須在重復(fù)書寫函數(shù)的功能等信息了。
舉例:
/*** 這是一個(gè)繪五星圖案的抽象類.* @abstract* @access public*/class paint_start { /** * 繪制數(shù)量 * @abstract * @access private */ var $number; /** * 繪制五星圖案 * @abstract * @access public */ function paint() { ; } /** * @brother paint() */ function draw() { ; }} |
@const[ant] label [description] 使用范圍:define
指明常量
這個(gè)標(biāo)記實(shí)際上是用來說明php的define關(guān)鍵字定義的常量。
@copyright description 使用范圍:class, function, var, module, define, use
指明版權(quán)信息。
@deprec[ated] label 使用范圍:class, function, var, module, define, use
指明不推薦或者是廢棄的信息.
如果你的某個(gè)函數(shù)或者方法,已經(jīng)被新的函數(shù)方法替代,或者是已經(jīng)廢棄,不希望讀者繼續(xù)使用。那么你可以使用這個(gè)標(biāo)志告訴讀者,這個(gè)函數(shù)只是為了保持兼容性而保留的,它不被推薦使用,如果它已經(jīng)被其他函數(shù)替代,也要指出這個(gè)替代者。
例子:
/*** 過時(shí)的類** @deprec 1.5-2000/12/06* @access public*/function dontUseMeAnyMore() { print "Don't use me any more. I have been deprecated.";} |
@exclude label 使用范圍:class, function, var, module, define, use
指明當(dāng)前的注釋將不進(jìn)行分析,不出現(xiàn)在文擋中
@final 使用范圍:class, function, var
指明這是一個(gè)最終的類、方法、屬性,禁止派生、修改。
舉例:
/** * 圓周率 * @final */ var $PI = 3.1415926; |
@global (object objecttype|type) [$varname] [description] 使用范圍:function
指明在此函數(shù)中引用的全局變量
舉例:
/*** Simuliert include_once in PHP 3.** @global array $__used_files 已經(jīng)include的文件列表* @access public*/function include_once($filename) { global $__used_files; if (!isset($__used_files["include_once"][$filename])) { $__used_files["include_once"][$filename] = true; include($filename); }} |
@include description 使用范圍:use
指明包含的文件的信息。
舉例:
/*** 抽象繪圖類的定義.** @includeFunction: _require_*/require("abstract.php"); |
@link URL description 使用范圍:class, function, var, module, define, use
定義在線連接,如上面3.4中講到的,你可以使用@link添加適當(dāng)?shù)脑诰€鏈接。
例如:@link http://www.phpdoc.de/ PHPDoc Home
@magic description
這個(gè)標(biāo)記在phpdoc中沒有說明,具體用法現(xiàn)在仍不清楚
@module label 使用范圍:module
定義歸屬的模塊信息,label是模塊的名字,擁有相同的模塊名字的函數(shù)在索引分類中將被組合在一起。如果你沒有使用OOP的思想來編寫PEAR代碼,那么建議你使用這個(gè)標(biāo)記把相關(guān)的函數(shù)歸集到相應(yīng)的模塊下面,這樣你的整體的框架不至于過于零散和混亂。
@modulegroup label 使用范圍:module
定義歸屬的模塊組 label是這個(gè)模塊組的名字,如果你的應(yīng)用程序的模塊很多,你可以把不同的模塊按照邏輯功能的不同,劃分成相應(yīng)的模塊組,這樣,你的應(yīng)用框架可以有比較清晰的邏輯關(guān)系。這是對(duì)于沒有使用OOP編程的來說的,如果使用OOP的思想,沒有必要使用模塊組的概念,因?yàn)橹苯邮褂?包-超類--基類--子類"的形式來體現(xiàn)你的框架結(jié)構(gòu)要比使用"包-模塊組-模塊"的形式好的多。
@package label 使用范圍:class, module
定義歸屬的包的信息,label 是這個(gè)包的名字。相同的包的名字的類在最終文檔索引中將被分在一起。實(shí)際上,包還可以理解為不同的名字空間,雖然PHP沒有名字空間的概念,但是你可以把相關(guān)的類、模塊都?xì)w屬于同一個(gè)包,這樣,相當(dāng)于組織了一個(gè)名字空間,當(dāng)然,你的應(yīng)用框架可能會(huì)有不同的包,可惜的是,這種情況下從語法上是得不到名字空間這種保證的,你只能通過人為地去避免不同的包的函數(shù)或者類重名。
@param[eter] (object objecttype|type) [$varname] [description] 使用范圍:function
定義函數(shù)或者方法的參數(shù)信息。這是最常使用的文檔標(biāo)記了。
ojecttype 是對(duì)象的類名,type 指出這個(gè)參數(shù)的類型,它可以是下列類型:
* * @param array $tags array of tags returned by getTags * @param array $data array where the allowed tags |
@return (object objecttype|type) [$varname] 使用范圍:function
定義函數(shù)或者方法的返回信息。
返回信息的類型同@param一樣,$varname是返回變量的名稱,可有可無。不同的是@return只有一個(gè),不會(huì)出現(xiàn)多個(gè)@return
@see (function()|$varname|((module|class)::)(function()|$varname)) [, ...] 使用范圍:class, function, var, module, define, use
定義需要參考的函數(shù)、變量,并加入相應(yīng)的超級(jí)連接。這也是較常用的標(biāo)記。對(duì)于相關(guān)的函數(shù),變量,你可以使用@see來增加一個(gè)到相關(guān)函數(shù)和變量的鏈接。多個(gè)相關(guān)的函數(shù)、變量寫在一行,中間用逗號(hào)來分隔。
參考的函數(shù)、變量如果是當(dāng)前類或模塊的,那么你可以直接寫函數(shù)、或者變量的名,如果是函數(shù)那么要在函數(shù)名后面加上括號(hào)(),變量名要加上$。需要注意的,這里所謂的變量名也應(yīng)該是你用@var來說明過的,否則,phpdoc將無法找到相關(guān)的參照而報(bào)錯(cuò)。
如果你想引用其他類或者其他模塊的函數(shù)或者是變量,那么,你可以在函數(shù)名、變量名前面加上類或模塊的名字作為范圍指示,中間用::來分隔。
下面是一些例子:
@see $run_time,$idle_time,$begin_time,$end_time
@see getRuntime(), getIdletime(),getBegintime(),getEndtime()
@see TIME::$run_time, TIME::getBegintime()
@since label 使用范圍: class, function, var, module, define, use
指明該api函數(shù)或者方法是從哪個(gè)版本開始引入的。
@static 使用范圍:class, function, var
指明變量、類、函數(shù)是靜態(tài)的。
@throws exception [, exception] 使用范圍: function
指明此函數(shù)可能拋出的錯(cuò)誤異常,極其發(fā)生的情況
如果你預(yù)料到在這個(gè)函數(shù)中有產(chǎn)生異常的條件,那么你可以使用@throws標(biāo)記來說明這些異常是什么,什么情況下產(chǎn)生異常。比如,讀取磁盤文件出錯(cuò),無法連接數(shù)據(jù)庫(kù),網(wǎng)絡(luò)連接超時(shí)或者是在一些情況下,你"故意"拋出的異常等等。
@todo 使用范圍:class, function, module, use
指明應(yīng)該改進(jìn)或沒有實(shí)現(xiàn)的地方
@var[iable] (object objecttype|type) [$varname] [description] 使用范圍:var
定義說明變量/屬性。
object objecttype|type 定義你的變量的類型,同@param一樣
$varname 該變量的名字,你可以從其他地方使用@see來引用這個(gè)名字
description 對(duì)變量的描述
@version label 使用范圍:class, function, module, use
定義版本信息.
你當(dāng)然可以自己手工寫這些版本信息,不過PEAR推薦你使用CVS的$Id標(biāo)記來自動(dòng)標(biāo)示你的版本信息。形式如下:
@version $Id
這樣,當(dāng)你checkout的時(shí)候,CVS自動(dòng)會(huì)擴(kuò)展成: @version $Id: PhpdocParserCore.php,v 1.4 2001/02/18 14:45:27 uw Exp
5. 生成文檔
5.1 安裝PHPDOC
安裝PHPDOC很簡(jiǎn)單,實(shí)際上因?yàn)樗呀?jīng)隨同PHP 4.05一同發(fā)布了,所以如果你的PHP是4.05,那么在PEAR目錄下面會(huì)發(fā)現(xiàn)PHPDOC這個(gè)模塊.如果你沒有發(fā)現(xiàn),你可以從PHPDOC的CVS獲得一份最新的源碼.
5.2 運(yùn)行PHPDOC
運(yùn)行PHPDOC需要做一些準(zhǔn)備工作,首先要調(diào)整你的PHP.INI的參數(shù),
因?yàn)镻HPDOC運(yùn)行的時(shí)間比一般的PHP應(yīng)用要長(zhǎng),很可能會(huì)超過你在PHP.INI中定義的最大運(yùn)行時(shí)間(缺省是30秒),根據(jù)作者的建議:PIII,60秒,120秒PII,240秒MMX200,480秒如果配置更低的話。如果出現(xiàn)超時(shí),你可以自己適當(dāng)延長(zhǎng)這些數(shù)值。
在php.ini中修改:
;;;;;;;;;;;;;;;;;;;; Resource Limits ;;;;;;;;;;;;;;;;;;;;max_execution_time = 480memory_limit = 8388608 |
如果你不愿意或者沒有修改php.ini的權(quán)限,那么你可以使用set_time_limit()函數(shù)來設(shè)置這個(gè)時(shí)間,使用方法: set_time_limit(480);
設(shè)置從此點(diǎn)開始,運(yùn)行480秒后才超時(shí)。將這個(gè)函數(shù)加在index.php中,就可以和修改php.ini達(dá)到同樣的效果。
其次,你要修改phpdoc目錄下面的index.php文件:
// Directory with include filesdefine("PHPDOC_INCLUDE_DIR", "c:/www/apache/doc/"); |
// Important: set this to the Linebreak sign of your system!
define("LINEBREAK", "/r/n");
下面,為你的要生成文檔的應(yīng)用程序做一些定制工作:
// Sets the name of your application.// The name of the application is used e.g. as a page title$doc->setApplication("PHPDoc");setApplication()用來設(shè)置你的應(yīng)用程序的名稱,將PHPDOC替換成你應(yīng)用程序的名字。// directory where your source files reside:$doc->setSourceDirectory(PHPDOC_INCLUDE_DIR);setSourceDirectory()設(shè)置你的應(yīng)用程序的PHP源文件所在的目錄, |
5.3 實(shí)用工具
通過PHPDOC的INDEX.PHP雖然可以產(chǎn)生文檔,但是畢竟不是那么方便,這里我給出了一個(gè)自己寫的shell程序 makeapidoc ,你可以用它來方便的產(chǎn)生你的API文檔,無須每次都要修改,也不用非要啟動(dòng)瀏覽器來執(zhí)行。
用法如下:makeapidoc -t 你的應(yīng)用程序的標(biāo)題 -s 源程序目錄 -d 生成文檔存放目錄
在使用之前,先修改下面2行:PHPDOC_DIR="/usr/local/lib/php/pear/PHPDoc" # windows: c:/php/pear/PHPDoc
PHPBIN="/usr/local/bin/php" #windows: c:/php/php.exe
PHPDOC_DIR是PHPDOC的目錄,PHPBIN是PHP可執(zhí)行文件的路徑。
這個(gè)程序?qū)嶋H上是把PHP作為一個(gè)SHELLSCRIPT來使用了,不過是嵌在BASH中使用,實(shí)際上PHP完全可以做為普通的SHELL腳本一樣運(yùn)行,只需加上 -q 參數(shù),這樣就不打印HTTP HEADER了。
6. 進(jìn)階:定制輸出的文檔
如果你認(rèn)為缺省的PHPDOC產(chǎn)生的HTML文檔不夠美觀,你想做進(jìn)一步的改進(jìn),比如你想把一些注釋換成中文或者是其他的文字,你想加入你的LOGO,或者是你的聯(lián)系方式,換成一個(gè)漂亮的背景圖案,有沒有方法可以作到?答案是當(dāng)然可以,并且非常簡(jiǎn)單.
PHPDOC在輸出HTML格式的API文檔的時(shí)候,使用的是PEAR的IT,ITX模塊,這是類似PHPLIB的TEMPLETE.CLASS的PEAR模塊,因此,你可以方便地定制和修改缺省的模板來為你所用.
我們先看看PHPDOC/renderer/html/templates: class.html classtree.html elementlist.html frame_packageelementlist.html
frame_packagelist.html module.html modulegroup.html packagelist.html phpdoc.css warnings.html xmlfiles.html
你會(huì)看到上面的這些文件,沒錯(cuò),這些就是PHPDOC用來產(chǎn)生API HTML的模板,現(xiàn)在你可以用你的編輯器來修改這些模板了,這里給出基本的修改原則:
7. 參考資源
作者簡(jiǎn)介 潘凡(Night Sailer):北京賽迪數(shù)據(jù)有限公司工程師。主要從事是數(shù)據(jù)的分析和轉(zhuǎn)換,以及相關(guān)的開發(fā)工作。擅長(zhǎng)使用VB,PERL,PHP進(jìn)行開發(fā)以及Linux的中文化工作。近期興趣是Perl,Php與XML的應(yīng)用,PHP的MVC開發(fā)模式,PERL-GTK的使用。您可以通過 E-mail:[email protected] 跟他聯(lián)系。 |
新聞熱點(diǎn)
疑難解答
網(wǎng)友關(guān)注