|
在PHP的論壇中總是聽到有人對(duì)PHP的OOP支持說(shuō)三道四的,說(shuō)這有缺陷,那里不足,但是都拿不出實(shí)際的例子。原來(lái)說(shuō)過(guò)要和大家說(shuō)說(shuō)這事,但是一直很忙,現(xiàn)在算是抽了些時(shí)間了,所以把我剛剛做過(guò)的一個(gè)項(xiàng)目的框架拿出來(lái)和大家探討一下。這個(gè)項(xiàng)目99%的代碼是用oop方式編寫的,感覺PHP對(duì)于OOP支持非常好,不是一般的好,是非常的好。有由于項(xiàng)目本身是一個(gè)商業(yè)項(xiàng)目所以源代碼不好公布出來(lái),但是基本框架還是可以說(shuō)一說(shuō)的,而且經(jīng)過(guò)簡(jiǎn)化的例子更容易理解一些。如果你對(duì)PHP中的OOP還不太了解,還是就此打住吧,先去看看手冊(cè),或者基礎(chǔ)讀物再來(lái)看也不遲,反正這個(gè)是貼子沒有長(zhǎng)腿也跑不了。 長(zhǎng)話短說(shuō),立刻開始吧。我這里會(huì)用到一個(gè)簡(jiǎn)單的例子,只有一個(gè)半的功能。一個(gè)是向?yàn)g覽器發(fā)送一句"Hello, I can say OOP in PHP world!",另外半個(gè)功能是從數(shù)據(jù)庫(kù)中進(jìn)行一個(gè)查詢?nèi)缓筝敵龅綖g覽器,說(shuō)它是半個(gè)功能是因?yàn)橹皇亲鳛橐粋€(gè)例子講講沒有實(shí)際的數(shù)據(jù)庫(kù)操作。 首先從我的第一個(gè)文件index.php 開始介紹吧。我的index.php文件是這樣的: <?php include_once ('config.php'); include_once ('class.Application.php'); $app = & new Application(); $app->;run(); ?>; 這個(gè)就是全部了,雖然只有4行,但是如果用OOP的方式寫這個(gè)應(yīng)該就夠了吧。 有一點(diǎn)經(jīng)驗(yàn)的哥們會(huì)發(fā)現(xiàn)這里只用到了一個(gè)Application 對(duì)象,那么一定很想知道這個(gè)對(duì)象究竟長(zhǎng)什么樣呢,我們繼續(xù)看看class.Application.php 這個(gè)文件的內(nèi)部。從以上的代碼中我們知道她應(yīng)該至少包含兩個(gè)方法 Application() 和 run() 所以大體上應(yīng)該長(zhǎng)成這樣 <?php class Application { function Application() { } function run() { } } ?>; 現(xiàn)在就算知道Application 是什么樣,它好像也沒有辦法完成我們預(yù)先設(shè)定的功能呀, 所以還要介紹一下如何運(yùn)行這個(gè)程序,在我的結(jié)構(gòu)中所有的頁(yè)面都是通過(guò)index.php和一個(gè)action參數(shù)進(jìn)行訪問的例如第一個(gè)功能應(yīng)該這樣訪問index.php?action=HelloPage,而第二個(gè)功能則是通過(guò)index.php?action=DatabasePage進(jìn)行訪問。這樣的結(jié)構(gòu)大家也許并不陌生吧。所以index.php 頁(yè)面應(yīng)當(dāng)知道傳進(jìn)來(lái)的 action 參數(shù)是什么,也就是說(shuō)Application對(duì)象應(yīng)當(dāng)知道 這個(gè)action 參數(shù)是什么。所以我們需要給Application增加一個(gè)方法 getAction()來(lái)獲得action參數(shù)。既然知道action,知道了要做什么,那么方法 run()也就有知道如何去run了。 同時(shí)我還可以把(完成功能的)每一個(gè)頁(yè)面作為一個(gè)對(duì)象來(lái)看待,所以我應(yīng)該至少還需要兩個(gè)類 class HelloPage 和 class DatabasePage 由于這兩個(gè)對(duì)象最終都是向?yàn)g覽器發(fā)送頁(yè)面所以把他們共同的部分提出來(lái)作為他們的父類 class Page 以下是三個(gè)類文件的內(nèi)容 class.Page.php <?php class Page { function Page() { } function show() { //不能直接調(diào)用這個(gè)方法一定要在子類中去具體實(shí)現(xiàn)。 die('You can not use this funciton directly from Page class'); } } ?>; 其中這個(gè)show方法應(yīng)該是所有頁(yè)面對(duì)象都具有的方法,只是在實(shí)現(xiàn)上有所不同。 class.HelloPage.php <?php require_once ("class.Page.php"); class HelloPage extends Page { function HelloPage() { parent::Page(); } function show() { echo "Hello, I can say OOP in PHP world!"; } } ?>; class.DatabasePage.php <?php require_once ("class.Page.php"); class DatabasePage extends Page { function DatabasePage() { parent::Page(); } function show() { //做一些數(shù)據(jù)庫(kù)操作然后將結(jié)果顯示出來(lái)。 } } ?>; 同時(shí)我們還遵守這樣的一條規(guī)則:action的值和調(diào)用的頁(yè)面類的名稱保持一致,例如當(dāng)action=HelloPage的時(shí)候程序就知道需要初始化一個(gè)HelloPage的對(duì)象,有了這樣的規(guī)則和以上的幾個(gè)文件我們就可以將 Application 類改進(jìn)成這樣。 <?php class Application { function Application() { } function getAction() { } function run() { $pageClass = $this->;getAction(); include_once ("class.".$pageClass.".php"); $page = & new $pageClass(); $page->;show(); } } ?>; 為什么getAction()空著,因?yàn)樗?jiǎn)單了,你自己可以輕松地把它寫出來(lái)呀。 看到這里,如果你還不太明白,不用急,可以停下來(lái)重新再看一遍。 如果全明白了,我們就繼續(xù)前進(jìn)。我們還有半個(gè)任務(wù)沒有完成,所以我們需要改進(jìn)我們的Application和頁(yè)面類,讓它完成數(shù)據(jù)庫(kù)操作功能。 進(jìn)行數(shù)據(jù)庫(kù)操作之前首先應(yīng)當(dāng)?shù)玫揭粋€(gè)正確的數(shù)據(jù)庫(kù)連接,如果讓每個(gè)需要數(shù)據(jù)庫(kù)連接的頁(yè)面類去做這樣的工作實(shí)在是一件非常費(fèi)時(shí)費(fèi)力的工作,不容易維護(hù)管理而且也破壞了oop的設(shè)計(jì)初衷,進(jìn)行數(shù)據(jù)庫(kù)操作的頁(yè)面類例如 DatabasePage 只應(yīng)當(dāng)完成它份內(nèi)工作即獲得數(shù)據(jù)。 仔細(xì)看看我們的設(shè)計(jì)不難發(fā)現(xiàn)建立數(shù)據(jù)庫(kù)連接的工作交給 Application 來(lái)做最合適不過(guò)了, 所以給Application 增加一個(gè)新的成員 $db 并且在初始化的時(shí)候?qū)⒔⒌臄?shù)據(jù)庫(kù)連接賦值給它。 <?php require_once ("class.Database.php"); class Application { var $db;//數(shù)據(jù)庫(kù)對(duì)象 function Application() { $this->;db = & new Database(DB_HOST,DB_NAME,DB_LOGIN,DB_PASS);//$db 現(xiàn)在是一個(gè)數(shù)據(jù)庫(kù)對(duì)象了 } function getAction() { return $_GET['action']; //簡(jiǎn)單的實(shí)現(xiàn) getAction; } funciton & getDatabase() { return $this->;db; } function run() { $pageClass = $this->;getAction(); include_once ("class.".$pageClass.".php"); $page = & new $pageClass($this); //這里是唯一做了手腳的地方,將這個(gè)Application對(duì)象傳給頁(yè)面對(duì)象。 $page->;show(); } } ?>; 你現(xiàn)在不用太關(guān)心這個(gè) Database對(duì)象從何而來(lái)如何實(shí)現(xiàn),知道它是一個(gè)含有數(shù)據(jù)庫(kù)連接的對(duì)象就可以了,如果用過(guò)phplib, ADODB,或者Pear庫(kù)的就很容易理解。 這個(gè)語(yǔ)句: $this->; db = & new Database(DB_HOST,DB_NAME,DB_LOGIN,DB_PASS); 就是建立一個(gè)數(shù)據(jù)庫(kù)連接而已。 至于DB_HOST,DB_NAME,DB_LOGIN,DB_PASS 這些都是常量我們?cè)赾onfig.php中已經(jīng)預(yù)先設(shè)定。 由于數(shù)據(jù)庫(kù)操作頁(yè)面 DatabasePage 需要進(jìn)行數(shù)據(jù)庫(kù)連接所以它也需要一個(gè)變量 $db 來(lái)保存數(shù)據(jù)庫(kù)對(duì)象,所以我們需要把DatabasePage改進(jìn)成這樣: class.DatabasePage.php <?php require_once ("class.Page.php"); class DatabasePage extends Page { var $db; function DatabasePage(&$app)//將Application對(duì)象作為參數(shù)接受。 { parent::Page(); $this->;db = $app->;getDatabase();//獲得 Application 中的數(shù)據(jù)庫(kù)對(duì)象。 } function show() { $sql = 'SELECT * FROM sale_orders';//簡(jiǎn)單的一個(gè) SQL 例子。 $results = $this->;db->;query($sql);//query 是 Database對(duì)象的一個(gè)公共的方法,通過(guò)它向數(shù)據(jù)庫(kù)提交SQL查詢。 ...;//做一些操作把得到的結(jié)果顯示出來(lái)。 } } ?>;
信息發(fā)布:廣州名易軟件有限公司 http://www.jetlc.com
|