PHP開發(fā)之編碼規(guī)范

20140513143065

良好的PHP編碼規(guī)范能讓你的代碼看起來更加的優(yōu)雅,清晰的結構有助于提高可讀性并減少工作量。

麥蔥最近在學習PHP框架,發(fā)現(xiàn)自己以前編寫的代碼一點都不規(guī)范,實在汗顏,特此貼上PHP編碼規(guī)范,以示警醒。

以下內容部分總結自 Typecho PHP 編碼規(guī)范 和 CodeIgniter 開發(fā)規(guī)范 ,可戳地址進行傳送。

編碼無BOM

文件應該使用 Unicode (UTF-8) 編碼保存,不要使用 字節(jié)序標記(BOM) 。與 UTF-16 和 UTF-32 不同,UTF-8 編碼的文件不需要指明字節(jié)序,而且 字節(jié)序標記(BOM) 在PHP中會產生預期之外的輸出,阻止了應用程序設置它自己的頭信息。

如果保存帶BOM的編碼,會在文件頭輸出類似\ufeff的內容。這樣是不好的,會導致JSON等數(shù)據(jù)無法正常讀取。

PHP 閉合標簽

PHP閉合標簽?>在PHP中對PHP的分析器是可選的。但是,如果使用閉合標簽,任何由開發(fā)者,用戶,或者FTP應用程序插入閉合標簽后面的空格都有可能會引起多余的輸出、php錯誤、之后的輸出無法顯示、空白頁。

因此,如果此文件為純php文件(沒有嵌套HTML),請不要用?>符號結尾,保持最后一行留空即可。

最好插入一段注釋來標明這是文件的底部并定位這個文件在這個應用的相對路徑,這樣有利于你確定這個文件已經(jīng)結束而不是被刪節(jié)的。

不當?shù)?
<?php

echo "Here's my code!";

?>

適當?shù)?
<?php

echo "Here's my code!";

/* End of file myfile.php */
/* Location: ./path/myfile.php */

Unix換行符

文件必須使用Unix換行符保存,即只有換行(LF或\n)沒有回車(CR或\r)。這對于那些在Windows下的開發(fā)者來說更為重要,但無論如何,確保你的文本編輯器已經(jīng)設置為使用Unix換行符來保存文件。

標記前后無空格

在PHP開始標記之前和結束標記之后都不能有空格。輸出已經(jīng)被緩存,所以文件中的空格會導致PHP在輸出自己的內容之前就開始了輸出,這會使PHP出錯且無法輸出正確的header()

Tab縮進代碼

4個空格(space) = 1個制表符(tab)

使用 tab 代替空格有利于那些閱讀你的代碼的開發(fā)者在他們各自所使用的應用程序中自定義縮進方式,使用這種方式保存的文件稍微緊湊一點。

文件命名

一個文件一個類,class名稱與文件名應該相關聯(lián),關聯(lián)的方法是以包所在的目錄為根目錄,到類所在的文件,將目錄分隔符改為下劃線即為此類的名稱。比如我們的包名稱為

Myclass

,我們的類文件所在路徑為

Myclass/Foo/Bar.php

,那么這個類的名稱就是Myclass_Foo_Bar

類和方法(函數(shù))的命名規(guī)則

類名的首字母應該大寫。

如果名稱由多個詞組成,詞之間要用下劃線分隔,如果class名稱與文件名關聯(lián),請使用駱駝命名法。

類中所有其他方法的名稱應該完全小寫并且名稱能明確指明這個函數(shù)的用途,最好用動詞開頭。盡量避免過長和冗余的名稱。

不當?shù)?
class superclass
class SuperClass

適當?shù)?
class Super_class
class Myclass_Foo_Bar // class名和文件名關聯(lián)
不當?shù)?
function fileproperties() // 方法名沒有清晰的描述以及下劃線分割單詞
function fileProperties() // 方法名沒有清晰的描述以及使用了駝峰法命名
function getfileproperties() // 還可以!但是忘記了下劃線分割單詞
function getFileProperties() // 使用了駝峰法命名
function get_the_file_properties_from_the_file() // 方法名太冗長

適當?shù)?
function get_file_properties() // 清晰的方法名描述,下劃線分割單詞,全部使用小寫字母

為類和文件加上唯一標識

當你的類或文件名是一個常見詞語時,或者是很可能與另一個PHP腳本同名時,使用一個唯一的前綴來避免沖突。

你必須始終明白這一點:你的最終用戶可能會運行其它第三方的附加組件或者PHP腳本。選擇一個能夠唯一標識開發(fā)者或公司的前綴。

不當?shù)?
class Email pi.email.php
class Xml ext.xml.php
class Import mod.import.php

恰當?shù)?
class Pre_email pi.pre_email.php
class Pre_xml ext.pre_xml.php
class Pre_import mod.pre_import.php

變量命名

變量名應該只包含小寫字母,用下劃線分隔,并且能適當?shù)刂该髯兞康挠猛竞蛢热荨D切┒痰摹o意義的變量名應該只作為迭代器用在for()等循環(huán)里。

不當?shù)?
$j = 'foo'; // 單字符變量應該只作為for()的循環(huán)變量使用
$Str // 使用了大寫字母
$bufferedText // 使用了駝峰命名,而且變量名應該更短,并有清晰的語法含義
$groupid // 多個詞組,應該使用下劃線分割
$name_of_last_city_used // 太長了

適當?shù)?
for ($j = 0; $j < 10; $j++)
$str
$buffer
$group_id
$last_city

如為私有變量,請在變量名前方加上下劃線。

private $_foo

常量命名

常量命名除了要全部用大寫外,其他的規(guī)則都和變量相同。為統(tǒng)一標識,可以為常量加上指定前綴。

不當?shù)?
define('myConstant', 'foo'); // 未使用下劃線分割單詞,未全部使用大寫字母
define('N', '2'); // 不能使用單個字母作為常量
define('S_C_VER', '1.0'); // 常量名沒有清晰的含義

恰當?shù)?
define('MY_CONSTANT', 'foo');
define('NEWLINE', '2');
define('SUPER_CLASS_VERSION', '1.0');

注釋

通常,代碼應該被詳細地注釋。這不僅僅有助于給缺乏經(jīng)驗的程序員描述代碼的流程和意圖,而且有助于給你提供豐富的內容以讓你在幾個月后再看自己的代碼時仍能很好的理解。 注釋沒有強制規(guī)定的格式,但是建議添加以下的形式。

文檔塊(DocBlock) 式的注釋要寫在類和方法的聲明前,這樣它們就能被集成開發(fā)環(huán)境(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
*
* @access public
* @param string
* @return string
*/
function xml_encode($str)

引用文件和定義常量注釋

/** 定義變量 **/
define('MY_CONSTANT', 'foo');

/** 引用文件 **/
require_once 'Foo/Bar.php';

使用行注釋時,在大的注釋塊和代碼間留一個空行,行間注釋采用雙斜線注釋法。

// 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/

$parts = $this->foo($parts);

大括號放置

大括號換行規(guī)則與linux內核書寫規(guī)則一致。if/elsewhiledo/whileforswitch這些可以帶語句塊的語句,語句塊的{}應該和關鍵字寫在同一行,用空格隔開,而不是單獨占一行。

if ($foo) {
} else if ($bar) {
}

函數(shù)定義的{}單獨占一行,這一點和語句塊的規(guī)定不同。

class Super_class
{
    function __construct()
    {
}
}

switch和語句塊里的casedefault對齊寫,也就是說語句塊里的casedefault標號相對于switch不往里縮進,但標號下的語句要往里縮進。

switch ($foo) {
case 'A':
    語句列表
case 'B':
    語句列表
default:
    語句列表
}

逗號放置

函數(shù)中用逗號來分隔參數(shù),所有的參數(shù)與前面的逗號之間要空格(第一個參數(shù)除外)。

public function connect($host, $port, $db, $user, $password, $charset = NULL)

空格符使用

除了參數(shù)之間要使用空格外,所有操作符之間都要使用空格,包括字符連接符.

$a = "Hello";
$a = ($b = 4) + 5;
$a = $b . ':' . $c

方括號及圓括號內的空格符

通常情況下,不要在方括號[]和圓括號()內增加任何空格符。唯一的例外就是為了提高可讀性和區(qū)別開它們與函數(shù),在接受參數(shù)的PHP語法控制結構所使用的括號里,需要增加空格符(declaredo/whileelseifforforeachifswitchwhile)。

不當?shù)?
$arr[ $foo ] = 'foo';

適當?shù)?
$arr[$foo] = 'foo'; // 數(shù)組鍵值的方括號內沒有空格

不當?shù)?
function foo ( $bar )
{

}

適當?shù)?
function foo($bar) // 函數(shù)聲明的圓括號內沒有空格
{

}

不當?shù)?
foreach( $query->result() as $row ) // PHP語法控制結構之后有空格,但不是在圓括號內

適當?shù)?
foreach ($query->result() as $row)

代碼布局

1、類的內部方法排序為

__construct
private
protected
public
__destruct

2、屬性的排序為

private
protected
public

邏輯運算符優(yōu)先級

在PHP中,邏輯與和邏輯或有兩種表現(xiàn)方式:&&||andor,他們表示的含義都是相同的,但是他們的優(yōu)先級不同

運算符優(yōu)先級的順序是&&(||)、=and(or)

$a=1 && 0;
echo $a; //返回 空
$a=1 and 0;
echo $a; //返回 1

比較返回值與類型映射

部分PHP函數(shù)執(zhí)行失敗時返回 FALSE, 但也可能有一個有效的返回值 ''0, 它在松散比較中會被計算為FALSE. 在條件語句中使用這些返回值的時候,為了確保返回值是你所預期的類型而不是一個有著松散類型的值,請進行顯式的比較。

在返回和檢查你自己的變量時也要遵循這種嚴格的方法,必要時使用=== 和 !==

不當?shù)?
// 如果 'foo' 位于此字符串的起始處,strpos將返回 0,
// 此處條件判斷的結果為TRUE
if (strpos($str, 'foo') == FALSE)

恰當?shù)?
if (strpos($str, 'foo') === FALSE)
不當?shù)?
function build_string($str = '')
{
if ($str == '') // uh-oh! 如果傳遞的參數(shù)是FALSE或者整數(shù)0那會怎么樣?
{

}
}

恰當?shù)?
function build_string($str = '')
{
if ($str === '')
{

}
}

大小寫敏感

1、所有變量均區(qū)分大小寫,包括普通變量以及$_GET$_POST$_REQUEST$_COOKIE$_SESSION$GLOBALS$_SERVER$_FILES$_ENV

$abc = 'abcd';
echo $abc; //輸出 'abcd'
echo $aBc; //無輸出
echo $ABC; //無輸出

2、常量名默認區(qū)分大小寫,通常都寫為大寫

define('ABC','Hello World');
echo ABC;   //輸出 Hello World
echo abc;   //輸出 abc

3、函數(shù)名、方法名、類名 不區(qū)分大小寫,但推薦使用與定義時相同的名字

function show()
{
    echo "Hello World";
}
show(); //輸出 Hello World    推薦寫法
SHOW(); //輸出 Hello World
class cls
{
    static function func(){   
        echo "hello world";   
    }   
} 
cls::funC(); //輸出hello world 
Cls::funC(); //輸出hello world

4、魔術常量不區(qū)分大小寫,推薦大寫

包括:__LINE____FILE____DIR____FUNCTION____CLASS____METHOD____NAMESPACE__

echo __file__; //輸出 /web/filename.php
echo __FILE__; //輸出 /web/filename.php

5、NULLTRUEFALSE不區(qū)分大小寫,但是關鍵字應該總是完全大寫的。

$a = null;
$b = NULL;
$c = true;
$d = TRUE;
$e = false;
$f = FALSE;
var_dump($a == $b); //輸出 bool(true)
var_dump($c == $d); //輸出 bool(true)
var_dump($e == $f); //輸出 bool(true)

6、類型強制轉換,不區(qū)分大小寫

包括:

  • (int)(integer) – 轉換成整型
  • (bool)(boolean) – 轉換成布爾型
  • (float)(double)(real) – 轉換成浮點型
  • (string) – 轉換成字符串
  • (array) – 轉換成數(shù)組
  • (object) – 轉換成對象
$a=1;
var_dump($a); //輸出 int 1
$b=(STRING)$a;
var_dump($b); //輸出string '1' (length=1)
$c=(string)$a;
var_dump($c); //輸出string '1' (length=1)

相等恒等判斷

涉及到的比較值為:0''nullfalsetrueFLASETREUarray()

//比較值 '' NULL 0 false true FALSE TRUE
//相等判斷
'' == NULL == 0 == false (相等)
array() = 0 == NULL == false (相等)
array() <> '' (不相等)

//恒等判斷
//任何兩個數(shù)比較都不恒等
var_dump(false == FALSE); //bool(true)
var_dump(false === FALSE); //bool(true)
var_dump(true == TRUE); //bool(true)
var_dump(true === TRUE); //bool(true)
var_dump('' == NULL); //bool(true)
var_dump('' === NULL); //bool(false)
var_dump('' == 0); //bool(true)
var_dump('' === 0); //bool(false)
var_dump('' == false); //bool(true)
var_dump('' === false); //bool(false)
var_dump('' == true); //bool(false)
var_dump('' === true); //bool(false)
var_dump(null == 0); //bool(true)
var_dump(null === 0); //bool(false)
var_dump(null == false); //bool(true)
var_dump(null === false); //bool(false)
var_dump(null == true); //bool(false)
var_dump(null === true); //bool(false)
var_dump(0 == false); //bool(true)
var_dump(0 === false); //bool(false)
var_dump(0 == true); //bool(false)
var_dump(0 === true); //bool(false)

//對true的一些判斷
var_dump('1' == true); //bool(true)
var_dump('1' === true); //bool(false)
var_dump(1 == true); //bool(true)
var_dump(1 === true); //bool(false)
var_dump(array() == true); //bool(false)
var_dump(array() === true); //bool(false)

//array()比較
var_dump(array() == ''); //bool(false)
var_dump(array() === ''); //bool(false)
var_dump(array() == NULL); //bool(true)
var_dump(array() === NULL); //bool(false)
var_dump(array() == 0); //bool(false)
var_dump(array() === 0); //bool(false)
var_dump(array() == false); //bool(true)
var_dump(array() === false); //bool(false)
var_dump(array() == true); //bool(false)
var_dump(array() === true); //bool(false)

//恒等比較
var_dump(0 === '0'); //bool(false)
var_dump(0 === 00); //bool(true)
var_dump(00 === intval('0')); //bool(true)

每行一條語句

切記不要在一行寫多條語句

不當?shù)?
$foo = 'this'; $bar = 'that'; $bat = str_replace($foo, $bar, $bag);

適當?shù)?
$foo = 'this';
$bar = 'that';
$bat = str_replace($foo, $bar, $bag);

字符串

除非你需要解析變量那么請一直使用單引號,如果需要解析變量請使用大括號({ }),大括號用來明確變量名的界線。如果字符串包含單引號(' ')的話你可以使用雙引號(" "),這樣就不用轉義了。

不當?shù)?
"My String" // 沒有解析變量,不需要使用雙引號
"My string $foo" // 解析變量需要使用括號
'SELECT foo FROM bar WHERE baz = \'bag\'' // 需要轉義單引號''時這樣寫比較難看,可以使用雙引號

適當?shù)?
'My String'
"My string {$foo}"
"SELECT foo FROM bar WHERE baz = 'bag'"

SQL 查詢

MySQL的關鍵詞都是大寫: SELECTINSERTUPDATEWHEREASJOINONIN 等。

考慮到易讀性,把長的查詢分成多行,最好是每行只有一個從句或子從句。

不當?shù)?
// 關鍵詞是小寫并且一行中的查詢太長(...表示行的繼續(xù))
$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ù)?
$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ù)

適當?shù)臅r候,提供函數(shù)參數(shù)的缺省值,這有助于防止因錯誤的函數(shù)調用引起的PHP錯誤,另外提供常見的備選值可以節(jié)省幾行代碼 例如:

function foo($bar = '', $baz = FALSE)

以上是麥蔥整理的PHP編碼規(guī)范,你可以閱讀 PHP手冊之語言參考 以了解更多。

+ 騰訊alloyteam團隊編寫的前端代碼規(guī)范:http://alloyteam.github.io/code-guide/
+ JavaScript 規(guī)范: https://github.com/adamlu/javascript-style-guide
+ + 更多: https://github.com/justjavac/free-programming-books-zh_CN

轉載請注明出處 AE博客|墨淵 ? PHP開發(fā)之編碼規(guī)范

發(fā)表評論

路人甲

網(wǎng)友評論(0)