這篇規範是PSR-1(基本代碼規範)的擴充和繼承。
本規通過制定一系列規範化PHP代碼的規則,以減少在浏覽不同作者的代碼時,因代碼風格的不同而造成不便。
這個風格規範是從各種各樣的項目的共性中延伸出來的。當多名程式員在多個項目中合作時,它有助于有一套準則,在所有的項目中使用。
是以,本指南的好處不是在規則本身,而是在這些規則的共享。
關鍵詞 “必須”(“MUST”)、“一定不可/一定不能”(“MUST NOT”)、“需要”(“REQUIRED”)、
“将會”(“SHALL”)、“不會”(“SHALL NOT”)、“應該”(“SHOULD”)、“不該”(“SHOULD NOT”)、
“推薦”(“RECOMMENDED”)、“可以”(“MAY”)和”可選“(“OPTIONAL”)的較長的描述可參見 RFC 2119
1.概覽
- 代碼必須遵循PSR-1基本代碼規範。
- 代碼必須使用四個空格符進行縮進,而不是一個tab鍵。
- 每行應該保持在80個字元以内,軟限制必須是120個字元,但一定不能有硬性限制。
- 每個
命名空間聲明語句和namespace
聲明語句塊後面,必須有一個空白行。use
- 類的開始花括号(
)必須寫在函數聲明後自成一行,結束花括号({
)也必須寫在函數主體後自成一行。}
- 方法的開始花括号(
)必須寫在函數聲明後自成一行,結束花括号({
)也必須寫在函數主體後自成一行。}
- 在所有的屬性和方法上都必須聲明可見性(譯者注:
,private
以及protected
);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個字元的行,應該被拆分成多個不超過80個字元的後續行。
在非空白行的後面一定不能有多餘的空格符。
空行可以用來改善可讀性和區分相關的代碼塊。
每行一定不能多餘一條語句。
2.4 縮進
代碼必須使用四個空格符縮進,一定不能使用tab鍵。
備注:隻用空格,不于tab混合使用,有助于避免代碼差異、打更新檔、重閱代碼以及注釋時産生混淆。使用空格還可以使調整細微的縮進來改變對齊變得簡單。
2.5 關鍵字和True/False/Null
PHP關鍵字必須全部小寫。
PHP常量true,false和null**必須**全部小寫。
3. 命名空間以及Use聲明
存在命名空間時,其後面必須有一個空白行。
所有的use,必須在命名空間後聲明。
每條
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 擴充和繼承
關鍵詞
extends
和
implements
必須和類名在同一行。
類開始的花括号(
{
)必須獨占一行,類結束的花括号(
}
)必須在類主體後獨占一行。
<?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
}
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 abstract
, final
和 static
abstract
final
static
當存在時,
abstract
和
final
聲明必須放在可見性之前。
當存在時,
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
);
5. 控制結構
控制結構基本樣式規範如下:
- 控制結構關鍵詞後必須有一個空格。
- 左括号
後面一定不能有空格。(
- 右括号
前一定不能有空格。)
- 右括号
和開始花括号)
之間必須有一個空格。{
- 結構體必須縮進一次。
- 結束花括号
必須在主體後自成一行。}
每個結構體的主題都必須被包含在成對的花括号中,這使結構體看起來更加規範以及減少加入新行時,出錯的可能性。。
5.1 if
, elseif
, else
if
elseif
else
一個if的結構如下所示。注意其括号、空格以及花括号的位置,并且
else
和
elseif
和前一個主體的結束花括号
}
在同一行。
<?php
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
應該使用
elseif
代替
else if
,使得所有的控制關鍵詞看起來像一個單詞。
5.2 switch
和 case
switch
case
一個
switch
結構如下所示。注意其括号、空格以及花括号的位置。
case
語句必須相對于
switch
進行一次縮進,
break
關鍵字(或其他終止關鍵字)必須和
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 while
, do while
while
do while
一個
while
語句如下所示。注意其括号、空格以及花括号的位置。
<?php
while ($expr) {
// structure body
}
同樣,一個
do while
語句如下所示。注意其括号、空格以及花括号的位置。
<?php
do {
// structure body;
} while ($expr);
5.4 for
for
一個
for
語句看起來像下面這個樣子。注意其括号、空格以及花括号的位置。
<?php
for ($i = 0; $i < 10; $i++) {
// for body
}
5.5 foreach
foreach
一個
foreach
語句看起來像下面這樣。注意其括号、空格以及花括号的位置。
<?php
foreach ($iterable as $key => $value) {
// foreach body
}
5.6 try
, catch
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
);
7. 結論
有許多元素的風格和實踐在本指南中被故意忽略掉。這些包括但不限于:
- 全局變量和常量的定義
- 函數的定義
- 操作符和指派
- 行内對齊
- 注釋和文檔描述塊
- 類名的字首及字尾
- 最佳實踐
未來的建議可能會修改和擴充本指南,以解決這些或其他元素的風格和實踐。