很早就想寫這篇文章了,但一直沒有時間完成它。不是說我來告訴大家如何做,我更希望本文只是做為一個引子,與大家來討論關於如何建立一個有效地、靈活的網路應用程式。
經過了2-3年的網路應用程式開發工作,我的開發經驗變得更加生動了,回過頭來看我以前為Geocrawler寫的代碼,簡直不敢相信這是我的。由於GPL的原因,在PHPBuilder中的源碼也是良莠不齊的。
最近我做為一個有經驗的PHP開發人員,一直在幫著寫SourceForge,我想這顯示出了最終結果的一個範圍。好的代碼應被分成了多個部分,合適的庫及函數調用,清楚的資料庫結構,網站的每一個部分與其它部分都是相對獨立的。
但是,這仍不是最好的。如果我可以重做,我將更多的關注於HTML層與資料層的分離,通過對象及清楚的函數庫實現這一點。
優美的圖形
我知道經理們喜歡用優美的圖形及圖表來描述它們,這將給我們留下最好的印象。用這種隱藏在一個結構後的想法,你可以把你的邏輯與外觀分離,這意味著任何一個複雜的程式都可以用"API/Data Access Layer"來表述。
與其你把安全檢測、更新的句子等放在HTML層中,不如把它們整體地放在你的API層裡。而這個HTML層只含有簡單的函數調用和返回的數組、對象或自定的其它什麼,以及一些資料庫的檢索結果的集合等。
如果你這樣做了,頂層將是非常的瘦小,你可以方便地建立及維護它。
如下的例子中,這個HTML介面中只有一些API層中的函數的直接調用,一些HTML工具庫(它能產生一個彈出框等等),和一些從資料庫抽象層中調用的資料庫操作方法(你不需要綁定某一個特別的資料庫)。
基礎
靈活的PHP程式結構最基本的方面有以下幾點:
資料庫無關性
介面無關性
可移植性
物件導向或至少應由函數庫組成
還有其它的?
當然還有一些其它的東西,但我認為那都是太大了,或許你自己能指出它們。
讓我們詳細地談談它們每一條吧。
1、資料庫無關性
你從不知道你的網站將會在哪裡運行,當然在你建立它時,你希望它變和得很大並且有很高的流量。所以你不想把你自己約束在 MS Access 上面或者其它什麼輕便的資料庫系統。雖然你不能立刻地插入各種不同的資料庫系統,但是你有可能很方便地在它們中間切換。你有一些不同的選擇可以把你的資料庫調用抽象出來。在PHP中一個奇特的方法是你不得不為每個不同的資料庫系統寫出不同的代碼,因為在PHP中對每一種不同的資料庫的訪問函數是不同的。為了避開這點,你可以使用一個抽象地資料庫訪問層,就象PHPLib、下一個版本的PEAR、及我們在SourceForge中描述的那樣。
2、介面無關性
一個應用程式是它的技術更重要還是它所啟動並執行網站更重要?我們並不能真正地知道。我從來不相信這一點--HTML是一個標準。特別是對於一個網路應用程式而言,介面發生了改動,意味著我們不得不總是重寫。但是如果你的應用程式是很大很複雜的,你就要為你的資料庫建立一些其它的介面了,只要你不想在你的網站程式中到處copy&paste你的訪問檢查等代碼。這也意味著,如果你正確地設計了你的應用程式,你可以很容易地改寫你的網站讓它適應WAP,只要簡單地寫一個小的WAP介面,並讓它調用你的資料庫訪問對象而已。但若你沒有很好地設計你的程式,你把你的HTML版改成WAP版是一個複雜的工程。
我把這個想法也帶入了SourceForge中,我們有一個巨大的使用者群,為我們發送/接收bugs、任務等。首先,我們指出所有的這些將通過我們的web頁面介面,然後,由於Eric Raymond 和其他人給的壓力,我們決定用XML來做資料庫的外部介面。
幸運的是我們曾在四月已把程式的核心邏輯代碼與它的介面分離了。我將試著表達我們是如何做的,希望對你的工作有所協助。
這個SourceForge的bugs跟蹤器和其它的一些工具被分成兩個庫-這個HTML庫和資料訪問庫。這個資料訪問庫檢查輸入的值的正確性,處理安全校正,並且當成功/失敗時返回TRUE 或 FALSE。
由於簡化的原因,這個例子並沒有基於一個完善的對象模式,那樣我還要解釋這個基類和它的一些衍生類等等,我想這個例子將給你一個最普通的想法。
HTML 庫的例子
//connect to database
require ("database.php");
//common utils like header/footer HTML
require ("html.php");
//data access library
require ("bug_data.php");
echo site_header("Page Title");
echo "
Updating A Bug
";
if (bug_data_update($field1,$field2,$field3)) {
echo "
Update Failed!
";
} else {
echo "
Updated Bug Successfully
";
//echo the global error string
echo $feedback;
}
echo site_footer();
?>
Data 訪問庫的例子
3、可移植性
毫無疑問,你不想讓你的代碼只能用於一個固定的網站,將來我們可能改變色彩的選擇、元素的名稱、字型或其它一些什麼,這樣應設定一個config檔案,它被多個頁面所包含。更好的觀點是你的網站被模組化,你不需要copy&paste任何一個HTML檔案,我傾向於把這些放入一個函數,在任何需要的地方調用它們。
同樣的方法可用於資料庫的密碼、資料庫連接字串等,這些可以放入一個資料庫處理的抽象層中。
4、物件導向/函數化
我們不是用COBOL開發,所以這意味著我們可以把進程分成多個函數的調用。每個調用都是一個自動的行為,有時僅僅是調用一小段其它的函數並返回這個結果。
一個好的例子是在每一個頁面校正使用者是否登入,你可以用cookie或查詢資料庫來完成這個功能,但一旦你想改變你的驗證系統,你不得不改動每一個頁面,其實你應該可以通過改動函數庫裡一個普通的函數就完成這個變動的。任何時候,你寫一段代碼,如果它將會被用於多於一個地方,你就要考慮把它放入一個庫裡了。
其它還有什嗎?
顯然還有很多我沒有談到的事,告訴我你的想法,我將在下一篇文章中來討論它們。特別地是,如果你寫了一個大型的、複雜的應用程式,我想聽聽你是如何規劃它的及你重做時不什麼不同的想法。