PSR-2標(biāo)準(zhǔn)

代碼風(fēng)格指南

本手冊是基礎(chǔ)代碼規(guī)范(PSR-1)的繼承和擴(kuò)展。

為了盡可能的提升閱讀其他人代碼時的效率,下面例舉了一系列的通用規(guī)則痰驱,特別是有關(guān)于PHP代碼風(fēng)格的录豺。

各個成員項目間的共性組成了這組代碼規(guī)范。當(dāng)開發(fā)者們在多個項目中合作時盖文,本指南將會成為所有這些項目中共用的一組代碼規(guī)范嘱蛋。 因此,本指南的益處不在于這些規(guī)則本身五续,而在于在所有項目中共用這些規(guī)則洒敏。

RFC 2119中的必須(MUST),不可(MUST NOT)疙驾,建議(SHOULD)凶伙,不建議(SHOULD NOT),可以/可能(MAY)等關(guān)鍵詞將在本節(jié)用來做一些解釋性的描述它碎。

1.概述

代碼必須遵守?PSR-1函荣。

代碼必須使用4個空格來進(jìn)行縮進(jìn),而不是用制表符扳肛。

一行代碼的長度不建議有硬限制傻挂;軟限制必須為120個字符,建議每行代碼80個字符或者更少敞峭。

在命名空間(namespace)的聲明下面必須有一行空行踊谋,并且在導(dǎo)入(use)的聲明下面也必須有一行空行。

類(class)的左花括號必須放到其聲明下面自成一行旋讹,右花括號則必須放到類主體下面自成一行殖蚕。

方法(method)的左花括號必須放到其聲明下面自成一行轿衔,右花括號則必須放到方法主體的下一行。

所有的屬性(property)和方法(method)必須有可見性聲明睦疫;抽象(abstract)和終結(jié)(final)聲明必須在可見性聲明之前害驹;而靜態(tài)(static)聲明必須在可見性聲明之后。

在控制結(jié)構(gòu)關(guān)鍵字的后面必須有一個空格蛤育;而方法(method)和函數(shù)(function)的關(guān)鍵字的后面不可有空格宛官。

控制結(jié)構(gòu)的左花括號必須跟其放在同一行,右花括號必須放在該控制結(jié)構(gòu)代碼主體的下一行瓦糕。

控制結(jié)構(gòu)的左括號之后不可有空格底洗,右括號之前也不可有空格。

1.1示例

這個示例中簡單展示了上文中提到的一些規(guī)則:

<?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()

? {

? ?//?方法主體

? }

}

2.通則

2.1 基礎(chǔ)代碼規(guī)范

代碼必須遵守?PSR-1?中的所有規(guī)則咕娄。

2.2 源文件

所有的PHP源文件必須使用Unix LF(換行)作為行結(jié)束符亥揖。

所有PHP源文件必須以一個空行結(jié)束。

純PHP代碼源文件的關(guān)閉標(biāo)簽?>必須省略圣勒。

2.3. 行

行長度不可有硬限制费变。

行長度的軟限制必須是120個字符;對于軟限制圣贸,代碼風(fēng)格檢查器必須警告但不可報錯挚歧。

一行代碼的長度不建議超過80個字符;較長的行建議拆分成多個不超過80個字符的子行吁峻。

在非空行后面不可有空格滑负。

空行可以用來增強(qiáng)可讀性和區(qū)分相關(guān)代碼塊。

一行不可多于一個語句锡搜。

2.4. 縮進(jìn)

代碼必須使用4個空格橙困,且不可使用制表符來作為縮進(jìn)。

注意:代碼中只使用空格耕餐,且不和制表符混合使用凡傅,將會對避免代碼差異,補(bǔ)丁肠缔,歷史和注解中的一些問題有幫助夏跷。空格的使用還可以使通過調(diào)整細(xì)微的縮進(jìn)來改進(jìn)行間對齊變得更加的簡單明未。

2.5. 關(guān)鍵字和 True/False/Null

PHP關(guān)鍵字(keywords)必須使用小寫字母槽华。

PHP常量true,false和null必須使用小寫字母。

3.命名空間(Namespace)和導(dǎo)入(Use)聲明

命名空間(namespace)的聲明后面必須有一行空行趟妥。

所有的導(dǎo)入(use)聲明必須放在命名空間(namespace)聲明的下面猫态。

一句聲明中,必須只有一個導(dǎo)入(use)關(guān)鍵字。

在導(dǎo)入(use)聲明代碼塊后面必須有一行空行亲雪。

示例:

<?phpnamespaceVendor\Package;useFooClass;useBarClassasBar;useOtherVendor\OtherPackage\BazClass;//... 其它PHP代碼 ...

4.類(class)勇凭,屬性(property)和方法(method)

術(shù)語“類”指所有的類(class),接口(interface)和特性(trait)义辕。

4.1擴(kuò)展(extend)和實現(xiàn)(implement)

一個類的擴(kuò)展(extend)和實現(xiàn)(implement)關(guān)鍵詞必須和類名(class name)在同一行虾标。

類(class)的左花括號必須放在下面自成一行;右花括號必須放在類(class)主體的后面自成一行灌砖。

<?phpnamespaceVendor\Package;useFooClass;useBarClassasBar;useOtherVendor\OtherPackage\BazClass;classClassNameextendsParentClassimplements\ArrayAccess,\Countable{//常量璧函、屬性、方法}

實現(xiàn)(implement)列表可以被拆分為多個縮進(jìn)了一次的子行基显。如果要拆成多個子行蘸吓,列表的第一項必須要放在下一行,并且每行必須只有一個接口(interface)撩幽。

<?phpnamespaceVendor\Package;useFooClass;useBarClassasBar;useOtherVendor\OtherPackage\BazClass;classClassNameextendsParentClassimplements\ArrayAccess,\Countable,\Serializable{//常量美澳、屬性、方法}

4.2.屬性(property)

所有的屬性(property)都必須聲明其可見性摸航。

變量(var)關(guān)鍵字不可用來聲明一個屬性(property)。

一條語句不可聲明多個屬性(property)舅桩。

屬性名(property name)不推薦用單個下劃線作為前綴來表明其保護(hù)(protected)或私有(private)的可見性酱虎。

一個屬性(property)聲明看起來應(yīng)該像下面這樣。

<?phpnamespaceVendor\Package;classClassName{public$foo=null;}

4.3.方法(method)

所有的方法(method)都必須聲明其可見性擂涛。

方法名(method name)不推薦用單個下劃線作為前綴來表明其保護(hù)(protected)或私有(private)的可見性读串。

方法名(method name)在其聲明后面不可有空格跟隨。其左花括號必須放在下面自成一行撒妈,且右花括號必須放在方法主體的下面自成一行恢暖。左括號后面不可有空格,且右括號前面也不可有空格狰右。

一個方法(method)聲明看來應(yīng)該像下面這樣杰捂。 注意括號,逗號棋蚌,空格和花括號的位置:

<?phpnamespaceVendor\Package;classClassName{publicfunctionfooBarBaz($arg1,&$arg2,$arg3=[]) {//方法主體部分 }}

4.4.方法(method)的參數(shù)

在參數(shù)列表中嫁佳,逗號之前不可有空格,而逗號之后則必須要有一個空格谷暮。

方法(method)中有默認(rèn)值的參數(shù)必須放在參數(shù)列表的最后面蒿往。

<?phpnamespaceVendor\Package;classClassName{publicfunctionfoo($arg1,&$arg2,$arg3=[]) {//方法主體部分 }}

參數(shù)列表可以被拆分為多個縮進(jìn)了一次的子行。如果要拆分成多個子行湿弦,參數(shù)列表的第一項必須放在下一行瓤漏,并且每行必須只有一個參數(shù)。

當(dāng)參數(shù)列表被拆分成多個子行,右括號和左花括號之間必須有一個空格并且自成一行蔬充。

<?phpnamespaceVendor\Package;classClassName{publicfunctionaVeryLongMethodName(ClassTypeHint$arg1,&$arg2,array$arg3=[] ) {//方法主體部分 }}

4.5.抽象(abstract)蝶俱,終結(jié)(final)和靜態(tài)(static)

當(dāng)用到抽象(abstract)和終結(jié)(final)來做類聲明時,它們必須放在可見性聲明的前面娃惯。

而當(dāng)用到靜態(tài)(static)來做類聲明時跷乐,則必須放在可見性聲明的后面。

<?phpnamespaceVendor\Package;abstractclassClassName{protectedstatic$foo;abstractprotectedfunctionzim();finalpublicstaticfunctionbar() {//方法主體部分 }}

4.6. 調(diào)用方法和函數(shù)

調(diào)用一個方法或函數(shù)時趾浅,在方法名或者函數(shù)名和左括號之間不可有空格愕提,左括號之后不可有空格,右括號之前也不可有空格皿哨。參數(shù)列表中浅侨,逗號之前不可有空格,逗號之后則必須有一個空格证膨。

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

參數(shù)列表可以被拆分成多個縮進(jìn)了一次的子行如输。如果拆分成子行,列表中的第一項必須放在下一行央勒,并且每一行必須只能有一個參數(shù)不见。

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

5.控制結(jié)構(gòu)

下面是對于控制結(jié)構(gòu)代碼風(fēng)格的概括:

控制結(jié)構(gòu)的關(guān)鍵詞之后必須有一個空格。

控制結(jié)構(gòu)的左括號之后不可有空格崔步。

控制結(jié)構(gòu)的右括號之前不可有空格稳吮。

控制結(jié)構(gòu)的右括號和左花括號之間必須有一個空格。

控制結(jié)構(gòu)的代碼主體必須進(jìn)行一次縮進(jìn)井濒。

控制結(jié)構(gòu)的右花括號必須主體的下一行灶似。

每個控制結(jié)構(gòu)的代碼主體必須被括在花括號里。這樣可是使代碼看上去更加標(biāo)準(zhǔn)化瑞你,并且加入新代碼的時候還可以因此而減少引入錯誤的可能性酪惭。

5.1.if,elseif者甲,else

下面是一個if條件控制結(jié)構(gòu)的示例春感,注意其中括號,空格和花括號的位置过牙。同時注意else和elseif要和前一個條件控制結(jié)構(gòu)的右花括號在同一行甥厦。

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

推薦用elseif來替代else if,以保持所有的條件控制關(guān)鍵字看起來像是一個單詞寇钉。

5.2.switch刀疙,case

下面是一個switch條件控制結(jié)構(gòu)的示例,注意其中括號扫倡,空格和花括號的位置谦秧。case語句必須要縮進(jìn)一級竟纳,而break關(guān)鍵字(或其他中止關(guān)鍵字)必須和case結(jié)構(gòu)的代碼主體在同一個縮進(jìn)層級。如果一個有主體代碼的case結(jié)構(gòu)故意的繼續(xù)向下執(zhí)行則必須要有一個類似于// no break的注釋疚鲤。

<?phpswitch($expr) {case0:echo'First case, with a break';break;case1:echo'Second case, which falls through';//no breakcase2:case3:case4:echo'Third case, return instead of break';return;default:echo'Default case';break;}

5.3.while锥累,do while

下面是一個while循環(huán)控制結(jié)構(gòu)的示例,注意其中括號集歇,空格和花括號的位置桶略。

<?phpwhile($expr) {//structure body}

下面是一個do while循環(huán)控制結(jié)構(gòu)的示例,注意其中括號诲宇,空格和花括號的位置际歼。

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

5.4.for

下面是一個for循環(huán)控制結(jié)構(gòu)的示例,注意其中括號姑蓝,空格和花括號的位置鹅心。

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

5.5.foreach

下面是一個foreach循環(huán)控制結(jié)構(gòu)的示例,注意其中括號纺荧,空格和花括號的位置旭愧。

<?phpforeach($iterableas$key=>$value) {//foreach body}

5.6.try,catch

下面是一個try catch異常處理控制結(jié)構(gòu)的示例,注意其中括號宙暇,空格和花括號的位置输枯。

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

6.閉包

聲明閉包時所用的function關(guān)鍵字之后必須要有一個空格,而use關(guān)鍵字的前后都要有一個空格占贫。

閉包的左花括號必須跟其在同一行用押,而右花括號必須在閉包主體的下一行。

閉包的參數(shù)列表和變量列表的左括號后面不可有空格靶剑,右括號的前面也不可有空格。

閉包的參數(shù)列表和變量列表中逗號前面不可有空格池充,而逗號后面則必須有空格桩引。

閉包的參數(shù)列表中帶默認(rèn)值的參數(shù)必須放在參數(shù)列表的結(jié)尾部分。

下面是一個閉包的示例收夸。注意括號坑匠,空格和花括號的位置。

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

參數(shù)列表和變量列表可以被拆分成多個縮進(jìn)了一級的子行卧惜。如果要拆分成多個子行厘灼,列表中的第一項必須放在下一行,并且每一行必須只放一個參數(shù)或變量咽瓷。

當(dāng)列表(不管是參數(shù)還是變量)最終被拆分成多個子行设凹,右括號和左花括號之間必須要有一個空格并且自成一行。

下面是一個參數(shù)列表和變量列表被拆分成多個子行的示例茅姜。

<?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};

把閉包作為一個參數(shù)在函數(shù)或者方法中調(diào)用時闪朱,依然要遵守上述規(guī)則。

<?php$foo->bar($arg1,function($arg2)use($var1) {//body },$arg3);

7.結(jié)論

本指南有意的省略了許多元素的代碼風(fēng)格。主要包括:

全局變量和全局常量的聲明

函數(shù)聲明

操作符和賦值

行間對齊

注釋和文檔塊

類名的前綴和后綴

最佳實踐

以后的代碼規(guī)范中可能會修正或擴(kuò)展本指南中規(guī)定的代碼風(fēng)格奋姿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锄开,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子称诗,更是在濱河造成了極大的恐慌萍悴,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寓免,死亡現(xiàn)場離奇詭異癣诱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)再榄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門狡刘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人困鸥,你說我怎么就攤上這事嗅蔬。” “怎么了疾就?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵澜术,是天一觀的道長。 經(jīng)常有香客問我猬腰,道長鸟废,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任姑荷,我火速辦了婚禮盒延,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鼠冕。我一直安慰自己添寺,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布懈费。 她就那樣靜靜地躺著计露,像睡著了一般。 火紅的嫁衣襯著肌膚如雪憎乙。 梳的紋絲不亂的頭發(fā)上票罐,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機(jī)與錄音泞边,去河邊找鬼该押。 笑死,一個胖子當(dāng)著我的面吹牛阵谚,可吹牛的內(nèi)容都是我干的沈善。 我是一名探鬼主播乡数,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闻牡!你這毒婦竟也來了净赴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤罩润,失蹤者是張志新(化名)和其女友劉穎玖翅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體割以,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡金度,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年许起,在試婚紗的時候發(fā)現(xiàn)自己被綠了教硫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抬吟。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡炸庞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脚翘,到底是詐尸還是另有隱情耻姥,我是刑警寧澤秧了,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布翩瓜,位于F島的核電站受扳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏兔跌。R本人自食惡果不足惜勘高,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坟桅。 院中可真熱鬧华望,春花似錦、人聲如沸仅乓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽方灾。三九已至,卻和暖如春碌更,著一層夾襖步出監(jiān)牢的瞬間裕偿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工痛单, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嘿棘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓旭绒,卻偏偏與公主長得像鸟妙,于是被迫代替她去往敵國和親焦人。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354