Zend Framework的PHP編碼標(biāo)準(zhǔn)
[摘自 Zend Framework 官方文檔]
C.2. PHP File 文件格式
C.2.1. 常規(guī)
對(duì)于只包含有 PHP 代碼的文件,結(jié)束標(biāo)志("?>")是不允許存在的,PHP自身不需要("?>"), 這樣做, 可以防止它的末尾的被意外地注入相應(yīng)。
重要: 由 __HALT_COMPILER() 允許的任意的二進(jìn)制代碼的內(nèi)容被 Zend Framework 中的 PHP 文件或由它們產(chǎn)生的文件禁止。這個(gè)功能的使用只對(duì)一些安裝腳本開(kāi)放。
C.2.2. 縮進(jìn)
縮進(jìn)由四個(gè)空格組成,禁止使用制表符 TAB 。
C.2.3. 行的最大長(zhǎng)度
一行 80 字符以?xún)?nèi)是比較合適,就是說(shuō),ZF 的開(kāi)發(fā)者應(yīng)當(dāng)努力在可能的情況下保持每行代碼少于 80 個(gè)字符,在有些情況下,長(zhǎng)點(diǎn)也可以, 但最多為 120 個(gè)字符。
C.2.4. 行結(jié)束標(biāo)志
行結(jié)束標(biāo)志遵循 Unix 文本文件的約定,行必需以單個(gè)換行符(LF)結(jié)束。換行符在文件中表示為 10,或16進(jìn)制的 0x0A。
注:不要使用 蘋(píng)果操作系統(tǒng)的回車(chē)(0x0D)或 Windows 電腦的回車(chē)換行組合如(0x0D,0x0A)。
C.3. 命名約定
C.3.1. 類(lèi)
Zend Framework 的類(lèi)命名總是對(duì)應(yīng)于其所屬文件的目錄結(jié)構(gòu)的,ZF 標(biāo)準(zhǔn)庫(kù)的根目錄是 “Zend/”,ZF 特別(extras)庫(kù)的根目錄是 "ZendX/",所有 Zend Framework 的類(lèi)在其下按等級(jí)存放。
類(lèi)名只允許有字母數(shù)字字符,在大部分情況下不鼓勵(lì)使用數(shù)字。下劃線(xiàn)只允許做路徑分隔符;例如 Zend/Db/Table.php 文件里對(duì)應(yīng)的類(lèi)名稱(chēng)是 Zend_Db_Table。
如果類(lèi)名包含多個(gè)單詞,每個(gè)單詞的第一個(gè)字母必須大寫(xiě),連續(xù)的大寫(xiě)是不允許的,例如 “Zend_PDF” 是不允許的,而 "Zend_Pdf" 是可接受的。
這些約定為 Zend Framework 定義了一個(gè)偽命名空間機(jī)制。如果對(duì)開(kāi)發(fā)者在他們的程序中切實(shí)可行,Zend Framework 將采用 PHP 命名空間特性(如果有的話(huà))。
參見(jiàn)在標(biāo)準(zhǔn)和特別庫(kù)中類(lèi)名作為類(lèi)名約定的例子。 重要: 依靠 ZF 庫(kù)展開(kāi)的代碼,但又不是標(biāo)準(zhǔn)或特別庫(kù)的一部分(例如程序代碼或不是 Zend 發(fā)行的庫(kù)),不要以 "Zend_" 或 "ZendX_" 開(kāi)頭。
C.3.2. 文件名
對(duì)于其它文件,只有字母數(shù)字字符、下劃線(xiàn)和短橫線(xiàn)("-")可用,空格是絕對(duì)不允許的。
包含任何 PHP 代碼的任何文件應(yīng)當(dāng)以 ".php" 擴(kuò)展名結(jié)尾,眾所周知的視圖腳本除外。下面這些例子給出 Zend Framework 類(lèi)可接受的文件名:
Zend/Db.php
Zend/Controller/Front.php
Zend/View/Helper/FormRadio.php
文件名必須遵循上述的對(duì)應(yīng)類(lèi)名的規(guī)則。
C.3.3. 函數(shù)和方法
函數(shù)名只包含字母數(shù)字字符,下劃線(xiàn)是不允許的。數(shù)字是允許的但大多數(shù)情況下不鼓勵(lì)。
函數(shù)名總是以小寫(xiě)開(kāi)頭,當(dāng)函數(shù)名包含多個(gè)單詞,每個(gè)子的首字母必須大寫(xiě),這就是所謂的 “駝峰” 格式。
我們一般鼓勵(lì)使用冗長(zhǎng)的名字,函數(shù)名應(yīng)當(dāng)長(zhǎng)到足以說(shuō)明函數(shù)的意圖和行為。
這些是可接受的函數(shù)名的例子:
filterInput()
getElementById()
widgetFactory()
對(duì)于面向?qū)ο缶幊?,?shí)例或靜態(tài)變量的訪(fǎng)問(wèn)器總是以 "get" 或 "set" 為前綴。在設(shè)計(jì)模式實(shí)現(xiàn)方面,如單態(tài)模式(singleton)或工廠(chǎng)模式(factory), 方法的名字應(yīng)當(dāng)包含模式的名字,這樣名字更能描述整個(gè)行為。
在對(duì)象中的方法,聲明為 "private" 或 "protected" 的, 名稱(chēng)的首字符必須是一個(gè)單個(gè)的下劃線(xiàn),這是唯一的下劃線(xiàn)在方法名字中的用法。聲明為 "public" 的從不包含下劃線(xiàn)。
全局函數(shù) (如:"floating functions") 允許但大多數(shù)情況下不鼓勵(lì),建議把這類(lèi)函數(shù)封裝到靜態(tài)類(lèi)里。
C.3.4. 變量
變量只包含數(shù)字字母字符,大多數(shù)情況下不鼓勵(lì)使用數(shù)字,下劃線(xiàn)不接受。
聲明為 "private" 或 "protected" 的實(shí)例變量名必須以一個(gè)單個(gè)下劃線(xiàn)開(kāi)頭,這是唯一的下劃線(xiàn)在程序中的用法,聲明為 "public" 的不應(yīng)當(dāng)以下劃線(xiàn)開(kāi)頭。
對(duì)函數(shù)名(見(jiàn)上面 3.3 節(jié))一樣,變量名總以小寫(xiě)字母開(kāi)頭并遵循“駝峰式”命名約定。
我們一般鼓勵(lì)使用冗長(zhǎng)的名字,這樣容易理解代碼,開(kāi)發(fā)者知道把數(shù)據(jù)存到哪里。除非在小循環(huán)里,不鼓勵(lì)使用簡(jiǎn)潔的名字如 "$i" 和 "$n" 。如果一個(gè)循環(huán)超過(guò) 20 行代碼,索引的變量名必須有個(gè)具有描述意義的名字。
C.3.5. 常量
常量包含數(shù)字字母字符和下劃線(xiàn),數(shù)字允許作為常量名。
常量名的所有字母必須大寫(xiě)。
常量中的單詞必須以下劃線(xiàn)分隔,例如可以這樣 EMBED_SUPPRESS_EMBED_EXCEPTION 但不許這樣 EMBED_SUPPRESSEMBEDEXCEPTION。
常量必須通過(guò) "const" 定義為類(lèi)的成員,強(qiáng)烈不鼓勵(lì)使用 "define" 定義的全局常量。
#p#
C.4. 編碼風(fēng)格
C.4.1. PHP 代碼劃分(Demarcation)
PHP 代碼總是用完整的標(biāo)準(zhǔn)的 PHP 標(biāo)簽定界:
- <?php
- ?>
短標(biāo)簽( )是不允許的,只包含 PHP 代碼的文件,不要結(jié)束標(biāo)簽 (參見(jiàn) Section C.2.1, “ 常規(guī) ”)。
C.4.2. 字符串
C.4.2.1. 字符串文字
當(dāng)字符串是文字(不包含變量),應(yīng)當(dāng)用單引號(hào)( apostrophe )來(lái)括起來(lái):
- $a = 'Example String';
C.4.2.2. 包含單引號(hào)(')的字符串文字
當(dāng)文字字符串包含單引號(hào)(apostrophe )就用雙引號(hào)括起來(lái),特別在 SQL 語(yǔ)句中有用:
- $sql = "SELECT `id`, `name` from `people` WHERE `name`='Fred' OR `name`='Susan'";
在轉(zhuǎn)義單引號(hào)時(shí),上述語(yǔ)法是首選的,因?yàn)楹苋菀组喿x。
C.4.2.3. 變量替換
變量替換有下面這些形式:
- $greeting = "Hello $name, welcome back!";
- $greeting = "Hello {$name}, welcome back!";
為保持一致,這個(gè)形式不允許:
- $greeting = "Hello ${name}, welcome back!";
C.4.2.4. 字符串連接
字符串必需用 "." 操作符連接,在它的前后加上空格以提高可讀性:
- $company = 'Zend' . ' ' . 'Technologies';
當(dāng)用 "." 操作符連接字符串,鼓勵(lì)把代碼可以分成多個(gè)行,也是為提高可讀性。在這些例子中,每個(gè)連續(xù)的行應(yīng)當(dāng)由 whitespace 來(lái)填補(bǔ),例如 "." 和 "=" 對(duì)齊:
- $sql = "SELECT `id`, `name` FROM `people` "
- . "WHERE `name` = 'Susan' "
- . "ORDER BY `name` ASC ";
C.4.3. 數(shù)組
C.4.3.1. 數(shù)字索引數(shù)組
索引不能為負(fù)數(shù),建議數(shù)組索引從 0 開(kāi)始。
當(dāng)用 array 函數(shù)聲明有索引的數(shù)組,在每個(gè)逗號(hào)的后面間隔空格以提高可讀性:
- $sampleArray = array(1, 2, 3, 'Zend', 'Studio');
可以用 "array" 聲明多行有索引的數(shù)組,在每個(gè)連續(xù)行的開(kāi)頭要用空格填補(bǔ)對(duì)齊:
- $sampleArray = array(1, 2, 3, 'Zend', 'Studio',
- $a, $b, $c,
- 56.44, $d, 500);
C.4.3.2. 關(guān)聯(lián)數(shù)組
當(dāng)用聲明關(guān)聯(lián)數(shù)組,array 我們鼓勵(lì)把代碼分成多行,在每個(gè)連續(xù)行的開(kāi)頭用空格填補(bǔ)來(lái)對(duì)齊鍵和值:
- $sampleArray = array('firstKey' => 'firstValue',
- 'secondKey' => 'secondValue');
C.4.4. 類(lèi)
C.4.4.1. 類(lèi)的聲明
用 Zend Framework 的命名約定來(lái)命名類(lèi)。
花括號(hào)應(yīng)當(dāng)從類(lèi)名下一行開(kāi)始(the "one true brace" form)。
每個(gè)類(lèi)必須有一個(gè)符合 PHPDocumentor 標(biāo)準(zhǔn)的文檔塊。
類(lèi)中所有代碼必需用四個(gè)空格的縮進(jìn)。
每個(gè) PHP 文件中只有一個(gè)類(lèi)。
放另外的代碼到類(lèi)里允許但不鼓勵(lì)。在這樣的文件中,用兩行空格來(lái)分隔類(lèi)和其它代碼。
下面是個(gè)可接受的類(lèi)的例子: // 459 9506 - 441 9658 下次從這里開(kāi)始
- /**
- * Documentation Block Here
- */
- class SampleClass
- {
- // 類(lèi)的所有內(nèi)容
- // 必需縮進(jìn)四個(gè)空格
- }
C.4.4.2. 類(lèi)成員變量
必須用Zend Framework的變量名約定來(lái)命名類(lèi)成員變量。
變量的聲明必須在類(lèi)的頂部,在方法的上方聲明。
不允許使用 var (因?yàn)?ZF 是基于 PHP 5 的 ),要用 private、 protected 或 public。 直接訪(fǎng)問(wèn) public 變量是允許的但不鼓勵(lì),最好使用訪(fǎng)問(wèn)器 (set/get)。
#p#
C.4.5. 函數(shù)和方法
C.4.5.1. 函數(shù)和方法聲明
必須用Zend Framework的函數(shù)名約定來(lái)命名函數(shù)。
在類(lèi)中的函數(shù)必須用 private、 protected 或 public 聲明它們的可見(jiàn)性。
象類(lèi)一樣,花括號(hào)從函數(shù)名的下一行開(kāi)始(the "one true brace" form)。
函數(shù)名和括參數(shù)的圓括號(hào)中間沒(méi)有空格。
強(qiáng)烈反對(duì)使用全局函數(shù)。
下面是可接受的在類(lèi)中的函數(shù)聲明的例子:
- /**
- * Documentation Block Here
- */
- class Foo
- {
- /**
- * Documentation Block Here
- */
- public function bar()
- {
- // 函數(shù)的所有內(nèi)容
- // 必需縮進(jìn)四個(gè)空格
- }
- }
注: 傳址(Pass-by-reference)是在方法聲明中允許的唯一的參數(shù)傳遞機(jī)制。
- /**
- * Documentation Block Here
- */
- class Foo
- {
- /**
- * Documentation Block Here
- */
- public function bar(&$baz)
- {}
- }
傳址在調(diào)用時(shí)是嚴(yán)格禁止的。
返回值不能在圓括號(hào)中,這妨礙可讀性而且如果將來(lái)方法被修改成傳址方式,代碼會(huì)有問(wèn)題。
- /**
- * Documentation Block Here
- */
- class Foo
- {
- /**
- * WRONG
- */
- public function bar()
- {
- return($this->bar);
- }
- /**
- * RIGHT
- */
- public function bar()
- {
- return $this->bar;
- }
- }
C.4.5.2. 函數(shù)和方法的用法
函數(shù)的參數(shù)應(yīng)當(dāng)用逗號(hào)和緊接著的空格分開(kāi),下面可接受的調(diào)用的例子中的函數(shù)帶有三個(gè)參數(shù):
- threeArguments(1, 2, 3);
傳址方式在調(diào)用的時(shí)候是嚴(yán)格禁止的,參見(jiàn)函數(shù)的聲明一節(jié)如何正確使用函數(shù)的傳址方式。
帶有數(shù)組參數(shù)的函數(shù),函數(shù)的調(diào)用可包括 "array" 提示并可以分成多行來(lái)提高可讀性,同時(shí),書(shū)寫(xiě)數(shù)組的標(biāo)準(zhǔn)仍然適用:
- threeArguments(array(1, 2, 3), 2, 3);
- threeArguments(array(1, 2, 3, 'Zend', 'Studio',
- $a, $b, $c,
- 56.44, $d, 500), 2, 3);
C.4.6. 控制語(yǔ)句
C.4.6.1. if/Else/Elseif
使用 if and elseif 的控制語(yǔ)句在條件語(yǔ)句的圓括號(hào)前后都必須有一個(gè)空格。
在圓括號(hào)里的條件語(yǔ)句,操作符必須用空格分開(kāi),鼓勵(lì)使用多重圓括號(hào)以提高在復(fù)雜的條件中劃分邏輯組合。
前花括號(hào)必須和條件語(yǔ)句在同一行,后花括號(hào)單獨(dú)在最后一行,其中的內(nèi)容用四個(gè)空格縮進(jìn)。
- if ($a != 2) {
- $a = 2;
- }
對(duì)包括"elseif" 或 "else"的 "if" 語(yǔ)句,和 "if" 結(jié)構(gòu)的格式類(lèi)似, 下面的例子示例 "if" 語(yǔ)句, 包括 "elseif" 或 "else" 的格式約定:
- if ($a != 2) {
- $a = 2;
- } else {
- $a = 7;
- }
- if ($a != 2) {
- $a = 2;
- } elseif ($a == 3) {
- $a = 4;
- } else {
- $a = 7;
- }
在有些情況下, PHP 允許這些語(yǔ)句不用花括號(hào),但在(ZF) 代碼標(biāo)準(zhǔn)里,它們("if"、 "elseif" 或 "else" 語(yǔ)句)必須使用花括號(hào)。
"elseif" 是允許的但強(qiáng)烈不鼓勵(lì),我們支持 "else if" 組合。
C.4.6.2. Switch
在 "switch" 結(jié)構(gòu)里的控制語(yǔ)句在條件語(yǔ)句的圓括號(hào)前后必須都有一個(gè)單個(gè)的空格。
"switch" 里的代碼必須有四個(gè)空格縮進(jìn),在"case"里的代碼再縮進(jìn)四個(gè)空格。
- switch ($numPeople) {
- case 1:
- break;
- case 2:
- break;
- default:
- break;
- }
switch 語(yǔ)句應(yīng)當(dāng)有 default。
注: 有時(shí)候,在 falls through 到下個(gè) case 的 case 語(yǔ)句中不寫(xiě) break or return 很有用。 為了區(qū)別于 bug,任何 case 語(yǔ)句中,所有不寫(xiě) break or return 的地方應(yīng)當(dāng)有一個(gè) "// break intentionally omitted" 這樣的注釋來(lái)表明 break 是故意忽略的。
#p#
C.4.7. 注釋文檔
C.4.7.1. 格式
所有文檔塊 ("docblocks") 必須和 phpDocumentor 格式兼容,phpDocumentor 格式的描述超出了本文檔的范圍,關(guān)于它的詳情,參考:http://phpdoc.org/。
所有類(lèi)文件必須在文件的頂部包含文件級(jí) ("file-level")的 docblock ,在每個(gè)類(lèi)的頂部放置一個(gè) "class-level" 的 docblock。下面是一些例子:
C.4.7.2. 文件
每個(gè)包含 PHP 代碼的文件必須至少在文件頂部的 docblock 包含這些 phpDocumentor 標(biāo)簽:
- /**
- * 文件的簡(jiǎn)短描述
- *
- * 文件的詳細(xì)描述(如果有的話(huà))... ...
- *
- * LICENSE: 一些 license 信息
- *
- * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/3_0.txt BSD License
- * @version $Id:$
- * @link http://framework.zend.com/package/PackageName
- * @since File available since Release 1.5.0
- */
C.4.7.3. 類(lèi)
每個(gè)類(lèi)必須至少包含這些 phpDocumentor 標(biāo)簽:
- /**
- * 類(lèi)的簡(jiǎn)述
- *
- * 類(lèi)的詳細(xì)描述 (如果有的話(huà))... ...
- *
- * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/ BSD License
- * @version Release: @package_version@
- * @link http://framework.zend.com/package/PackageName
- * @since Class available since Release 1.5.0
- * @deprecated Class deprecated in Release 2.0.0
- */
C.4.7.4. 函數(shù)
每個(gè)函數(shù),包括對(duì)象方法,必須有最少包含下列內(nèi)容的文檔塊(docblock):
函數(shù)的描述
所有參數(shù)
所有可能的返回值
因?yàn)樵L(fǎng)問(wèn)級(jí)已經(jīng)通過(guò) "public"、 "private" 或 "protected" 聲明, 不需要使用 "@access"。
如果函數(shù)/方法拋出一個(gè)異常,使用 @throws 于所有已知的異常類(lèi):
- @throws exceptionclass [description]