天天看點

PSR-2 代碼風格指南代碼風格指南

代碼風格指南

翻譯自:

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

PSR-2 在 PSR-1 的基礎上進行了繼承和擴充

1. 概述

  • 代碼

    必須

    遵循

    PSR-1

    規範
  • 代碼

    必須

    使用

    4個空格

    的縮進,而不是制表符

    tab

  • 一行代碼長度

    不可

    有硬性限制,軟限制必須為120個字元,也應當是80個字元或者更少
  • namespace

    聲明下面

    必須

    有一個空行,并且

    use

    聲明代碼塊下面也必須有一個空行
  • 類的開始花括号

    必須

    放到下一行,結束花括号

    必須

    放在類主體的下一行
  • 方法的開始花括号

    必須

    放在下一行,結束花括号

    必須

    放在方法主體下面
  • 所有的屬性和方法的可見性

    必須

    顯式(譯者注:

    Public

    ,

    Protect

    ,

    Private

    )聲明,

    abstract

    final

    聲明必須在顯式聲明可見性之前,

    static

    聲明必須在顯式聲明可見性之後
  • 控制結構(譯者注:

    for

    while

    等)的關鍵詞

    必須

    在後面有一個空格; 方法和函數

    必須

    沒有
  • 控制結構(譯者注:

    for

    while

    等)的開始花括号

    必須

    放在同一行,結束花括号

    必須

    放在控制主體的下一行
  • 控制結構的左括号後面不可有空格,右括号之前不可有空格

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

(換行)作為行結束符

所有PHP檔案

必須

以一個空行結束

隻有 PHP 代碼的檔案關閉标簽

?>

必須

省略

2.3 行

每行的長度

不可

有硬性限制

每行長度的軟限制必須是

120

個字元,對于軟限制,自動樣式檢查器

必須

警告但

不可

報錯

每行實際長度

不應該

超過

80

個字元,較長的行

應該

被拆分成多個不超過

80

個字元的後續行

在非空行後面

不可

有空格

空行

可以

用來改善可讀性和區分相關的代碼塊

每行

不可

多于一個語句

2.4 縮進

代碼

必須

使用

4個空格

的縮進,并且

不可

使用制表符

tab

作為縮進

注意:隻用空格,不與制表符

tab

混合使用,将會對避免代碼差異,更新檔,曆史和注解中的一些問題有幫助。使用空格還可以使調整細微的縮進來改進行間對齊變得簡單

2.5 關鍵詞

keywords

True/False/Null

PHP 的關鍵詞

keywords

必須

用小寫

PHP 中的常量

true

false

null

必須

全部小寫

3.

Namespace

Use

聲明

如果存在,

namespace

聲明後面

必須

有一個空行

如果存在,所有的

use

聲明

必須

放在

namespace

聲明下面

一個

use

關鍵字

必須

隻用于一個聲明

use

聲明代碼塊後面

必須

有一個空行

例:

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...
           

4. 類

class

,屬性

property

,方法

method

class

指所有的類

class

,接口

interface

和特性

trait

4.1. 繼承

extends

和接口實作

implements

一個類的

extends

implements

關鍵詞

必須

和類名

class name

在同一行

類的開始花括号

必須

放在下面自成一行,結束花括号

必須

放在類主體的後面自成一行

<?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. 屬性

property

所有的屬性

必須

顯式聲明可見性

var

關鍵詞

不可

用來聲明屬性

一個語句

不可

聲明多個屬性

屬性名稱

不應該

使用單個下劃線作為字首來表明保護或私有的可見性

一個屬性聲明應該像這樣:

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}
           

4.3. 方法

method

所有的方法

必須

顯式聲明可見性

方法名

不應該

使用單個下劃線作為字首來表明保護或私有的可見性

方法名在聲明之後

不可

跟随一個空格。開始花括号

必須

放在下面自成一行,并且結束花括号

必須

放在方法主體的下面自成一行

左括号後面

不可

有空格,右括号前面

不可

有空格

一個方法定義應該像下面這樣, 注意括号,逗号,空格和花括号:

<?php
namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}
           

4.4. 方法參數

Method Arguments

參數清單中,逗号之前

不可

有空格,逗号之後

必須

要有一個空格

方法中有預設值的參數

必須

放在參數清單的最後面

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

聲明

必須

放在可見性聲明後一個

<?php
namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}
           

4.6. 方法

method

和函數

function

調用

當進行函數或方法調用的時候,在方法或者函數名與左括号之間

不可

有空格,左括号之後

不可

有空格,右括号之前

不可

有空格

參數清單中,逗号之前

不可

有空格,逗号之後

必須

有一個空格

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

參數清單

可以

被拆分成多個有一個縮進的後續行。如果這麼做,清單中的第一項

必須

放在下一行,并且每一行

必須

隻有一個參數

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

5. 控制結構

Control Structures

對于控制結構通常的樣式規則如下:

  • 控制結構關鍵詞之後

    必須

    有一個空格
  • 左括号之後

    不可

    有空格
  • 右括号之前

    不可

    有空格
  • 在右括号和開始花括号之間

    必須

    有一個空格
  • 代碼主體

    必須

    有一次縮進
  • 結束花括号

    必須

    在主體的下一行

結構的主體部分

必須

被括在花括号裡,這使結構體看起來更加标準,減少了在主體部分中加入新行時出現錯誤的可能

5.1.

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

處縮進,并且

break

關鍵字(或其他中止關鍵字)必須和

case

主體縮進在同級。如果一個非空的

case

主體往下落空(譯者注:就是這個

case

不适用

break

結束)則必須有一個類似

// no break

的注釋

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

5.3.

while

do while

一個

while

語句看起來應該像下面這樣。注意括号,空格和花括号的位置

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

相同的,一個

do while

語句看起來應該像下面這樣。注意括号,空格和花括号的位置

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

5.4.

for

一個

for

語句看起來應該像下面這樣。注意括号,空格和花括号的位置

<?php
for ($i = ; $i < ; $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. 閉包

Closures

閉包在聲明時

function

關鍵詞之後

必須

有一個空格,并且

use

之前也需要一個空格

開始花括号

必須

function

在同一行,結束花括号

必須

在主體的下一行

參數清單和變量清單的左括号之後

不可

有空格,其右括号之前也

不可

有空格

在參數清單和變量清單中,逗号之前

不可

有空格,逗号之後

必須

有空格

閉包帶預設值的參數

必須

放在參數清單後面

一個閉包聲明看起來應該像下面這樣。注意括号,空格和花括号的位置

<?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. 結論

該指南中有很多風格的元素和做法被故意忽略掉。這些包括下面的等等:

  • 全局變量和全局常量的聲明
  • 方法聲明
  • 操作符和指派
  • 行間對齊
  • 注釋和文檔塊
  • 類名給你字首和字尾
  • 最佳實踐
敲了快兩個小時。。要瘋了(生無可戀)。。