常用風(fēng)格和語法
下面將描述采用CI開發(fā)中的編碼的規(guī)范.
內(nèi)容列表
- 文件格式
- PHP 閉合標(biāo)簽
- 類和方法的命名
- 變量命名
- 注釋
- 常量
- TRUE, FALSE, 和NULL
- 邏輯運算符
- 比較返回值和類型映射
- 調(diào)試代碼
- 空行分割
- 兼容性
- 用常規(guī)詞做類名和文件名
- 數(shù)據(jù)庫表名
- 一個文件一個類
- 空白
- 斷行
- 代碼縮進
- Bracket and Parenthetic Spacing
- Localized Text
- 私有方法和變量
- PHP 錯誤
- 短標(biāo)簽
- 每行一條語句
- 字符串
- SQL 查詢
- 缺省函數(shù)參數(shù)
文件格式
文件應(yīng)該使用 Unicode (UTF-8) 編碼保存。同時不要使用 字節(jié)序標(biāo)記(BOM) 。與 UTF-16 和 UTF-32 不同,UTF-8 編碼的文件不需要指明字節(jié)序,而且 字節(jié)序標(biāo)記(BOM) 在PHP中會產(chǎn)生預(yù)期之外的輸出,阻止了應(yīng)用程序設(shè)置它自己的頭信息。應(yīng)該使用Unix 格式的行結(jié)束符(LF)。
以下是在一些常見的文本編輯器中更改這些設(shè)置的方法。針對你的編輯器,方法也許會有所不同;請參考你的編輯器的說明。
TextMate
- Open the Application Preferences
- Click Advanced, and then the "Saving" tab
- In "File Encoding", select "UTF-8 (recommended)"
- In "Line Endings", select "LF (recommended)"
- Optional: Check "Use for existing files as well" if you wish to modify the line endings of files you open to your new preference.
BBEdit
- Open the Application Preferences
- Select "Text Encodings" on the left.
- In "Default text encoding for new documents", select "Unicode (UTF-8, no BOM)"
- Optional: In "If file's encoding can't be guessed, use", select "Unicode (UTF-8, no BOM)"
- Select "Text Files" on the left.
- In "Default line breaks", select "Mac OS X and Unix (LF)"
PHP 閉合標(biāo)簽
PHP閉合標(biāo)簽“?>”在PHP中對PHP的分析器是可選的。 但是,如果使用閉合標(biāo)簽,任何由開發(fā)者,用戶,或者FTP應(yīng)用程序插入閉合標(biāo)簽后面的空格都有可能會引起多余的輸出、php錯誤、之后的輸出無法顯示、空白頁。因此,所有的php文件應(yīng)該省略這個php閉合標(biāo)簽,并插入一段注釋來標(biāo)明這是文件的底部并定位這個文件在這個應(yīng)用的相對路徑。這樣有利于你確定這個文件已經(jīng)結(jié)束而不是被刪節(jié)的。
不當(dāng)?shù)?/strong>:
<?php
echo "Here's my code!";
?>
適當(dāng)?shù)?/strong>:
<?php
echo "Here's my code!";
類和方法(函數(shù))的命名規(guī)則
類名的首字母應(yīng)該大寫。如果名稱由多個詞組成,詞之間要用下劃線分隔,不要使用駱駝命名法。類中所有其他方法的名稱應(yīng)該完全小寫并且名稱能明確指明這個函數(shù)的用途,最好用動詞開頭。盡量避免過長和冗余的名稱
不當(dāng)?shù)?/strong>:
class superclass
class SuperClass
適當(dāng)?shù)?/strong>:
class Super_class
class Super_class {
function __construct()
{
}
}
不當(dāng)?shù)暮瓦m當(dāng)?shù)姆椒Q的示例:
不當(dāng)?shù)?/strong>:
function fileproperties() // 方法名沒有清晰的描述以及下劃線分割單詞
function fileProperties() // 方法名沒有清晰的描述以及使用了駝峰法命名
function getfileproperties() // 還可以!但是忘記了下劃線分割單詞
function getFileProperties() // 使用了駝峰法命名
function get_the_file_properties_from_the_file() // 方法名太冗長
適當(dāng)?shù)?/strong>:
function get_file_properties() // 清晰的方法名描述,下劃線分割單詞,全部使用小寫字母
變量命名
變量的命名規(guī)則與方法的命名規(guī)則十分相似。就是說,變量名應(yīng)該只包含小寫字母,用下劃線分隔,并且能適當(dāng)?shù)刂该髯兞康挠猛竞蛢?nèi)容。那些短的、無意義的變量名應(yīng)該只作為迭代器用在for()循環(huán)里。
不當(dāng)?shù)?/strong>:
$j = 'foo'; // 單字符變量應(yīng)該只作為for()的循環(huán)變量使用
$Str // 使用了大寫字母
$bufferedText // 使用了駝峰命名,而且變量名應(yīng)該更短,并有清晰的語法含義
$groupid // 多個詞組,應(yīng)該使用下劃線分割
$name_of_last_city_used // 太長了
適當(dāng)?shù)?/strong>:
for ($j = 0; $j < 10; $j++)
$str
$buffer
$group_id
$last_city
注釋
通常,代碼應(yīng)該被詳細地注釋。這不僅僅有助于給缺乏經(jīng)驗的程序員描述代碼的流程和意圖,而且有助于給你提供豐富的內(nèi)容以讓你在幾個月后再看自己的代碼時仍能很好的理解。 注釋沒有強制規(guī)定的格式,但是我們建議以下的形式。
文檔塊(DocBlock) 式的注釋要寫在類和方法的聲明前,這樣它們就能被集成開發(fā)環(huán)境(IDE)捕獲:
class Super_class {
function xml_encode($str)
使用行注釋時,在大的注釋塊和代碼間留一個空行。
// break up the string by newlines
$parts = explode("\n", $str);
// A longer comment that needs to give greater detail on what is
// occurring and why can use multiple single-line comments. Try to
// keep the width reasonable, around 70 characters is the easiest to
// read. Don't hesitate to link to permanent external resources
// that may provide greater detail:
//
// http://example.com/information_about_something/in_particular/
$parts = $this->foo($parts);
常量
常量命名除了要全部用大寫外,其他的規(guī)則都和變量相同。在適當(dāng)?shù)臅r候,始終使用CodeIgniter常量,例如LASH, LD, RD, PATH_CACHE等等.
不當(dāng)?shù)?/strong>:
myConstant // 未使用下劃線分割單詞,未全部使用大寫字母
N // 不能使用單個字母作為常量
S_C_VER // 常量名沒有清晰的含義
$str = str_replace('{foo}', 'bar', $str); // should use LD and RD constants
恰當(dāng)?shù)?/strong>:
MY_CONSTANT
NEWLINE
SUPER_CLASS_VERSION
$str = str_replace(LD.'foo'.RD, 'bar', $str);
TRUE, FALSE, 和 NULL
TRUE, FALSE, 和 NULL 關(guān)鍵字應(yīng)該總是完全大寫的。
不當(dāng)?shù)?/strong>:
if ($foo == true)
$bar = false;
function foo($bar = null)
恰當(dāng)?shù)?/strong>:
if ($foo == TRUE)
$bar = FALSE;
function foo($bar = NULL)
邏輯操作符
|| 有時讓人底氣不足,不容易辨識,因為在某些輸出設(shè)備上它不夠清晰(可能看起來像數(shù)字11). && 要優(yōu)先于 AND ,不過兩者都可以被接受, 使用 ! 時要在其前后都加一個空格。
不當(dāng)?shù)?/strong>:
if ($foo || $bar)
if ($foo AND $bar) // 可以,但有時不被常用的語法程序高亮推薦(高亮標(biāo)識)
if (!$foo)
if (! is_array($foo))
恰當(dāng)?shù)?/strong>:
if ($foo OR $bar)
if ($foo && $bar) // 推薦
if ( ! $foo)
if ( ! is_array($foo))
比較返回值與類型映射
Some PHP functions return FALSE on failure, but may also have a valid return value of "" or 0, which would evaluate to FALSE in loose comparisons. Be explicit by comparing the variable type when using these return values in conditionals to ensure the return value is indeed what you expect, and not a value that has an equivalent loose-type evaluation.
試譯:部分PHP函數(shù)執(zhí)行失敗時返回 FALSE, 但也可能有一個有效的返回值 "" 或 0, 它在松散比較中會被計算為FALSE. 在條件語句中使用這些返回值的時候,為了確保返回值是你所預(yù)期的類型而不是一個有著松散類型的值,請進行顯式的比較。
Use the same stringency in returning and checking your own variables. Use === and !== as necessary.
試譯:在返回和檢查你自己的變量時也要遵循這種嚴格的方法,必要時使用=== 和 !== 。不當(dāng)?shù)?/strong>:
// 如果 'foo' 位于此字符串的起始處,strpos將返回 0,
// 此處條件判斷的結(jié)果為TRUE
if (strpos($str, 'foo') == FALSE)
恰當(dāng)?shù)?/strong>:
if (strpos($str, 'foo') === FALSE)
不當(dāng)?shù)?/strong>:
function build_string($str = "")
{
if ($str == "") // uh-oh! 如果傳遞的參數(shù)是FALSE或者整數(shù)0那會怎么樣?
{
}
}
恰當(dāng)?shù)?/strong>:
function build_string($str = "")
{
if ($str === "")
{
}
}
See also information regarding typecasting, which can be quite useful. Typecasting has a slightly different effect which may be desirable. When casting a variable as a string, for instance, NULL and boolean FALSE variables become empty strings, 0 (and other numbers) become strings of digits, and boolean TRUE becomes "1":
試譯:另見類型映射的信息,也會非常有用。類型映射的結(jié)果稍微有些不同,但也是可用的。比如,你把一個變量映射為字符串的時候,NULL以及布爾值FALSE會變成空字符串,0(以及其它數(shù)字)變成包含數(shù)字的字符串,布爾值TRUE變成 "1":
$str = (string) $str; // 將 $str 映射為字符串
調(diào)試代碼
No debugging code can be left in place for submitted add-ons unless it is commented out, i.e. no var_dump(), print_r(), die(), and exit() calls that were used while creating the add-on, unless they are commented out.
試譯:在已提交的附加組件所在的地方不能有調(diào)試代碼,它們被注釋掉的情況除外,例如,創(chuàng)建附加組件時不能調(diào)用 var_dump(), print_r(), die(), 以及 exit() ,除非它們已經(jīng)被注釋掉了。
// print_r($foo);
文件中的空格
No whitespace can precede the opening PHP tag or follow the closing PHP tag. Output is buffered, so whitespace in your files can cause output to begin before CodeIgniter outputs its content, leading to errors and an inability for CodeIgniter to send proper headers. In the examples below, select the text with your mouse to reveal the incorrect whitespace.
試譯:在PHP開始標(biāo)記之前和結(jié)束標(biāo)記之后都不能有空格。輸出已經(jīng)被緩存,所以文件中的空格會導(dǎo)致CodeIgniter在輸出自己的內(nèi)容之前就開始了輸出,這會使CodeIgniter出錯且無法輸出正確的header。在下面的例子中,使用鼠標(biāo)選中這些文本,你就能看到那些不應(yīng)該有的空格。
不當(dāng)?shù)?/strong>:
<?php
// ...在PHP開始標(biāo)記上面有空格和換行符
// 并且在PHP結(jié)束標(biāo)記后面也有空格
?>
恰當(dāng)?shù)?/strong>:
<?php
// 本例中,PHP開始標(biāo)記之前和結(jié)束標(biāo)記之后就沒有空格
?>
兼容性
Unless specifically mentioned in your add-on's documentation, all code must be compatible with PHP version 4.3+. Additionally, do not use PHP functions that require non-default libraries to be installed unless your code contains an alternative method when the function is not available, or you implicitly document that your add-on requires said PHP libraries.
試譯:除非你的附加組件的文檔中有特別說明,否則所有代碼必須與PHP 5.1以上版本兼容。此外,不要使用那些依賴于非默認安裝的庫的函數(shù),除非你的代碼中包含了該函數(shù)不可用時的替代方法,或者你在文檔中明確說明了你的附加組件需要某些庫。
使用常見詞語來命名類和文件
When your class or filename is a common word, or might quite likely be identically named in another PHP script, provide a unique prefix to help prevent collision. Always realize that your end users may be running other add-ons or third party PHP scripts. Choose a prefix that is unique to your identity as a developer or company.
試譯:當(dāng)你的類或文件名是一個常見詞語時,或者是很可能與另一個PHP腳本同名時,使用一個唯一的前綴來避免沖突。你必須始終明白這一點:你的最終用戶可能會運行其它第三方的附加組件或者PHP腳本。選擇一個能夠唯一標(biāo)識開發(fā)者或公司的前綴。
不當(dāng)?shù)?/strong>:
class Email pi.email.php
class Xml ext.xml.php
class Import mod.import.php
恰當(dāng)?shù)?/strong>:
class Pre_email pi.pre_email.php
class Pre_xml ext.pre_xml.php
class Pre_import mod.pre_import.php
數(shù)據(jù)庫表名
Any tables that your add-on might use must use the 'exp_' prefix, followed by a prefix uniquely identifying you as the developer or company, and then a short descriptive table name. You do not need to be concerned about the database prefix being used on the user's installation, as CodeIgniter's database class will automatically convert 'exp_' to what is actually being used.
你的附加組件所用到的任何表都必須使用 'exp_' 這個前綴,然后是一個能夠唯一標(biāo)識開發(fā)者或公司的前綴,最后才是一個簡短的描述性的表名。你不需要擔(dān)心用戶安裝時所使用的數(shù)據(jù)庫前綴,因為CodeIgniter的數(shù)據(jù)庫類將根據(jù)實際情況自動地對 'exp_' 進行轉(zhuǎn)換。
不當(dāng)?shù)?/strong>:
email_addresses // 缺少這兩個前綴
pre_email_addresses // 缺少 exp_ 前綴
exp_email_addresses // 缺少唯一前綴
恰當(dāng)?shù)?/strong>:
exp_pre_email_addresses
NOTE: Be mindful that MySQL has a limit of 64 characters for table names. This should not be an issue as table names that would exceed this would likely have unreasonable names. For instance, the following table name exceeds this limitation by one character. Silly, no? exp_pre_email_addresses_of_registered_users_in_seattle_washington
說明: 請注意MySQL對表名的限制是不能多于64個字符。會超出這個限制的那些表名都是不合理的,因此這應(yīng)該不是問題。例如,下面的這個些表名比最大限制多出一個字符。這很傻,不是嗎? exp_pre_email_addresses_of_registered_users_in_seattle_washington
一個文件一個類
Use separate files for each class your add-on uses, unless the classes are closely related. An example of CodeIgniter files that contains multiple classes is the Database class file, which contains both the DB class and the DB_Cache class, and the Magpie plugin, which contains both the Magpie and Snoopy classes.
對于你的附加組件所使用的類應(yīng)當(dāng)遵循一個文件一個類的原則,除非這些類是緊密相關(guān)的。CodeIgniter的文件中包含多個類的一個例子是數(shù)據(jù)庫類文件,其中包含了DB類和DB_Cache類,還有Magpie插件,其中包含了Magpie和Snoopy類。
空格
Use tabs for whitespace in your code, not spaces. This may seem like a small thing, but using tabs instead of whitespace allows the developer looking at your code to have indentation at levels that they prefer and customize in whatever application they use. And as a side benefit, it results in (slightly) more compact files, storing one tab character versus, say, four space characters.
在代碼中使用tab代替空格。這雖然看起來像是小事,但是使用tab代替空格有利于那些閱讀你的代碼的開發(fā)者在他們各自所使用的應(yīng)用程序中自定義縮進方式。此外還有一個好處是,使用這種方式保存的文件稍微緊湊一點。
換行
文件必須使用Unix換行符保存。這對于那些在Windows下的開發(fā)者來說更為重要,但無論如何,確保你的文本編輯器已經(jīng)設(shè)置為使用Unix換行符來保存文件。
代碼縮進
使用 Allman 風(fēng)格縮進。除了類聲明以外,括號總是獨占一行,且縮進與“屬于”它的控制語句同級。
不恰當(dāng)?shù)?/strong>:
function foo($bar) {
// ...
}
foreach ($arr as $key => $val) {
// ...
}
if ($foo == $bar) {
// ...
} else {
// ...
}
for ($i = 0; $i < 10; $i++)
{
for ($j = 0; $j < 10; $j++)
{
// ...
}
}
恰當(dāng)?shù)?/strong>:
function foo($bar)
{
// ...
}
foreach ($arr as $key => $val)
{
// ...
}
if ($foo == $bar)
{
// ...
}
else
{
// ...
}
for ($i = 0; $i < 10; $i++)
{
for ($j = 0; $j < 10; $j++)
{
// ...
}
}
方括號及圓括號內(nèi)的空格符
通常情況下,不要在方括號"[]"和圓括號"()"內(nèi)增加任何空格符。唯一的例外就是為了提高可讀性和區(qū)別開它們與函數(shù),在接受參數(shù)的PHP語法控制結(jié)構(gòu)所使用的括號里,需要增加空格符(declare, do-while, elseif, for, foreach, if, switch, while)。
不恰當(dāng)?shù)?
$arr[ $foo ] = 'foo';
正確的:
$arr[$foo] = 'foo'; // 數(shù)組鍵值的方括號內(nèi)沒有空格
不恰當(dāng)?shù)?
function foo ( $bar )
{
}
正確的:
function foo($bar) // 函數(shù)聲明的圓括號內(nèi)沒有空格
{
}
不恰當(dāng)?shù)?
foreach( $query->result() as $row ) // PHP語法控制結(jié)構(gòu)之后有空格,但不是在圓括號內(nèi)
正確的:
foreach ($query->result() as $row)
本地化文本
Any text that is output in the control panel should use language variables in your lang file to allow localization.
所有在控制面板輸出的文本都應(yīng)該使用 lang 文件里的語言變量來允許本地化。
INCORRECT:
return "Invalid Selection";
CORRECT:
return $this->lang->line('invalid_selection');
私有方法和變量
Methods and variables that are only accessed internally by your class, such as utility and helper functions that your public methods use for code abstraction, should be prefixed with an underscore.
如果方法和變量只在類的內(nèi)部使用,應(yīng)當(dāng)使用下劃線作為前綴。
convert_text() // public method
_convert_text() // private method
PHP Errors
Code must run error free and not rely on warnings and notices to be hidden to meet this requirement. For instance, never access a variable that you did not set yourself (such as $_POST array keys) without first checking to see that it isset().
Make sure that while developing your add-on, error reporting is enabled for ALL users, and that display_errors is enabled in the PHP environment. You can check this setting with:
if (ini_get('display_errors') == 1)
{
exit "Enabled";
}
On some servers where display_errors is disabled, and you do not have the ability to change this in the php.ini, you can often enable it with:
ini_set('display_errors', 1);
NOTE: Setting the display_errors setting with ini_set() at runtime is not identical to having it enabled in the PHP environment. Namely, it will not have any effect if the script has fatal errors
短標(biāo)記
一直使用 PHP 完整標(biāo)記,以免服務(wù)器不支持短標(biāo)記,也就是未打開 short_open_tag 。(IT不倒翁注釋:這條已經(jīng)不成立,因為新版本的 CI 已經(jīng)解決了服務(wù)器不支持短標(biāo)記的問題,不過還是建議使用完整標(biāo)記)
不正確的:
<? echo $foo; ?>
<?=$foo?>
正確的:
<?php echo $foo; ?>
每行一條語句
切記不要在一行寫多條語句
不正確:
$foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);
正確:
$foo = 'this';
$bar = 'that';
$bat = str_replace($foo, $bar, $bag);
字符串
一直使用單引號除非你需要解析變量,如果需要解析變量請使用大括號, to prevent greedy token parsing. 如果字符串包含單引號的話你可以使用雙引號,這樣就不用轉(zhuǎn)義了。
INCORRECT:
"My String" // 沒有解析變量,不需要使用雙引號
"My string $foo" // 解析變量需要使用括號
'SELECT foo FROM bar WHERE baz = \'bag\'' // 需要轉(zhuǎn)義單引號''時這樣寫比較難看,可以使用雙引號
CORRECT:
'My String'
"My string {$foo}"
"SELECT foo FROM bar WHERE baz = 'bag'"
SQL 查詢
MySQL 的關(guān)鍵字一直大寫: SELECT, INSERT, UPDATE, WHERE, AS, JOIN, ON, IN等等
考慮到易讀性,請將從句句分成多行來寫。
INCORRECT:
// keywords are lowercase and query is too long for
// a single line (... indicates continuation of line)
$query = $this->db->query("select foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses
...where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100");
CORRECT:
$query = $this->db->query("SELECT foo, bar, baz, foofoo, foobar AS raboof, foobaz
FROM exp_pre_email_addresses
WHERE foo != 'oof'
AND baz != 'zab'
ORDER BY foobaz
LIMIT 5, 100");
函數(shù)的默認參數(shù)
可能的話,請?zhí)峁┖瘮?shù)的默認參數(shù),這樣可以阻止諸如錯誤的調(diào)用的 PHP 錯誤,同時可以獲取公用的返回值,節(jié)約很多行代碼。例:
function foo($bar = '', $baz = FALSE)
?