人都有自由的天性,所以規(guī)范是不受歡迎的,但當(dāng)你被舊代碼或別人的代碼繞的云里霧里的時候,就會想要是有規(guī)范多好。所以規(guī)范最重要的作用是統(tǒng)一寫作風(fēng)格,提高可讀性,當(dāng)然這些規(guī)范不是某個人的規(guī)范,而是一些優(yōu)秀的、已經(jīng)達(dá)成共識的規(guī)則組成,例如大名鼎鼎的 Google Code Style,是google建議的編碼規(guī)范。PHP標(biāo)準(zhǔn)組也有一系列的風(fēng)格建議,其中關(guān)于代碼風(fēng)格的,即 PSR-0, PSR-1, PSR-2 和 PSR-4。
說明
基于php 5.3 版本編寫
文件規(guī)范
- 文件編碼必須使用utf-8編碼;
- 文件后綴只使用 .php,不允許使用其他后綴;
- 文件或目錄的命名和引用必須是大小寫敏感,Gather.php 和 gather.php 是兩個不同的文件;
- 每個php文件只允許聲明或定義一個類,在類文件里面寫其它代碼是允許的,但不鼓勵;
- 接口類和抽象類必須獨(dú)立一個文件,接口類的命名以xxxxInterface.php,抽象類的命名以 xxxxAbstract.php;
編碼風(fēng)格
- 強(qiáng)制縮進(jìn):代碼結(jié)構(gòu)的層次通過縮進(jìn)表達(dá),1個縮進(jìn)使用4個空格,如果使用Tab鍵進(jìn)行縮進(jìn),先檢查IDE的Tab設(shè)置是否為4個空格;
- 顯式聲明變量權(quán)限:每個類屬性和方法 必須顯式聲明訪問的權(quán)限:public / protected / private;
-
變量不允許轉(zhuǎn)換類型:每個變量在定義的時候必須顯式聲明變量的類型,例如:$articleList = array(); ,并且在運(yùn)行過程中,不允許對已聲明的變量變更類型。
<pre>
//局部變量初始化
$articles = array();
...
...
$articles = 'article';//雖然php允許,但不建議這樣用,可能增加未知風(fēng)險
...
...
</pre> -
大括號的使用,允許兩種方式,但在一個系統(tǒng)里,保持使用其中一種方式:
<pre>
方式一:
if(...){
//code
}else{
//code
}
方式二:
if(...)
{
//code
}
else
{
//code
}
</pre>
命名規(guī)范
以下命名規(guī)范包含文件名/類名/接口名/變量名/函數(shù)名
- 命名區(qū)分大小寫;
- 命名使用對應(yīng)的英文進(jìn)行拼寫,不使用拼音拼寫;
- 命名書寫采用駝峰式寫法(除常量外);
文件名、類名規(guī)范
- 文件名首字母大寫,并且只允許字母、數(shù)字組成;
- 類名與類文件名保持一致;
- 文件名和類名在程序中保持唯一;例如:GatherHandle.php 文件里面,定義了一個 GatherHandle 的類
變量名規(guī)范
- 除常量外,其他變量首字母小寫,變量名由字母、數(shù)字、下劃線組成;
- 全局變量,以小寫g開頭,例如:$gUserConfig;
- 靜態(tài)變量,以小寫s開頭,例如:$sNumCount;
- private 的類屬性,以下劃線開頭,例如:$_currentStringEncoding;
- protected、public 類屬性/局部變量,以小寫字母開頭,例如:$currentStringEncoding;
- 類中的常量 constant 和全局范圍內(nèi)常量define,使用全大寫拼寫,由大寫字母、數(shù)字、下劃線組成,例如:UTF8_ENCODING;
函數(shù)名
- 函數(shù)名/方法名由字母、數(shù)字、下劃線組成;
- private 的類方法,以下劃線開頭,例如:function _getStringEncoding($string){ ... }
- protected、public 類方法/函數(shù),以小寫字母開頭,例如:function getStringEncoding($string){ ... }
防御式編程
必須檢測數(shù)據(jù)是否符合預(yù)期類型
<pre>
$articleList = '';
...
...
foreach($articleList as $article){
...
}
//對變量進(jìn)行隨意更改類型(雖然php允許)可能增加bug風(fēng)險,良好習(xí)慣的重要性
</pre>
- 常用函數(shù)包括:isset、empty、is_array、is_int、is_string...更多參考Variable handling
- 或使用filter_input、filter_var系列函數(shù)進(jìn)行處理
對外部數(shù)據(jù)注重合法性判斷
用戶輸入數(shù)據(jù),例如:GET/POST 進(jìn)來的數(shù)據(jù),$_GET['pageId']
函數(shù)參數(shù)傳進(jìn)來的數(shù)據(jù),例如:function getStringEncoding($string){ ... }
- 首先確保數(shù)據(jù)的安全性(防止注入攻擊):
a. 如果對于確定類型的(非文本),可以使用強(qiáng)制類型轉(zhuǎn)換,例如:$pageId = (isset($_GET['pageId']))?(int)$_GET['pageId']:1;
b. 如果對于字符文本數(shù)據(jù),則需要做xss過濾,建議使用:HTMLPurifier - 其次判斷數(shù)據(jù)上下邊界有效性,例如:pageId 有效范圍是 1~5,那如果用戶輸入是 6,如果不處理,后面的代碼又依賴于這個數(shù),可能導(dǎo)致不可預(yù)期的異常;
- 對于上傳的文件,需判斷格式、文件大小是否符合預(yù)定約束。
對過程數(shù)據(jù)注重數(shù)據(jù)邊界判斷
在遵循 “編碼風(fēng)格:變量不允許轉(zhuǎn)換類型”這個原則下,是不會出現(xiàn)變量數(shù)據(jù)合法性問題,在過程數(shù)據(jù)中,注重的是數(shù)據(jù)的邊界:
<pre>
$articleList = array(1,2,3,4);
...
...
$articleIndex = $articleList[4]; //超過數(shù)組邊界,將報錯
</pre>
建議性規(guī)范
- 命名時候不建議使用過度縮寫,因為每個人理解差異,過度縮寫會導(dǎo)致難以閱讀;
- 當(dāng)一個字符串是純文本組成的時候(即不含變量),以單引號 '...' 作為定界符。例如:$stringEncoding = 'UTF-8';
- 勿濫用 @ 做錯誤處理,出現(xiàn)異常時候會導(dǎo)致程序難以調(diào)試;
工具推薦
sublime的phpcs,提示語法和自動糾正語法錯誤,可以節(jié)省格式化的編碼時間。