雖然名字叫《PHP最佳實踐》,但是它主要談的不是編程規則,而是PHP應用程序的合理架構。
它提供了一種邏輯和數據分離的架構模式,屬於MVC模式的一種實踐。我覺得,這是很有參考價值的學習資料,類似的文章網上並不多,所以一邊學習,一邊就把它翻譯了出來。
根據自己的理解,我總結了它的MVC模式的實現方式(詳細解釋見譯文):
* 視圖層(View):前端網頁;
* 邏輯層(Controller):先是頁邏輯(Page Controller),負責處理頁面請求;然後,調用業務邏輯(Business Controller),實現具體功能;
* 數據層(Model):數據保存在數據庫之中,上面有一個數據庫抽象層,再上面則是一個"數據訪問對象"(DAO),它生成"值對象"(Value Object)。業務邏輯通過DAO,操作值對象。
=======================================
PHP最佳實踐
原載:http://www.odi.ch/prog/design/php/guide.php
譯者:阮一峰
本文給出了PHP程序設計常見問題的解決方法,同時簡單描述了PHP應用程序的架構。
1. php.ini設置
php.ini控制了解釋器的行為,下面的一些設置保證了你的程序有最大的可移植性。
i. short_open_tag
設為0,即永遠使用PHP的長標簽形式:,不用短標簽形式。
ii. asp_tags
設為0,不使用ASP標簽。
iii. magic_quotes_gpc
建議在腳本中包含一個全局文件,負責在讀取$_GET、$_POST、$_COOKIE變量之前,首先檢查這個設置是否打開,如果打開了,這對這些變量應用stripslashes函數。(注:該設置已經在PHP 5.3中被廢除。)
iv. register_globals
不要依賴這個設置,永遠通過全局變量$_GET、$_POST、$_COOKIE去讀取GET、POST和COOKIE的值。為了方便起見,建議聲明$PHP_SELF = $_SERVER[PHP_SELF]。
v. file_uploads
上傳文件的最大大小,由下面的設置決定:
* file_uploads必須設為1(默認值),表示允許上傳。
* memory_limit必須略大於post_max_size和upload_max_filesize。
* post_max_size和upload_max_filesize要足夠大,能滿足上傳的需要。
2. 配置文件(configuration file)
你應該把與應用程序相關的所有配置,寫在一個文件裡。這樣你就能很方便地適應開發環境的變化。配置文件通常包含以下信息:數據庫參數、email地址、各類選項、debug和logging輸出開關、應用程序常數。
3. 名稱空間(namespace)
選擇類和函數名的時候,必須很小心,避免出現重名。盡可能不要在類以外,放置全局性函數,類對內部的屬性和方法,相當於有一層名稱空間保護。如果你確實有必要聲明全局性函數,那麼使用一個前綴,比如dao_factory()、 db_getConnection()、text_parseDate()等等。
4. 數據庫抽象層
PHP不提供數據庫操作的通用函數,每種數據庫都有一套自己的函數。你不應該直接使用這些函數,否則一旦改用其他數據庫(比如從MySQL 轉為Oracle),你就有大麻煩了。而且,數據庫抽象層通常比系統本身的數據庫函數,更易用一些。
5. "值對象"(Value Object, VO)
值對象(VO)在形式上,就像C語言的struct結構。它是一個只包含屬性、不包含任何方法(或只包含很少方法)的類。一個值對象,就對應一個實體。它的屬性,通常應該與數據庫的字段名保持相同。此外,還應該有一個ID屬性。
class Person {
var $id, $first_name, $last_name, $email;
}
6. 數據訪問對象(Data Access Object, DAO)
數據訪問對象(DAO)的作用,主要是將數據庫訪問與其他代碼相隔離。DAO應該是可以疊加(stacked)的,這樣就有利於將來你再添加數據庫緩存。每一個值對象的類,都應該有自己的DAO。
class PersonDAO {
var $conn;
function PersonDAO(&$conn) {
$this->conn =& $conn;
}
function save(&$vo) {
if ($v->id == 0) {
$this->insert($vo);
} else {
$this->update($vo);
}
}
function get($id) {
#execute select statement
#create new vo and call getFromResult
#return vo
}
function delete(&$vo) {
#execute delete statement
#set id on vo to 0
}
#-- private functions
function getFromResult(&vo, $result) {
#fill vo from the database result set
}
function update(&$vo) {
#execute update statement here
}
function insert(&$vo) {
#generate id (from Oracle sequence or automatically)
#insert record into db
#set id on vo
}
}