# [PHP 開發規范](http://codeigniter.org.cn/user_guide/general/styleguide.html#id27)
CodeIgniter 的開發遵循本頁所描述的編碼規范,我們也推薦在你自己的應用程序開發中使用 這些規范,但不做強求。
目錄
[TOC=2,2]
## 文件格式
文件應該保存為 Unicode(UTF-8)編碼格式,不要使用?字節序標記(BOM),和 UTF-16 和 UTF-32 不一樣, UTF-8 編碼格式的文件不需要指定字節序。而且 BOM 會在 PHP 的輸出中產生副作用, 它會阻止應用程序設置它的頭信息。另外,所有的換行符應該使用 Unix 格式換行符(LF)。
以下是在一些常見的文本編輯器中更改這些設置的方法。針對你的編輯器,方法也許會有所不同, 請參考你的編輯器的說明。
### TextMate
1. 打開應用程序設置
2. 點擊 "高級" ,切換到 "保存" 標簽頁。
3. 在 "文件編碼" 中,選擇 "UTF-8(推薦)"
4. 在 "換行符" 中,選擇 "LF(推薦)"
5. 可選:如果你想對現有文件也能自動作此設置,勾上 "同時應用到已有文件" 選項
### BBEdit
1. 打開應用程序設置
2. 選擇左側的 "文本編碼"
3. 在 "新文檔的默認編碼",選擇 "Unicode (UTF-8, no BOM)"
4. 可選:在 "如果無法檢測文件編碼,使用...",選擇 "Unicode (UTF-8, no BOM)"
5. 選擇左側的 "文本文件"
6. 在 "默認的換行符" 中,選擇 "Mac OS X and Unix (LF)"
## PHP 結束標簽
PHP 結束標簽?**?>**?對于 PHP 解析器來說是可選的,但是只要使用了,結束標簽之后的空格 有可能會導致不想要的輸出,這個空格可能是由開發者或者用戶又或者 FTP 應用程序引入的, 甚至可能導致出現 PHP 錯誤,如果配置了不顯示 PHP 錯誤,就會出現空白頁面。基于這個原因, 所有的 PHP 文件將不使用結束標簽,而是以一個空行代替。
## 文件的命名
類文件的命名必須以大寫字母開頭,其他文件(配置文件,視圖,一般的腳本文件等)的命名是全小寫。
**錯誤的**:
~~~
somelibrary.php
someLibrary.php
SOMELIBRARY.php
Some_Library.php
Application_config.php
Application_Config.php
applicationConfig.php
~~~
**正確的**:
~~~
Somelibrary.php
Some_library.php
applicationconfig.php
application_config.php
~~~
另外,類文件的名稱必須和類的名稱保持一致,例如,如果你有一個類名為?Myclass?, 那么文件名應該是?**Myclass.php**?。
## 類和方法的命名
類名必須以大寫字母開頭,多個單詞之間使用下劃線分割,不要使用駝峰命名法。
**錯誤的**:
~~~
class superclass
class SuperClass
~~~
**正確的**:
~~~
class Super_class
~~~
~~~
class Super_class {
public function __construct()
{
}
}
~~~
類的方法應該使用全小寫,并且應該明確指出該方法的功能,最好包含一個動詞。 避免使用冗長的名稱,多個單詞之間使用下劃線分割。
**錯誤的**:
~~~
function fileproperties() // not descriptive and needs underscore separator
function fileProperties() // not descriptive and uses CamelCase
function getfileproperties() // Better! But still missing underscore separator
function getFileProperties() // uses CamelCase
function get_the_file_properties_from_the_file() // wordy
~~~
**正確的**:
~~~
function get_file_properties() // descriptive, underscore separator, and all lowercase letters
~~~
## 變量的命名
變量的命名規則和類方法的命名規則非常接近,使用全小寫,使用下劃線分割, 并且應該明確指出該變量的用途。非常短的無意義的變量只應該在 for 循環中作為迭代器使用。
**錯誤的**:
~~~
$j = 'foo'; // single letter variables should only be used in for() loops
$Str // contains uppercase letters
$bufferedText // uses CamelCasing, and could be shortened without losing semantic meaning
$groupid // multiple words, needs underscore separator
$name_of_last_city_used // too long
~~~
**正確的**:
~~~
for ($j = 0; $j < 10; $j++)
$str
$buffer
$group_id
$last_city
~~~
## 注釋
通常情況下,應該多寫點注釋,這不僅可以向那些缺乏經驗的程序員描述代碼的流程和意圖, 而且當你幾個月后再回過頭來看自己的代碼時仍能幫你很好的理解。 注釋并沒有強制規定的格式,但是我們建議以下的形式。
[DocBlock](http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html#basics.docblock)?風格的注釋,寫在類、方法和屬性定義的前面,可以被 IDE 識別:
~~~
/**
* Super Class
*
* @package Package Name
* @subpackage Subpackage
* @category Category
* @author Author Name
* @link http://example.com
*/
class Super_class {
~~~
~~~
/**
* Encodes string for use in XML
*
* @param string $str Input string
* @return string
*/
function xml_encode($str)
~~~
~~~
/**
* Data for class manipulation
*
* @var array
*/
public $data = array();
~~~
單行注釋應該和代碼合在一起,大塊的注釋和代碼之間應該留一個空行。
~~~
// 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);
~~~
## 常量
常量遵循和變量一樣的命名規則,除了它需要全部大寫。**盡量使用 CodeIgniter 已經定義好的常量, 如:SLASH、LD、RD、PATH_CACHE 等。**
**錯誤的**:
~~~
myConstant // missing underscore separator and not fully uppercase
N // no single-letter constants
S_C_VER // not descriptive
$str = str_replace('{foo}', 'bar', $str); // should use LD and RD constants
~~~
**正確的**:
~~~
MY_CONSTANT
NEWLINE
SUPER_CLASS_VERSION
$str = str_replace(LD.'foo'.RD, 'bar', $str);
~~~
## TRUE、FALSE 和 NULL
**TRUE**?、?**FALSE**?和?**NULL**?這幾個關鍵字全部使用大寫。
**錯誤的**:
~~~
if ($foo == true)
$bar = false;
function foo($bar = null)
~~~
**正確的**:
~~~
if ($foo == TRUE)
$bar = FALSE;
function foo($bar = NULL)
~~~
## 邏輯操作符
不要使用?||?操作符,它在一些設備上看不清(可能看起來像是數字 11), 使用?&&?操作符比使用?AND?要好一點,但是兩者都可以接受。 另外,在!?操作符的前后都應該加一個空格。
**錯誤的**:
~~~
if ($foo || $bar)
if ($foo AND $bar) // okay but not recommended for common syntax highlighting applications
if (!$foo)
if (! is_array($foo))
~~~
**正確的**:
~~~
if ($foo OR $bar)
if ($foo && $bar) // recommended
if ( ! $foo)
if ( ! is_array($foo))
~~~
## 對返回值進行比較以及類型轉換
有一些 PHP 函數在失敗時返回 FALSE ,但是也可能會返回 "" 或 0 這樣的有效值, 這些值在松散類型比較時和 FALSE 是相等的。所以當你在條件中使用這些返回值作比較時, 一定要使用嚴格類型比較,確保返回值確實是你想要的,而不是松散類型的其他值。
在檢查你自己的返回值和變量時也要遵循這種嚴格的方式,必要時使用?**===**?和?**!==**?。
**錯誤的**:
~~~
// If 'foo' is at the beginning of the string, strpos will return a 0,
// resulting in this conditional evaluating as TRUE
if (strpos($str, 'foo') == FALSE)
~~~
**正確的**:
~~~
if (strpos($str, 'foo') === FALSE)
~~~
**錯誤的**:
~~~
function build_string($str = "")
{
if ($str == "") // uh-oh! What if FALSE or the integer 0 is passed as an argument?
{
}
}
~~~
**正確的**:
~~~
function build_string($str = "")
{
if ($str === "")
{
}
}
~~~
另外關于?[類型轉換](http://php.net/manual/en/language.types.type-juggling.php#language.types.typecasting)?的信息也將很有用。 類型轉換會對變量產生一點輕微的影響,但可能也是期望的。例如 NULL 和 布爾值 FALSE 會轉換為空字符串, 數字 0 (和其他數字)將會轉換為數字字符串,布爾值 TRUE 會變成 "1":
~~~
$str = (string) $str; // cast $str as a string
~~~
## 調試代碼
不要在你的提交中包含調試代碼,就算是注釋掉了也不行。 像?var_dump()?、?print_r()?、?die()?和?exit()?這樣的函數,都不應該包含在你的代碼里, 除非它們用于除調試之外的其他特殊用途。
## 文件中的空格
PHP 起始標簽的前面和結束標簽的后面都不要留空格,輸出是被緩存的,所以如果你的文件中有空格的話, 這些空格會在 CodeIgniter 輸出它的內容之前被輸出,從而會導致錯誤,而且也會導致 CodeIgniter 無法發送正確的頭信息。
## 兼容性
CodeIgniter 推薦使用 PHP 5.4 或更新版本,但是它還得同時兼容 PHP 5.2.4 。 你的代碼要么提供適當的回退來兼容這點,要么提供一些可選的功能,當不兼容時能安靜的退出而不影響用戶的程序。
另外,不要使用那些需要額外安裝的庫的 PHP 函數,除非你能給出當該函數不存在時,有其他的函數能替代它。
## 一個類一個文件
除非幾個類是*緊密相關的*,否則每個類應該單獨使用一個文件。 在 CodeIgniter 中一個文件包含多個類的一個例子是 Xmlrpc 類文件。
## 空格
在代碼中使用制表符(tab)來代替空格,這雖然看起來是一件小事,但是使用制表符代替空格, 可以讓開發者閱讀你代碼的時候,可以根據他們的喜好在他們的程序中自定義縮進。 此外還有一個好處是,這樣文件可以更緊湊一點,也就是本來是四個空格字符, 現在只要一個制表符就可以了。
## 換行
文件必須使用 Unix 的換行格式保存。這對于那些在 Windows 環境下的開發者可能是個問題, 但是不管在什么環境下,你都應該確認下你的文本編輯器已經配置好使用 Unix 換行符了。
## 代碼縮進
使用 Allman 代碼縮進風格。除了類的定義之外,其他的所有大括號都應該獨占一行, 并且和它對應的控制語句保持相同的縮進。
**錯誤的**:
~~~
function foo($bar) {
// ...
}
foreach ($arr as $key => $val) {
// ...
}
if ($foo == $bar) {
// ...
} else {
// ...
}
for ($i = 0; $i < 10; $i++)
{
for ($j = 0; $j < 10; $j++)
{
// ...
}
}
try {
// ...
}
catch() {
// ...
}
~~~
**正確的**:
~~~
function foo($bar)
{
// ...
}
foreach ($arr as $key => $val)
{
// ...
}
if ($foo == $bar)
{
// ...
}
else
{
// ...
}
for ($i = 0; $i < 10; $i++)
{
for ($j = 0; $j < 10; $j++)
{
// ...
}
}
try
{
// ...
}
catch()
{
// ...
}
~~~
## 中括號和小括號內的空格
一般情況下,使用中括號和小括號的時候不應該使用多余的空格。 唯一的例外是,在那些接受一個括號和參數的 PHP 的控制結構(declare、do-while、elseif、for、 foreach、if、switch、while)的后面應該加一個空格,這樣做可以和函數區分開來,并增加可讀性。
**錯誤的**:
~~~
$arr[ $foo ] = 'foo';
~~~
**正確的**:
~~~
$arr[$foo] = 'foo'; // no spaces around array keys
~~~
**錯誤的**:
~~~
function foo ( $bar )
{
}
~~~
**正確的**:
~~~
function foo($bar) // no spaces around parenthesis in function declarations
{
}
~~~
**錯誤的**:
~~~
foreach( $query->result() as $row )
~~~
**正確的**:
~~~
foreach ($query->result() as $row) // single space following PHP control structures, but not in interior parenthesis
~~~
## 本地化文本
CodeIgniter 的類庫應該盡可能的使用相應的語言文件。
**錯誤的**:
~~~
return "Invalid Selection";
~~~
**正確的**:
~~~
return $this->lang->line('invalid_selection');
~~~
## 私有方法和變量
那些只能在內部訪問的方法和變量,例如供共有方法使用的那些工具方法或輔助函數,應該以下劃線開頭。
~~~
public function convert_text()
private function _convert_text()
~~~
## PHP 錯誤
運行代碼時不應該出現任何錯誤信息,并不是把警告和提示信息關掉來滿足這一點。 例如,絕不要直接訪問一個你沒設置過的變量(例如,$_POST?數組), 你應該先使用?isset()?函數判斷下。
確保你的開發環境對所有人都開啟了錯誤報告,PHP 環境的 display_errors 參數也開啟了, 你可以通過下面的代碼來檢查:
~~~
if (ini_get('display_errors') == 1)
{
exit "Enabled";
}
~~~
有些服務器上?display_errors?參數可能是禁用的,而且你沒有權限修改 php.ini 文件, 你可以使用下面的方法來啟用它:
~~~
ini_set('display_errors', 1);
~~~
注解
使用?ini_set()?函數在運行時設置?[display_errors](http://php.net/manual/en/errorfunc.configuration.php#ini.display-errors)?參數和通過 php.ini 配置文件來設置是不一樣的,換句話說,當出現致命錯誤(fatal errors)時,這種方法沒用。
## 短標記
使用 PHP 的完整標記,防止服務器不支持短標記(?short_open_tag?)參數。
**錯誤的**:
~~~
<? echo $foo; ?>
<?=$foo?>
~~~
**正確的**:
~~~
<?php echo $foo; ?>
~~~
> 注解
> PHP 5.4 下?`<?=`?標記是永遠可用的。
## 每行只有一條語句
切記不要在同一行內寫多條語句。
**錯誤的**:
~~~
$foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);
~~~
**正確的**:
~~~
$foo = 'this';
$bar = 'that';
$bat = str_replace($foo, $bar, $bag);
~~~
## 字符串
字符串使用單引號引起來,當字符串中有變量時使用雙引號,并且使用大括號將變量包起來。 另外,當字符串中有單引號時,也應該使用雙引號,這樣就不用使用轉義符。
**錯誤的**:
~~~
"My String" // no variable parsing, so no use for double quotes
"My string $foo" // needs braces
'SELECT foo FROM bar WHERE baz = \'bag\'' // ugly
~~~
**正確的**:
~~~
'My String'
"My string {$foo}"
"SELECT foo FROM bar WHERE baz = 'bag'"
~~~
## SQL 查詢
SQL 關鍵字永遠使用大寫:SELECT、INSERT、UPDATE、WHERE、AS、JOIN、ON、IN 等。
考慮到易讀性,把長的查詢分成多行,最好是每行只有一個從句或子從句。
**錯誤的**:
~~~
// 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");
~~~
**正確的**:
~~~
$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");
~~~
## 缺省的函數參數
適當的時候,提供函數參數的缺省值,這有助于防止因錯誤的函數調用引起的PHP錯誤, 另外提供常見的備選值可以節省幾行代碼。例如:
~~~
function foo($bar = '', $baz = FALSE)
~~~
- 歡迎使用 CodeIgniter
- 安裝說明
- 下載 CodeIgniter
- 安裝說明
- 從老版本升級
- 疑難解答
- CodeIgniter 概覽
- CodeIgniter 將從這里開始
- CodeIgniter 是什么?
- 支持特性
- 應用程序流程圖
- 模型-視圖-控制器
- 設計與架構目標
- 教程 - 內容提要
- 加載靜態內容
- 讀取新聞條目
- 創建新聞條目
- 結束語
- 常規主題
- CodeIgniter URL
- 控制器
- 保留名稱
- 視圖
- 模型
- 輔助函數
- 使用 CodeIgniter 類庫
- 創建類庫
- 使用 CodeIgniter 驅動器
- 創建驅動器
- 創建核心系統類
- 創建附屬類
- 鉤子 - 擴展框架核心
- 自動加載資源
- 公共函數
- 兼容性函數
- URI 路由
- 錯誤處理
- 網頁緩存
- 程序分析
- 以 CLI 方式運行
- 管理你的應用程序
- 處理多環境
- 在視圖文件中使用 PHP 替代語法
- 安全
- PHP 開發規范
- 類庫參考
- 基準測試類
- 緩存驅動器
- 日歷類
- 購物車類
- 配置類
- Email 類
- 加密類
- 加密類(新版)
- 文件上傳類
- 表單驗證類
- FTP 類
- 圖像處理類
- 輸入類
- Javascript 類
- 語言類
- 加載器類
- 遷移類
- 輸出類
- 分頁類
- 模板解析類
- 安全類
- Session 類
- HTML 表格類
- 引用通告類
- 排版類
- 單元測試類
- URI 類
- 用戶代理類
- XML-RPC 與 XML-RPC 服務器類
- Zip 編碼類
- 數據庫參考
- 數據庫快速入門: 示例代碼
- 數據庫配置
- 連接你的數據庫
- 查詢
- 生成查詢結果
- 查詢輔助函數
- 查詢構造器類
- 事務
- 數據庫元數據
- 自定義函數調用
- 數據庫緩存類
- 數據庫工廠類
- 數據庫工具類
- 數據庫驅動器參考
- 輔助函數參考
- 數組輔助函數
- 驗證碼輔助函數
- Cookie 輔助函數
- 日期輔助函數
- 目錄輔助函數
- 下載輔助函數
- 郵件輔助函數
- 文件輔助函數
- 表單輔助函數
- HTML 輔助函數
- 語言輔助函數
- Inflector 輔助函數
- 數字輔助函數
- 路徑輔助函數
- 安全輔助函數
- 表情輔助函數
- 字符串輔助函數
- 文本輔助函數
- 排版輔助函數
- URL 輔助函數
- XML 輔助函數
- 向 CodeIgniter 貢獻你的力量