PHP推薦標準編碼規範(PSR-1,PSR-2,PSR-3,PSR-4,PSR-12)

PSR是PHP Standards Recommendation的簡稱

PSR是php-fig組織制定的一套規範。

官網:https://www.php-fig.org/

下面是常用的幾套規範:

PSR-0:該標準不推薦使用,已被PSR-4替代。
PSR-1:基本編碼標準。
PSR-2:該標準不推薦使用,已被PSR-12替代。
PSR-3:日誌記錄器接口。
PSR-4:自動加載。
PSR-12:擴展編碼樣式。該規範擴展,擴展和替代了PSR-2(編碼樣式指南),並且要求遵守基本編碼標準PSR-1

PSR-1

RSR-1:基本編碼標準。

概述

  1. 文件只能使用<?php和<?=標記。

  2. 文件必須僅使用UTF-8,而不使用BOM用於PHP代碼。

  3. 文件應該任一聲明的符號(類,函數,常量等) 或引起副作用(例如生成輸出,變化的.ini設置,等等),但是不應該這樣做既。

  4. 命名空間和類必須遵循“自動加載” PSR:[ PSR-0,PSR-4 ]。

  5. 類名必須在中聲明StudlyCaps。

  6. 類常量必須在所有大寫字母中使用下劃線分隔符聲明。

  7. 方法名稱必須在中聲明camelCase。

命名空間和類名詳解

命名空間和類必須遵循“自動加載” PSR:[ PSR-0,PSR-4 ]。

這意味着每個類本身都在文件中,並且在至少一個級別的命名空間中:頂級供應商名稱。

類名必須在中聲明StudlyCaps。

爲PHP 5.3和之後編寫的代碼必須使用正式的大駝峯式名稱空間。

例如:

<?php
// PHP 5.3 and later:
namespace Vendor\Model;

class Foo
{
}

爲5.2.x和之前版本編寫的代碼應Vendor_在類名上使用前綴的僞命名間隔約定。

<?php
// PHP 5.2.x and earlier:
class Vendor_Model_Foo
{
}

類常量,屬性和方法詳解

術語“類”是指所有類,接口和特徵。

1.常數
類常量必須在所有大寫字母中使用下劃線分隔符聲明。例如:

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}

2.屬性名稱

本指南有意避免關於使用任何建議
 $StudlyCaps,$camelCase或$under_score
屬性名稱。

無論使用哪種命名約定,都應在合理範圍內一致地應用。該範圍可以是供應商級,程序包級,類級或方法級。

3.方法
方法名稱必須小寫字母開頭的駝峯式camelCase() 。

PSR-3

RSR-3:日誌規範樣式。
八個 水平(調試,信息,通知,警告,錯誤,危險,嚴重警告,緊急)

<?php

namespace Psr\Log;

/**
 * Describes log levels.
 */
class LogLevel
{
    const EMERGENCY = 'emergency';
    const ALERT     = 'alert';
    const CRITICAL  = 'critical';
    const ERROR     = 'error';
    const WARNING   = 'warning';
    const NOTICE    = 'notice';
    const INFO      = 'info';
    const DEBUG     = 'debug';
}

PSR-4

RSR-4:自動加載。

規格

術語“類”是指類,接口,特徵和其他類似的結構。

完全限定的類名稱具有以下形式:

 \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

完全合格的類名稱必須具有頂級名稱空間名稱,也稱爲“供應商名稱空間”。

完全合格的類名稱可以具有一個或多個子命名空間名稱。

完全合格的類名稱必須具有終止類名稱。

下劃線在完全限定的類名的任何部分中沒有特殊含義。

完全限定的類名中的字母字符可以是小寫和大寫的任意組合。

所有類名必須以區分大小寫的方式引用。

加載與完全限定的類名相對應的文件時…

在完全限定的類名(“名稱空間前綴”)中,一個或多個開頭的名稱空間和子名稱空間名稱(不包括開頭的名稱空間分隔符)的連續序列對應於至少一個“基本目錄”。

“名稱空間前綴”之後的連續子名稱空間名稱對應於“基本目錄”中的子目錄,其中名稱空間分隔符表示目錄分隔符。子目錄名稱必須與子命名空間名稱的大小寫匹配。

終止類名對應於以結尾的文件名.php。文件名必須與終止類名的大小寫匹配。

自動加載器的實現不得拋出異常,不得引發任何級別的錯誤,並且不應返回值。

示例
完整名稱 命名空間前綴 基本目錄 結果文件路徑
\Acme\Log\Writer\File_Writer Acme\Log\Writer ./acme-log-writer/lib/ ./acme-log-writer/lib/File_Writer.php
\Aura\Web\Response\Status Aura\Web /path/to/aura-web/src/ /path/to/aura-web/src/Response/Status.php
\Symfony\Core\Request Symfony\Core ./vendor/Symfony/Core/ ./vendor/Symfony/Core/Request.php
\Zend\Acl Zend /usr/includes/Zend/ /usr/includes/Zend/Acl.php

PSR-12

RSR-12:擴展編碼樣式。

總覽

該規範擴展,擴展和替代了PSR-2(編碼樣式指南),並且要求遵守基本編碼標準PSR-1。

本示例簡要概述了以下一些規則:

<?php

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;

use function Vendor\Package\{functionA, functionB, functionC};

use const Vendor\Package\{ConstantA, ConstantB, ConstantC};

class Foo extends Bar implements FooInterface
{
    public function sampleFunction(int $a, int $b = null): array
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

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

線長絕不能有硬性限制。

行長的軟限制必須爲120個字符。

行數不能超過80個字符;長於該行的行應分成多行,每行不超過80個字符。

行尾一定不能有尾隨空格。

除非明確禁止,否則可以添加空行以提高可讀性並指示相關的代碼塊。

每行不得超過一個語句。

縮進

代碼必須爲每個縮進級別使用4個空格的縮進,並且不得使用製表符進行縮進。

關鍵字和類型

所有PHP保留的關鍵字類型都必須小寫。
添加到將來的PHP版本中的任何新類型和關鍵字都必須小寫。
類型關鍵字的縮寫形式必須使用,即bool代替boolean, int代替integeretc。

聲明語句,命名空間和導入語句

PHP文件的標頭可能包含許多不同的塊。如果存在,則下面的每個塊都必須由單個空白行分隔,並且不得包含空白行。每個塊都必須按照下面列出的順序進行,儘管可以忽略不相關的塊。

開頭<?php標籤。
文件級文檔塊。
一個或多個聲明語句。
文件的名稱空間聲明。
一個或多個基於類的use導入語句。
一個或多個基於函數的use導入語句。
一個或多個基於常量的use導入語句。
文件中的其餘代碼。
當文件包含HTML和PHP的混合時,以上任何部分都可以使用。如果是這樣,即使代碼的其餘部分包含一個封閉的PHP標記,然後包含HTML和PHP,它們也必須出現在文件的頂部。

當開始<?php標記在文件的第一行時,它必須在自己的行上且沒有其他語句,除非它是一個包含PHP開頭和結束標記之外的標記的文件。

導入語句絕不能以反斜槓開頭,因爲它們必須始終完全合格。

以下示例說明了所有塊的完整列表:

<?php

/**
 * This file contains an example of coding styles.
 */

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use Vendor\Package\AnotherNamespace\ClassE as E;

use function Vendor\Package\{functionA, functionB, functionC};
use function Another\Vendor\functionD;

use const Vendor\Package\{CONSTANT_A, CONSTANT_B, CONSTANT_C};
use const Another\Vendor\CONSTANT_D;

/**
 * FooBar is an example class.
 */
class FooBar
{
    // ... additional PHP code ...
}
extends和implements

在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在接口的列表中,如果是接口,則extends可以分成多行,每行的後一行縮進一次。這樣做時,列表中的第一項必須位於下一行,並且每行必須只有一個接口。

<?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
}
抽象,最終和靜態

如果存在,則abstract和final聲明必須在可見性聲明之前。

如果存在,則static聲明必須在可見性聲明之後。

<?php

namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}
控制結構

控件結構的通用樣式規則如下:

控制結構關鍵字後面必須有一個空格
開頭括號後一定不能有空格
右括號前不得有空格
右括號和左括號之間必須有一個空格
結構體必須縮進一次
主體必須在開括號之後的下一行
右括號必須在主體之後的下一行
每個結構的主體必須用大括號括起來。

<?php

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

if (
    $expr1
    && $expr2
) {
    // if body
} elseif (
    $expr3
    && $expr4
) {
    // elseif body
}

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

switch (
    $expr1
    && $expr2
) {
    // structure body
}

while ($expr) {
    // structure body
}

while (
    $expr1
    && $expr2
) {
    // structure body
}

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

do {
    // structure body;
} while (
    $expr1
    && $expr2
);

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

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

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

try {
    // try body
} catch (FirstThrowableType $e) {
    // catch body
} catch (OtherThrowableType | AnotherThrowableType $e) {
    // catch body
} finally {
    // finally body
}
一元運算符

遞增/遞減運算符不得在運算符和操作數之間有任何空格。

$i++;
++$j;

類型轉換運算符的括號內不得有任何空格:

$intValue = (int) $input;
二元運算符

所有二進制算術,比較,賦值,按位, 邏輯,字符串和類型運算符都必須位於前綴和後跟至少一個空格:

if ($a === $b) {
    $foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
    $foo = $a + $b * $c;
}
三元運算符

條件運算符(也簡稱爲三元運算符)必須位於? 和:字符之前和之後至少一個空格:

$variable = $foo ? 'foo' : 'bar';

當省略條件運算符的中間操作數時,該運算符必須遵循與其他二進制比較運算符相同的樣式規則:

$variable = $foo ?: 'bar';
閉包

閉包必須在function關鍵字之後加一個空格,在關鍵字之前和之後加一個空格use。

開括號必須在同一行上,閉括號必須在主體之後的下一行上。

參數列表或變量列表的右括號後不得有空格,參數列表或變量列表的右括號前不得有空格。

在參數列表和變量列表中,每個逗號前面一定不能有空格,每個逗號後面一定不能有空格。

具有默認值的閉包參數必須位於參數列表的末尾。

如果存在返回類型,則它必須遵循與正常函數和方法相同的規則;如果存在use關鍵字,則冒號必須緊跟use列表結束括號,兩個字符之間不能有空格。

閉包聲明如下所示。請注意括號,逗號,空格和花括號的位置:

<?php

$closureWithArgs = function ($arg1, $arg2) {
    // body
};

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

$closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool {
    // body
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章