PSR-2- Coding Style Guide 編碼風格規范 - PHP標準規范

代碼風格規范

本篇規范是 PSR-1 基本代碼規范的繼承與擴展。

本規范希望通過制定一系列規范化PHP代碼的規則,以減少在瀏覽不同作者的代碼時,因代碼風格的不同而造成不便。

當多名程序員在多個項目中合作時,就需要一個共同的編碼規范,
而本文中的風格規范源自于多個不同項目代碼風格的共同特性,
因此,本規范的價值在于我們都遵循這個編碼風格,而不是在于它本身。

關鍵詞 “必須”("MUST")、“一定不可/一定不能”("MUST NOT")、“需要”("REQUIRED")、
“將會”("SHALL")、“不會”("SHALL NOT")、“應該”("SHOULD")、“不該”("SHOULD NOT")、
“推薦”("RECOMMENDED")、“可以”("MAY")和”可選“("OPTIONAL")的詳細描述可參見 RFC 2119

1. 概覽


  • 代碼必須遵循 PSR-1 中的編碼規范 。

  • 代碼必須使用4個空格符而不是 tab鍵 進行縮進。

  • 每行的字符數應該軟性保持在80個之內, 理論上一定不可多于120個, 但一定不能有硬性限制。

  • 每個 namespace 命名空間聲明語句和 use 聲明語句塊后面,必須插入一個空白行。

  • 類的開始花括號{必須寫在其聲明后自成一行,結束花括號}必須寫在其主體后自成一行。

  • 方法的開始花括號{必須寫在函數聲明后自成一行,結束花括號}必須寫在函數主體后自成一行。

  • 類的屬性和方法必須添加訪問修飾符(privateprotected 以及 public), abstract 以及 final 必須聲明在訪問修飾符之前,而 static 必須聲明在訪問修飾符之后。

  • 控制結構的關鍵字后必須要有一個空格符,而調用方法或函數時則一定不能有。

  • 控制結構的開始花括號{必須寫在聲明的同一行,而結束花括號}必須寫在主體后自成一行。

  • 控制結構的開始左括號后和結束右括號前,都一定不能有空格符。

1.1. 例子

以下例子程序簡單地展示了以上大部分規范:

<?php
 namespace Vendor\Package;
 
 use FooInterface;
 use BarClass as Bar;
 use OtherVendor\OtherPackage\BazClass;
 
 class Foo extends Bar implements FooInterface
 {
     public function sampleFunction($a, $b = null)
     {
         if ($a === $b) {
             bar();
         } elseif ($a > $b) {
             $foo->bar($arg1);
         } else {
             BazClass::bar($arg2, $arg3);
         }
     }
 
     final public static function bar()
     {
         // method body
     }
 }

2. 通則


2.1 基本編碼準則

代碼必須符合 PSR-1 中的所有規范。

2.2 文件

所有PHP文件必須使用Unix LF (linefeed)作為行的結束符。

所有PHP文件必須以一個空白行作為結束。

純PHP代碼文件必須省略最后的 ?> 結束標簽。

2.3. 行

行的長度一定不能有硬性的約束。

軟性的長度約束一定要限制在120個字符以內,若超過此長度,帶代碼規范檢查的編輯器一定要發出警告,不過一定不可發出錯誤提示。

每行不應該多于80個字符,大于80字符的行應該折成多行。

非空行后一定不能有多余的空格符。

空行可以使得閱讀代碼更加方便以及有助于代碼的分塊。

每行一定不能存在多于一條語句。

2.4. 縮進

代碼必須使用4個空格符的縮進,一定不能用 tab鍵 。

備注: 使用空格而不是tab鍵縮進的好處在于,
避免在比較代碼差異、打補丁、重閱代碼以及注釋時產生混淆。
并且,使用空格縮進,讓對齊變得更方便。

sublime中按如下配置:

  "translate_tabs_to_spaces": true,
  "tab_size": 4

2.5. 關鍵字 以及 True/False/Null

PHP所有 關鍵字必須全部小寫。

常量 truefalsenull必須全部小寫。

3. namespace 以及 use 聲明


namespace 聲明后 必須 插入一個空白行。

所有 use 必須 在 namespace 后聲明。

每條 use 聲明語句 必須 只有一個 use 關鍵詞。

use 聲明語句塊后 必須 要有一個空白行。

例如:

 <?php
 namespace Vendor\Package;
 
 use FooClass;
 use BarClass as Bar;
 use OtherVendor\OtherPackage\BazClass;
 
 // ... additional PHP code ...
 

4. 類、屬性和方法


此處的“類”泛指所有的class類、接口以及traits可復用代碼塊。

4.1. 擴展與繼承

關鍵詞 extendsimplements必須寫在類名稱的同一行。

類的開始花括號必須獨占一行,結束花括號也必須在類主體后獨占一行。

 <?php
 namespace Vendor\Package;
 
 use FooClass;
 use BarClass as Bar;
 use OtherVendor\OtherPackage\BazClass;
 
 class ClassName extends ParentClass implements \ArrayAccess, \Countable
 {
     // constants, properties, methods
 }

implements 的繼承列表也可以分成多行,這樣的話,每個繼承接口名稱都必須分開獨立成行,包括第一個。

 <?php
 namespace Vendor\Package;
 
 use FooClass;
 use BarClass as Bar;
 use OtherVendor\OtherPackage\BazClass;
 
 class ClassName extends ParentClass implements
     \ArrayAccess,
     \Countable,
     \Serializable
 {
     // constants, properties, methods
 }

當需要擴展多個接口時,extends 的相關規范與 4.1 節中 implements 的規范一致。

4.2. 屬性

每個屬性都必須添加訪問修飾符。

一定不可使用關鍵字 var 聲明一個屬性。

每條語句一定不可定義超過一個屬性。

不要使用下劃線作為前綴,來區分屬性是 protected 或 private。

以下是屬性聲明的一個范例:

 <?php
 namespace Vendor\Package;
 
 class ClassName
 {
     public $foo = null;
 }

4.3. 方法

所有方法都必須添加訪問修飾符。

不要使用下劃線作為前綴,來區分方法是 protected 或 private。

方法名稱后一定不能有空格符,其開始花括號必須獨占一行,結束花括號也必須在方法主體后單獨成一行。參數左括號后和右括號前一定不能有空格。

一個標準的方法聲明可參照以下范例,留意其括號、逗號、空格以及花括號的位置。

 <?php
 namespace Vendor\Package;
 
 class ClassName
 {
     public function fooBarBaz($arg1, &$arg2, $arg3 = [])
     {
         // method body
     }
 }

4.4. 方法的參數

參數列表中,每個逗號后面必須要有一個空格,而逗號前面一定不能有空格。

有默認值的參數,必須放到參數列表的末尾。

 <?php
 namespace Vendor\Package;
 
 class ClassName
 {
     public function foo($arg1, &$arg2, $arg3 = [])
     {
         // method body
     }
 }

參數列表可以分列成多行,這樣,包括第一個參數在內的每個參數都必須單獨成行。

拆分成多行的參數列表后,結束括號以及方法開始花括號 必須 寫在同一行,中間用一個空格分隔。

 <?php
 namespace Vendor\Package;
 
 class ClassName
 {
     public function aVeryLongMethodName(
         ClassTypeHint $arg1,
         &$arg2,
         array $arg3 = []
     ) {
         // method body
     }
 }

4.5. abstractfinal 、 以及 static

需要添加 abstractfinal 聲明時, 必須寫在訪問修飾符前,而 static必須寫在其后。

 <?php
 namespace Vendor\Package;
 
 abstract class ClassName
 {
     protected static $foo;
 
     abstract protected function zim();
 
     final public static function bar()
     {
         // method body
     }
 }

4.6. 方法及函數調用

方法及函數調用時,方法名或函數名與參數左括號之間一定不能有空格,參數右括號前也 一定不能有空格。每個逗號前一定不能有空格,但其后必須有一個空格。

 <?php
 bar();
 $foo->bar($arg1);
 Foo::bar($arg2, $arg3);

參數可以分列成多行,此時包括第一個參數在內的每個參數都必須單獨成行。

 <?php
 $foo->bar(
     $longArgument,
     $longerArgument,
     $muchLongerArgument
 );

使用一個或多個跨行的參數(如數組和匿名函數)并不需要觸發 4.6 節中關于參數列表的單行規定,
因此,在參數表中的數組和匿名函數是可以單獨分列成多行的。

以下的例子是符合 PSR-2 規范的:

 <?php
 somefunction($foo, $bar, [
   // ...
 ], $baz);
 
 $app->get('/hello/{name}', function ($name) use ($app) { 
     return 'Hello '.$app->escape($name); 
 });

5. 控制結構


控制結構的基本規范如下:

  • 控制結構關鍵詞后必須有一個空格。
  • 左括號 (一定不能有空格。
  • 右括號 ) 前也一定不能有空格。
  • 右括號 ) 與開始花括號 {一定有一個空格。
  • 結構體主體一定要有一次縮進。
  • 結束花括號 } 一定在結構體主體后單獨成行。

每個結構體的主體都必須被包含在成對的花括號之中,
這能讓結構體更加結構話,以及減少加入新行時,出錯的可能性。

5.1. ifelseifelse

標準的 if 結構如下代碼所示,留意 括號、空格以及花括號的位置,
注意 elseelseif 都與前面的結束花括號在同一行。

 <?php
 if ($expr1) {
     // if body
 } elseif ($expr2) {
     // elseif body
 } else {
     // else body;
 }

應該使用關鍵詞 elseif 代替所有 else if ,以使得所有的控制關鍵字都像是單獨的一個詞。

5.2. switchcase

標準的 switch 結構如下代碼所示,留意括號、空格以及花括號的位置。
case 語句必須相對 switch 進行一次縮進,而 break 語句以及 case 內的其它語句都 必須 相對 case 進行一次縮進。
如果存在非空的 case 直穿語句,主體里必須有類似 // no break 的注釋。

 <?php
 switch ($expr) {
     case 0:
         echo 'First case, with a break';
         break;
     case 1:
         echo 'Second case, which falls through';
         // no break
     case 2:
     case 3:
     case 4:
         echo 'Third case, return instead of break';
         return;
     default:
         echo 'Default case';
         break;
 }

5.3. whiledo while

一個規范的 while 語句應該如下所示,注意其 括號、空格以及花括號的位置。

 <?php
 while ($expr) {
     // structure body
 }

標準的 do while 語句如下所示,同樣的,注意其 括號、空格以及花括號的位置。

 <?php
 do {
     // structure body;
 } while ($expr);

5.4. for

標準的 for 語句如下所示,注意其 括號、空格以及花括號的位置。

 <?php
 for ($i = 0; $i < 10; $i++) {
     // for body
 }

5.5. foreach

標準的 foreach 語句如下所示,注意其 括號、空格以及花括號的位置。

 <?php
 foreach ($iterable as $key => $value) {
     // foreach body
 }

5.6. try, catch

標準的 try catch 語句如下所示,注意其 括號、空格以及花括號的位置。

 <?php
 try {
     // try body
 } catch (FirstExceptionType $e) {
     // catch body
 } catch (OtherExceptionType $e) {
     // catch body
 }

6. 閉包


閉包聲明時,關鍵詞 function 后以及關鍵詞 use 的前后都必須要有一個空格。

開始花括號必須寫在聲明的同一行,結束花括號必須緊跟主體結束的下一行。

參數列表和變量列表的左括號后以及右括號前,必須不能有空格。

參數和變量列表中,逗號前必須不能有空格,而逗號后必須要有空格。

閉包中有默認值的參數必須放到列表的后面。

標準的閉包聲明語句如下所示,注意其 括號、逗號、空格以及花括號的位置。

 <?php
 $closureWithArgs = function ($arg1, $arg2) {
     // body
 };
 
 $closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
     // body
 };

參數列表以及變量列表可以分成多行,這樣,包括第一個在內的每個參數或變量都必須單獨成行,而列表的右括號與閉包的開始花括號必須放在同一行。

以下幾個例子,包含了參數和變量列表被分成多行的多情況。

 <?php
 $longArgs_noVars = function (
     $longArgument,
     $longerArgument,
     $muchLongerArgument
 ) {
    // body
 };
 
 $noArgs_longVars = function () use (
     $longVar1,
     $longerVar2,
     $muchLongerVar3
 ) {
    // body
 };
 
 $longArgs_longVars = function (
     $longArgument,
     $longerArgument,
     $muchLongerArgument
 ) use (
     $longVar1,
     $longerVar2,
     $muchLongerVar3
 ) {
    // body
 };
 
 $longArgs_shortVars = function (
     $longArgument,
     $longerArgument,
     $muchLongerArgument
 ) use ($var1) {
    // body
 };
 
 $shortArgs_longVars = function ($arg) use (
     $longVar1,
     $longerVar2,
     $muchLongerVar3
 ) {
    // body
 };

注意,閉包被直接用作函數或方法調用的參數時,以上規則仍然適用。

 <?php
 $foo->bar(
     $arg1,
     function ($arg2) use ($var1) {
         // body
     },
     $arg3
 );
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容

  • 編碼風格指南 本篇規范是 [PSR-1][] 基本代碼規范的繼承與擴展。 本規范希望通過制定一系列規范化PHP代碼...
    零一間閱讀 332評論 0 0
  • 整理自 PHP 標準規范 作為程序員來說,采用統一的編碼風格是非常重要的。這將給未來代碼的編寫、閱讀節省大量時間。...
    野塵lxw閱讀 716評論 0 2
  • 作為剛畢業沒多久的非計算機學院出身的工科生,誤打誤撞的變成一個程序猿,因基礎知識很薄弱,在此記錄一些學習的過程。...
    firsTime閱讀 206評論 0 0
  • Wendy_7f11閱讀 1,442評論 0 2
  • 欣頻老師夢想藍圖課程之后的我,身體上的毛孔系統全面打開來,那種暢快淋漓的舒暢感,清醒的頭腦,當其他人興奮的沉...
    UnaFung閱讀 639評論 3 3