源起
借來一本書,《PHP&MySQL范例精解——?jiǎng)?chuàng)建、修改、重用》。雖然是2008年出版的老書,但對與我這樣的新手來說還是挺有幫助的,畢竟那些基本的設(shè)計(jì)思想是不會(huì)過時(shí)的。
目錄結(jié)構(gòu)設(shè)計(jì)
書中說,在開發(fā)過程中第一步是設(shè)計(jì)程序的目錄結(jié)構(gòu)。建議創(chuàng)建三個(gè)主文件夾,分別用來:
- public_files:保存可以公共訪問的頁面;
- lib:保存可以被其他文件調(diào)用的引用文件;
- templates:保存頁面顯示文件。
Web服務(wù)器只允許訪問public_files下的文件,如此一來可以增強(qiáng)系統(tǒng)的安全性。
數(shù)據(jù)庫設(shè)計(jì)
將使用次數(shù)很少甚至只有一次的數(shù)據(jù)單獨(dú)存放在一個(gè)表中并及時(shí)刪除,以避免數(shù)據(jù)冗余。
例如,此書就將用戶激活相關(guān)的信息單獨(dú)放在了一個(gè)表中。因?yàn)檫@些信息只在激活時(shí)用到一次,用完即刪。
編寫共享代碼
將共享的代碼及鏈接數(shù)據(jù)庫的代碼分別存在在一個(gè)文件中,增加代碼的重用度,方便其他文件調(diào)用。
User類的設(shè)計(jì)
在MVC思想中該部分屬于model的設(shè)計(jì)。
在設(shè)計(jì)一個(gè)類的時(shí)候應(yīng)牢記,在面向?qū)ο缶幊讨校瑢ο蠹磳?yīng)著生活中的實(shí)體。類的屬性用于描述對象,而類的方法則用于直接操作對象或者做一些與該對象相關(guān)的操作。
對于一個(gè)用戶類而言,首先要有用戶ID、用戶名、密碼等這些用戶信息,是為該類的屬性。再者,我們需要對用戶進(jìn)行查找、創(chuàng)建、更新信息、激活等操作,于是便有與之對應(yīng)的方法來完成這些操作。
屬性的重載
此書使用了重載的放松來動(dòng)態(tài)地創(chuàng)建屬性。這樣做的好處是若以后要新增一些屬性幾乎不用對代碼作出改動(dòng),直接調(diào)用這些需要添加的屬性,就行了。
利用重載來動(dòng)態(tài)創(chuàng)建屬性與直接再代碼中添加一個(gè)新的屬性是不一樣的。屬性的重載利用了魔術(shù)方法__get()和__set()。在給不可訪問屬性(未定義或不可見)賦值時(shí),__set()會(huì)被調(diào)用;在讀取不可訪問屬性的值時(shí)__get()會(huì)被調(diào)用。一般通過__set()將重載的屬性的數(shù)據(jù)保存到一個(gè)私有數(shù)組字段中,需要讀取重載的屬性時(shí)又通過__get()從這個(gè)私有數(shù)組字段中讀取。示例代碼如下:
class User
{
private $uid;
private $field;
//initialize a User object
public function __construct()
{
$this->uid = null;
$this->field = array('username' => '',
'password' => '',
'emailAddr' => '',
'isActive' => false);
}
//override magic method to retrieve properties
public function __get($field)
{
if($field == 'userId'){
return $this->uid;
}else{
return $this->field[$field];
}
}
//override magic method to set properties
public function __set($field, $value)
{
if(array_key_exists($field, $this->field)){
$this->field[$field] = $value;
}
}
}
需要注意的是PHP中的重載與其他語言的不同。其他語言的重載一般是指同函數(shù)名稱不同參數(shù)個(gè)數(shù)從而實(shí)現(xiàn)同名的多個(gè)函數(shù)。關(guān)于PHP重載的更多內(nèi)容見PHP手冊:重載
對數(shù)據(jù)進(jìn)行驗(yàn)證
在對數(shù)據(jù)進(jìn)行處理之前需要對數(shù)據(jù)進(jìn)行驗(yàn)證。當(dāng)數(shù)據(jù)驗(yàn)證為是我們期望的那樣之后再對數(shù)據(jù)進(jìn)行處理。否則可能會(huì)出現(xiàn)不可預(yù)知的錯(cuò)誤。新手往往可能會(huì)忽視這一點(diǎn)。
例如在PHP的代碼中經(jīng)常會(huì)出現(xiàn)檢測某個(gè)量是否為空,若非空再進(jìn)行操作。
動(dòng)態(tài)的SQL語句
實(shí)現(xiàn)查找、保存等方法是需要用到動(dòng)態(tài)的SQL語句。此書通過sprintf()函數(shù)來實(shí)現(xiàn)。sprintf()函數(shù)類似與C#中的String.Format()。然而這種方式略繁瑣,個(gè)人感覺目前會(huì)有更好的方式。
當(dāng)使用sprintf()函數(shù)實(shí)現(xiàn)動(dòng)態(tài)SQL時(shí),對于較復(fù)雜的字符串參數(shù)需要使用real_escape_string()函數(shù)進(jìn)行轉(zhuǎn)義,以確保代碼的安全性。(編碼問題貌似一般和SQL注入有關(guān))。
模板
使用模板可以將邏輯和頁面設(shè)計(jì)分離。此書在這里使用了一個(gè)簡單的模板:將頁面各個(gè)部分的內(nèi)容保存到$GLOBALS數(shù)組中,模板文件在各個(gè)部分直接輸出數(shù)組的內(nèi)容。因此若想動(dòng)態(tài)的展示頁面,只需修改$GLOBALS中的內(nèi)容,再展示模板文件即可。
結(jié)語
本文是一篇簡單的學(xué)習(xí)筆記,主要是幫助自己整理思路,如果能對其他人也有一些幫助就更好了~【用markdown寫東西確實(shí)也挺爽的