一、文件格式
1. 對(duì)于只含有 PHP 代碼的文件,我們將在文件結(jié)尾處忽略掉 ”?>” 。這是為了防止多余的空格或者其它字符影響到代碼。
例如:
<?php
$foo = ’foo’;
2. 縮進(jìn)應(yīng)該能夠反映出代碼的邏輯結(jié)果,盡量使用四個(gè)空格,禁止使用制表符TAB,因?yàn)檫@樣能夠保證有跨客戶(hù)端編程器軟件的靈活性。
例如:
if (1 == $x) {
$indented_code = 1;
if (1 == $new_line) {
$more_indented_code = 1;
}
}
3. 變量賦值必須保持相等間距和排列。
例如:
$variable = ’demo’;
$var = ’demo2′;
4. 每行代碼長(zhǎng)度應(yīng)控制在80個(gè)字符以?xún)?nèi),最長(zhǎng)不超過(guò)120個(gè)字符。因?yàn)?Linux 讀入文件一般以80列為單位,就是說(shuō)如果一行代碼超過(guò)80個(gè)字符,那么系統(tǒng)將為此付出額外操作指令。這個(gè)雖然看起來(lái)是小問(wèn)題,但是對(duì)于追求完美的程序員來(lái)說(shuō)也是值得注意并遵守的規(guī)范。
5. 每行結(jié)尾不允許有多余的空格。
二、命名約定
1. 類(lèi)文件都是以“.class.php“為后綴,且類(lèi)文件名只允許字母,使用駝峰法命名,并且首字母大寫(xiě),例如:DbMysql.class.php 。
2. 配置和函數(shù)等其他類(lèi)庫(kù)文件之外的文件一般是分別以“.inc.php“和”.php“為后綴,且文件名命名使用小寫(xiě)字母和下劃線的方式,多個(gè)單詞之間以下 劃線分隔,例如config.inc.php , common.php,install_function.php 。
3. 確保文件的命名和調(diào)用大小寫(xiě)一致,是由于在類(lèi)Unix系統(tǒng)上面,對(duì)大小寫(xiě)是敏感的。
4. 類(lèi)名和文件名一致(包括上面說(shuō)的大小寫(xiě)一致),且類(lèi)名只允許字母,例如 UserAction類(lèi)的文件命名是UserAction.class.php, InfoModel類(lèi)的文件名是InfoModel.class.php 。
5. 控制器類(lèi)以Action為后綴,例如 UserAction、InfoAction ,模型類(lèi)以Model為后綴,例如UserModel、InfoModel ,其他類(lèi)也分別以相應(yīng)分類(lèi)為后綴,例如Service 、Widget。
6. 方法名只允許由字母組成,下劃線是不允許的,首字母要小寫(xiě),其后每個(gè)單詞首字母要大寫(xiě),即所謂的 “駝峰法命名” 規(guī)則,且越詳細(xì)越好,應(yīng)該能夠描述清楚該方法的功能,例如switchModel、findPage。
7. 屬性的命名只允許由字母組成,下劃線是不允許的,首字母要小寫(xiě),其后每個(gè)單詞首字母要大寫(xiě),即所謂的 “駝峰法命名” 規(guī)則,例如tablePrefix、tableName 。
8. 對(duì)于對(duì)象成員的訪問(wèn),我們必須始終使用 “get” 和 “set” 方法。例如:
class Foo
{
protected $_testObj;
public function getTestObj()
{
return $this->_testObj;
}
public function setTestObj($testObj)
{
$this->testObj = $_testObj;
}
}
9. 當(dāng)類(lèi)成員方法被聲明為 private 時(shí),必須分別以雙下劃線 ”__”為開(kāi)頭;被聲明為 protected 時(shí),必須分別以單下劃線 ”_” 為開(kāi)頭;一般情況下的方法不含下劃線。例如 :
class Foo
{
private function __example()
{
// …
}
protected function _example()
{
// …
}
public function example()
{
// …
}
}
10. 如果我們需要把一些經(jīng)常使用的方法定義為全局函數(shù),那么應(yīng)該把它們以靜態(tài) (static) 的形式定義在類(lèi)中。例如:
class Think
{
// …
static public function autoload($classname)
{
// …
}
}
11. 被聲明為 private的類(lèi)成員屬性必須由雙下劃線 ”__” 作為開(kāi)頭;被聲明為 protected 的類(lèi)成員屬性必須由下劃線 ”_” 作為開(kāi)頭;而聲明為 public 的成員屬性則在任何時(shí)候都不允許含有下劃線。
12. 函數(shù)的命名使用小寫(xiě)字母和下劃線的方式,且越詳細(xì)越好,應(yīng)該能夠描述清楚該函數(shù)的功能,例如 get_client_ip 。
13. 當(dāng)方法或函數(shù)參數(shù)不一定需要被賦值的時(shí)候,用 ”null” 來(lái)代替 ”false” 作為函數(shù)參數(shù)的默認(rèn)值,除非該參數(shù)是 boolean 值。
14. 變量只允許由小寫(xiě)字母和下劃線組成,且建議用描述性的變量的命名,越詳細(xì)越好,以至于像 $i 或 $n 等等都是不鼓勵(lì)使用的。
15. 類(lèi)中的常量 constant 和全局范圍內(nèi)常量define,只能由大寫(xiě)字母和下劃線組成,各個(gè)單詞之間以下劃線分割。
16. boolean 值和 null 值都采用小寫(xiě)。
三、編碼風(fēng)格
1. php 代碼必須以完整的形式來(lái)定界(<?php … ?>),即不要使用php 短標(biāo)簽(<? … ?>),且保證在關(guān)閉標(biāo)簽后不要有任何空格。
2. 當(dāng)一個(gè)字符串是純文本組成的時(shí)候(即不含有變量),則必須總是以單引號(hào)(’)作為定界符。例如:
$a = ’Example String’;
3. 變量替換中的變量只允許用 $+變量名 的形式。例如:
$greeting = ”Hello $name, welcome back!”; // 允許
$greeting = ”Hello {$name}, welcome back!”; // 允許
$greeting = ”Hello ${name}, welcome back!”; // 不允許
當(dāng)用點(diǎn)號(hào) ”.” 連接各字符串的時(shí)候,字符串與點(diǎn)號(hào)間必須用一個(gè)空格隔開(kāi),且允許把它分割成多行以增強(qiáng)可讀性。在這種情況下,點(diǎn)號(hào) ”.” 必須與等于號(hào) ”=” 對(duì)齊。例如:
$sql = ”SELECT `id`, `name` ” . ” FROM `people` ”
. ”WHERE `name` = ’Susan’ ”
. ”ORDER BY `name` ASC ”;
當(dāng)用 array 類(lèi)型符號(hào)來(lái)構(gòu)造數(shù)組的時(shí)候,必須在每個(gè)逗號(hào)之后加上一個(gè)空格來(lái)增強(qiáng)可讀性。例如:$sampleArray = array(1, 2, 3, ’Think’, ’SNS’);
4. 當(dāng)使用 array 類(lèi)型符聲明關(guān)聯(lián)數(shù)組的時(shí)候,我們鼓勵(lì)把它分成多個(gè)行,只是我們必須同時(shí)保證每行的鍵與值的對(duì)齊,以保持美觀。例如:
$sampleArray = array(
‘firstKey’ => ’firstValue’,
’secondKey’ => ’secondValue’
);
5. 大括號(hào)的開(kāi)始必須在類(lèi)名的下一行頂格。例如:
class Think
{
// …
}
6. 類(lèi)中的所有代碼都必須用四個(gè)空格來(lái)進(jìn)行縮進(jìn)。
7. 每個(gè) php 文件只允許聲明一個(gè)類(lèi)。在類(lèi)文件里面寫(xiě)其它代碼是允許的,但并不鼓勵(lì)這樣做。假如真要附加代碼的話,必須用空行來(lái)分隔。
8. 任何類(lèi)變量的聲明都必須放在類(lèi)頂部,先于任何函數(shù)的聲明。
9. 不允許用 var 符號(hào)來(lái)聲明變量,類(lèi)成員變量必須以 private,protected 和 public 來(lái)聲明。其次,把類(lèi)成員聲明為 public 而直接引用雖然是允許的,但通常更好的方法是使用 get 和 set 方法來(lái)訪問(wèn)類(lèi)成員。
10. 方法必須總是用 private,protected 或者 public 來(lái)聲明其作用域。
11. 靜態(tài) static 方法應(yīng)該聲明其作用域,且不應(yīng)該再被聲明為 private 私有,而應(yīng)該為 protected 或者public ,如果只是不想被子類(lèi)繼承,則應(yīng)該用 final 聲明它們。
12. 函數(shù)或方法的初始大括號(hào)應(yīng)該在函數(shù)聲明的下一行頂格。例如:
function get_client_ip()
{
// …
}
13. 在函數(shù)或方法名與參數(shù)括號(hào)之間不允許出現(xiàn)多余的空格。例如:
function get_client_ip()
{
// …
}
14. 引用只允許定義在函數(shù)參數(shù)中,實(shí)時(shí)傳遞引用是禁止的。例如:
// 引用定義在函數(shù)參數(shù)-允許的
function defineRefInMethod(&$a)
{
$a = ’a';
}
defineRefInMethod($b);
echo $b; // ’a’
// 實(shí)時(shí)傳遞引用-禁止的
function callTimePassRef($a)
{
$a = ’a';
}
callTimePassRef(&$c);
echo $c; // ’a’
15. 函數(shù)或方法返回值不可以用括號(hào)包住,不然會(huì)降低可讀性,而且假如以后函數(shù)修改為返回引用的話,這將會(huì)拋出一個(gè)異常。
16. 鼓勵(lì)盡量使用類(lèi)型提示,特別是在模塊設(shè)計(jì)中。例如:
class Foo
{
public function foo(SomeInterface $object)
{
}
public function bar(array $options)
{
}
}
17. 函數(shù)和方法參數(shù)必須用逗號(hào)+空格來(lái)分隔。
18. 對(duì)于參數(shù)為數(shù)組的函數(shù),參數(shù)中的數(shù)組應(yīng)該分成多行以增強(qiáng)可讀性。例如:
threeArguments(array(1, 2, 3), 2, 3);
threeArguments(array(1, 2, 3, ’Think’,
‘SNS’, $a, $b, $c,
56.44, $d, 500), 2, 3);
19. 基于”if”, ”else”和”else if”的條件控制里,我們必須用空格間隔開(kāi)語(yǔ)句和括號(hào),大括號(hào)的開(kāi)始 ”{“ 必須與條件控制語(yǔ)句位于同一行,結(jié)束 ”}” 必須總是獨(dú)占一行且頂格,控制流程內(nèi)容必須用四個(gè)空格進(jìn)行縮進(jìn),且不使用”elseif”。
if ($condition) {
// …
} else if ($_condition) {
// …
} else {
// …
}
20. 在條件控制語(yǔ)句的條件括號(hào)內(nèi),必須用空格將操作符與其它元素隔開(kāi)。如果遇到很長(zhǎng)的邏輯判斷,則鼓勵(lì)用內(nèi)嵌括號(hào)來(lái)分割各個(gè)邏輯。例如:
if (($a != 2) and ($b == 1)) {
$a = $b;
}
21. “switch” 條件控制語(yǔ)句中,必須用空格將待測(cè)參數(shù)與其它元素分隔開(kāi)。例如:
switch ($num) {
// …
}
22. ”switch” 語(yǔ)句的內(nèi)容必須以四個(gè)空格縮進(jìn),”case” 條件控制的內(nèi)容必須再加四個(gè)空格進(jìn)行縮進(jìn)。例如:
switch ($indentedSpaces) {
case 2:
echo ”錯(cuò)誤”;
break;
case 4:
echo ”正確”;
break;
default:
break;
}
23. 在 ”switch” 語(yǔ)句中應(yīng)該總是包括 ”default” 控制。
24. 有時(shí)候我們需要在 ”case” 語(yǔ)境中省略掉 ”break” 或 ”return” ,這個(gè)時(shí)候我們必須為這些 ”case” 語(yǔ)句加上 ”// 此處無(wú)break” 注釋。例如:
switch ($numPeople) {
case 1: // 此處無(wú)break
case 2:
break;
default:
break;
}