PSR-2:編碼樣式指南

PSR-2:編碼樣式指南

翻譯:薛粲
受權許可:CC BY-NC 4.0php

這份文檔是《PSR-2: Coding Style Guide》的非官方譯文。閉包

《PSR-2:編碼樣式指南》擴展和擴充了《PSR-1:基礎編碼規範》。ide

這份指南的初衷是減小當咱們閱讀不一樣做者編寫的代碼時遇到的認知差別。它指望經過列舉了一組可供共同遵循的規則用於格式化 PHP 源代碼來實現這一目的。函數

英文原文使用的關鍵詞 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 以及 "OPTIONAL" 遵循 RFC 2119 的描述。譯文中根據上下文可能會使用不一樣的詞彙來對應這些關鍵詞,並加粗顯示。ui

1. 概述

  • 代碼必須遵循一份 PSR 編碼樣式指南 PSR-1編碼

  • 代碼必須使用 4 個空格而不是製表符做爲縮進。spa

  • 不得對行寬進行硬性限制;軟性限制必須是 120 個字符;每行應該包含 80 個或者更少的字符。翻譯

  • namespace 聲明以後必須有一個空行,在 use 聲明以後也必須有一個空行。設計

  • 類的左花括號必須在下一行,右花括號必須在內容後的下一行。code

  • 方法的左花括號必須在下一行,右花括號必須在內容後的下一行。

  • 必須爲全部屬性和方法聲明訪問控制;abstractfinal 必須在訪問控制以前;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()
    {
        // 方法內容
    }
}

2. 通用規則

2.1 基礎編碼標準

代碼必須遵循 PSR-1 規範列出的全部規則。

2.2 文件

全部 PHP 源文件必須使用 Unix LF (linefeed) 做爲換行符。

全部 PHP 源文件必須以一個空行結束。

對於只包含 PHP 的文件,必須省略用於指示 PHP 段結束的 ?> 標記。

2.3. 行

不得對行寬設置硬性限制。

對行寬的軟性限制必須是 120 個字符;超出時自動樣式檢查必須發出警告但不得產生錯誤。

不該該超過 80 個字符;超過的行應該分割爲多個不超過 80 個字符的行。

非空的行不得以空白字符結束。

能夠添加空行用於指出代碼塊的關聯性以提高代碼的可讀性。

一行不得包含超過一個語句。

2.4. 縮進

代碼必須使用 4 個空格用於縮進,不得使用製表符用於縮進。

只使用空格,不混用空格和製表符,可以幫助避免查看差別、打補丁、查看歷史以及批註時潛在的問題。使用空格還讓跨行對齊時插入細粒度的子縮進更加容易。

2.5. 保留字和 True/False/Null

PHP 保留字必須使用小寫。

PHP 常量 truefalse 以及 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. 類、屬性和方法

術語「類」指代全部的類、接口和 trait。

4.1. Extends 和 Implements

保留字 extendsimplements 必須與類名位於同一行。

類的起始花括號必須獨自一行;結束花括號必須在內容結束後的下一行。

<?php
namespace Vendor\Package;

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

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // 常量、屬性、方法等
}

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 聲明屬性。

一條語句不得聲明超過一個屬性。

不該該使用單個下劃線做爲 protectedprivate 屬性的訪問控制的前綴。

屬性聲明看相似下面的例子。

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}

4.3. 方法

必須爲全部方法聲明訪問控制。

不該該使用單個下劃線做爲 protectedprivate 方法的訪問控制的前綴。

方法名後不得使用空格。左花括號必須獨佔一行,右花括號必須在內容以後的行。左括號後不得緊接一個空格,右括號前不得放置一個空格。

方法的聲明相似下面的示例。請留意其中括號、逗號、空格以及花括號的位置:

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

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 塊中穿透行爲是設計須要的時候,必須添加相似 // 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. trycatch

一個 try catch 塊看起來形以下面的示例。請留意其中括號、空格以及花括號的位置。

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

6. 閉包

閉包聲明中保留字 function 以後必須有一個空格,保留字 use 先後必須各有一個空格。

左花括號必須與閉包聲明同一行,右花括號必須在內容結束後另起一行。

參數表和變量表的左括號以後不得留空格,右括號以前不得留空格。

參數表和變量表中逗號以前不得留空格,逗號以後必須留有一個空格。

閉包中具備默認值的參數必須位於參數表的最後。

一個閉包聲明看起來形以下面的示例。請留意其中括號、逗號、空格以及花括號的位置。

$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. 後記

這份規範有意的忽略了一些樣式和實踐準則,這些內容包括但不限於:

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

  • 函數的聲明

  • 操做符和賦值

  • 跨行對齊

  • 註釋和文檔塊

  • 類名的前綴和後綴

  • 最佳實踐

後續的推薦標準能夠修訂和擴展這份指南來涵蓋這部分或更多其它的樣式和實踐準則。

附錄 A:問卷調查

在起草這份指南是,PHP FIG 小組對其有成員項目進行了問卷調查以決定哪些實踐行爲是最廣泛的。原文在附錄中包含了問卷調查的狀況,譯文略。

相關文章
相關標籤/搜索