文章轉發自專業的Laravel開發者社區,原始連接: https://learnku.com/laravel/t...
文章中的關鍵詞 MUST
, MUST NOT
, REQUIRED
, SHALL
, SHALL NOT
, SHOULD
,SHOULD NOT
, RECOMMENDED
, MAY
,和 OPTIONAL
都在 [RFC 2119][] 中進行來解釋。php
此規範起到繼承,擴展和替換 [PSR-2][] 的做用, 同時編碼風格遵照 [PSR-1][] 這個基礎編碼標準。
和 [PSR-2][] 同樣, 此規範的目的是減小不一樣人在閱讀代碼時認知衝突。 它經過列舉一套如何格式化 PHP
代碼的公共的規則和指望來實現這個目標。 PSR
力圖提供一套方法,編碼風格工具能夠利用,項目能夠遵照,開發人員能夠方便的在不一樣的項目中使用。當各個的開發人員在進行多項目合做的時候,它能夠幫助在這些項目中提供一套通用的指導。因此,本指南的價值不是規則自己,而是這些規則的共享。html
[PSR-2][] 在 2012 年被接受,隨後 PHP
經歷了不少變化,影響了編碼風格。同時 [PSR-2] 是 PHP
編碼時候的基礎功能,被普遍的採用。所以,PSR
力圖經過一種更加現代的方式說明 PSR-2
的內容和新功能,並對 PSR-2
進行更正。laravel
在整個文檔中,任何說明均可以被忽略,若是它們不存在於你項目所支持的 PHP 版本中。數組
此示例包含如下一些規則做爲快速概述:閉包
<?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() { // 方法內容 } }
代碼必須遵循[PSR-1]中列出的全部規則。app
PSR-1中的術語 'StudlyCaps' 必須解釋爲 PascalCase (帕斯卡命名法:大駝峯式命名法),其中每一個單詞的第一個字母大寫,包括第一個字母。函數
全部 PHP 文件只能使用Unix LF (換行符) 結尾。工具
全部的 PHP 文件都必須以非空行結尾,以一個 LF 結尾。編碼
在僅包含 PHP 代碼的文件中,必須省略結尾的 ?>
標記。spa
行長度不得有硬限制。
行長度的軟限制必須爲120個字符。
行的長度不該超過80個字符;超過該長度的行應拆分爲多個後續行,每一個行的長度不該超過80個字符。
行尾不能有尾隨空格。
能夠添加空行以提升可讀性並指示相關的代碼塊,除非明確禁止。
每行不能有多個語句。
代碼必須爲每一個縮進級別使用4個空格的縮進,而且不能使用縮進標籤。
PHP 的全部關鍵字和類型 [[1]]關鍵字][類型] 都必須使用小寫。
PHP將來版本中新加的全部關鍵字和類型也都必須使用小寫。
類型關鍵字必須使用縮寫。使用 bool
而不是 boolean
,使用 int
而不是 integer
等等。
一個PHP文件的頭部可能會包含多個塊。若是包含多個塊,則每一個塊都必須用空白行和其餘塊分隔,而且塊內不能包含空白行。全部的塊都必須按照下面的順序排列,若是不存在該塊則忽略。
<?php
。use
聲明語句。use
聲明語句。use
聲明語句。當文件包含HTML和PHP的混合代碼時,可使用上面列出的任何部分。若是是這種狀況的話,即時代碼的其餘部分包含有PHP結束符,而後再包含HTML和PHP代碼,聲明、命名空間和導入語句塊也必須放在文件的頂部。
何時開始 <?php
標籤位於文件的第一行,它必須位於本身的行,沒有其餘語句,除非它是一個包含 PHP 以外的標記的文件打開和關閉標記。
import語句不能之前導反斜槓開頭,由於它們必須始終徹底合格。
如下示例演示了全部塊的完整列表:
<?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 { // ... 其餘php代碼 ... }
深度不能超過兩層的複合名稱空間,所以如下展現了容許的最大複合深度。
<?php use Vendor\Package\SomeNamespace\{ SubnamespaceOne\ClassA, SubnamespaceOne\ClassB, SubnamespaceTwo\ClassY, ClassZ, };
而且不容許如下內容:
<?php use Vendor\Package\SomeNamespace\{ SubnamespaceOne\AnotherNamespace\ClassA, SubnamespaceOne\ClassB, ClassZ, };
當但願在 PHP 外部包含標記的文件中聲明嚴格類型時打開和關閉標籤,聲明必須寫在文件的第一行而且包含在一個開始的 PHP 標籤,以及嚴格的類型聲明和結束標籤。
例如:
<?php declare(strict_types=1) ?> <html> <body> <?php // ... 其餘 PHP 代碼 ... ?> </body> </html>
聲明語句不能包含空格,而且必須徹底是 declare(strict_types=1)
(帶有可選的分號終止符)。
容許使用塊聲明語句,而且必須按照如下的格式設置。注意的位置括號和間距:
declare(ticks=1) { // 一些代碼 }
這裏的『類』指的是全部類,接口,以及 trait 。
任何註釋和語句 不得 跟在其右花括號後的同一行。
當實例化一個類時,後面的圓括號 必須 寫出來,即便沒有參數傳進其構造函數。
new Foo();
關鍵字 繼承
和 實現
必須 在類名的同一行聲明。
類的左花括號 必須 另起一行;右花括號 必須 跟在類主體的下一行。
類的左花括號 必須 獨自成行,且 不得 在其上一行或下一行存在空行。
右花括號 必須 獨自成行,且 不得 在其上一行存在空行。
<?php namespace Vendor\Package; use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class ClassName extends ParentClass implements \ArrayAccess, \Countable { // 常量,屬性,方法 }
若是有接口, 實現
接口和 繼承
父類 能夠 分爲多行,前者每行需縮進一次。當這麼作時,第一個接口 必須 寫在下一行,且每行 必須 只能寫一個接口。
<?php namespace Vendor\Package; use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class ClassName extends ParentClass implements \ArrayAccess, \Countable, \Serializable { // 常量,屬性,方法 }
在類裏面用於實現 trait 的關鍵字 use
必須 在左花括號的下一行聲明。
<?php namespace Vendor\Package; use Vendor\Package\FirstTrait; class ClassName { use FirstTrait; }
每一個導入類的 trait 必須 每行一個包含聲明,且每一個包含聲明 必須 有其 use
導入語句。
<?php namespace Vendor\Package; use Vendor\Package\FirstTrait; use Vendor\Package\SecondTrait; use Vendor\Package\ThirdTrait; class ClassName { use FirstTrait; use SecondTrait; use ThirdTrait; }
在類文件中,若是在使用'use Trait'以後沒有其餘內容了 ,類名右大括號必須另起一行。
<?php namespace Vendor\Package; use Vendor\Package\FirstTrait; class ClassName { use FirstTrait; }
若有其餘內容,二者之間需空一行。
<?php namespace Vendor\Package; use Vendor\Package\FirstTrait; class ClassName { use FirstTrait; private $property; }
當使用' insteadof '和' as '運算符時,它們必須如圖所示使用,注意縮進、間距和另起一行。
<?php class Talker { use A, B, C { B::smallTalk insteadof A; A::bigTalk insteadof C; C::mediumTalk as FooBar; } }
全部屬性 必須 聲明可見性。
若是你的項目 PHP 最小版本支持常量可見性( PHP 7.1 或以上),全部常量 必須 聲明可見性。
關鍵字 var
不得 用於聲明屬性。
每條聲明語句 不得 聲明多於一個屬性。
屬性名 不得 用單個下劃線開頭代表其受保護的或私有的可見性。也就是說,一個下劃線開頭顯然是沒有意義的。
類型聲明和屬性名之間 必須 有一個空格。
一個屬性聲明看上去以下所示:
<?php namespace Vendor\Package; class ClassName { public $foo = null; public static int $bar = 0; }
全部的方法 必須 事先聲明類型。
方法命名 必定不可 用單個下劃線來區分是 protected
或 private
類型。也就是說,不要用一個沒有意義的下劃線開頭。
方法和函數名稱中,方法命名後面 必定不可 使用空格。方法開始的花括號 必須 寫在方法聲明後自成一行, 結束花括號也 必須 寫在方法後面自成一行。開始左括號後和結束右括號前,都 必定不可 有空格符。
一個方法的聲明應該以下所示。注意括號,逗號,空格和花括號的位置:
<?php namespace Vendor\Package; class ClassName { public function fooBarBaz($arg1, &$arg2, $arg3 = []) { // 方法主體 } }
一個函數的聲明應該以下所示。注意括號,逗號,空格和花括號的位置:
<?php function fooBarBaz($arg1, &$arg2, $arg3 = []) { // 函數主體 }
在參數列表中, 不得 在每一個逗號前存在空格,且 必須 在每一個逗號後有一個空格。
方法和函數中帶有默認值的參數 必須 放在參數列表的最後。
<?php namespace Vendor\Package; class ClassName { public function foo(int $arg1, &$arg2, $arg3 = []) { // 方法主體 } }
參數列表 能夠 分爲多行,每行參數縮進一次。當這麼作時,第一個參數 必須 放在下一行,且每行 必須 只能有一個參數。
當參數列表分紅多行時,右圓括號和左花括號 必須 放在同一行且單獨成行,二者之間存在一個空格。
<?php namespace Vendor\Package; class ClassName { public function aVeryLongMethodName( ClassTypeHint $arg1, &$arg2, array $arg3 = [] ) { // 方法主體 } }
當你定義一個返回值類型聲明時,冒號後面的類型聲明 必須 用空格符隔開。冒號和聲明 必須 在同一行,且跟參數列表後的結束括號之間沒有空格。
<?php declare(strict_types=1); namespace Vendor\Package; class ReturnTypeVariations { public function functionName(int $arg1, $arg2): string { return 'foo'; } public function anotherFunction( string $foo, string $bar, int $baz ): string { return 'foo'; } }
在可空類型聲明中,問號和類型聲明之間不能有空格。
<?php declare(strict_types=1); namespace Vendor\Package; class ReturnTypeVariations { public function functionName(?string $arg1, ?int &$arg2): ?string { return 'foo'; } }
當在參數以前使用引用運算符 &
時,引用運算符以後不能有空格,例如上面的示例。
可變參數聲明的三個點和參數名稱之間不能有空格:
public function process(string $algorithm, ...$parts) { // 函數體 }
當同時使用引用運算符和可變參數運算符時,它們之間不能有任何空格:
public function process(string $algorithm, &...$parts) { // 函數體 }
abstract
, final
, and static
若是是 abstract
and final
,那麼申明的時候必須是可見性聲明。
若是是 static
,聲明必須位於可見性聲明以後。
<?php namespace Vendor\Package; abstract class ClassName { protected static $foo; abstract protected function zim(); final public static function bar() { // 請求體 } }
當咱們在進行方法或者函數調用的時候,方法或函數與左括號之間不能出現空格,在右括號以後也不能出現空格,而且在右括號以前也必定不能有空格。在參數列表中,每一個逗號前面必定不能有空格,每一個逗號後面也必定不能有空格。
<?php bar(); $foo->bar($arg1); Foo::bar($arg2, $arg3);
參數列表能夠分爲多行,每行後面縮進一次。這個作以後,列表中的第一行必須位於下一行,而且每一行必須只有一個參數。跨多個行拆分單個參數(就像匿名函數或者數組那樣)並不構成拆分參數列表自己。
<?php $foo->bar( $longArgument, $longerArgument, $muchLongerArgument );
<?php somefunction($foo, $bar, [ // ... ], $baz); $app->get('/hello/{name}', function ($name) use ($app) { return 'Hello ' . $app->escape($name); });
以下是主要的流程控制風格規則:
每一個流程控制主體 必須 以封閉的括號結束。這將標準化流程結構,同時減小因爲流程中添加新的內容而引入錯誤的可能性。
if
, elseif
, else
if
結構以下。注意括號,空格,和大括號的位置;else
和 elseif
都在同一行,和右大括號同樣在主體的前面。
<?php if ($expr1) { // if body } elseif ($expr2) { // elseif body } else { // else body; }
關鍵詞 elseif
應該 替換 else if
,這樣控制關鍵詞看起來像一個詞。
括號中的表達式 可能 會被分開爲多行,每一行至少縮進一次。若是這樣作,第一個條件 必須 在新的一行。右括號和左大括號 必須 在同一行,並且中間有一個空格。條件中間的布爾控制符 必須 在每一行的開頭或者結尾,而不是混在一塊兒。
<?php if ( $expr1 && $expr2 ) { // if body } elseif ( $expr3 && $expr4 ) { // elseif body }
switch
, case
switch
結構以下。注意括號,空格和大括號的位置。case
必須 縮進一次從switch
開始, break
關鍵詞 (或者其餘終止關鍵詞) 必須 縮進和 care
主體保持一致。必須 要有一個像 // 不終止
這樣的註釋在不爲空且繼續的 care
主體之中。
<?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; }
括號中的表達式 可能 會被分開多行,每一行至少要縮進一次。若是這樣作,第一個條件 必須 在新的一行。右括號和左大括號 必須 在同一行,並且中間有一個空格。條件中間的布爾控制符 必須 在沒一行的開頭或者結尾,而不是混在一塊兒。
<?php switch ( $expr1 && $expr2 ) { // structure body }
while
, do while
while
結構以下。注意括號,空格和大括號的位置。
<?php while ($expr) { // structure body }
括號中的表達式 可能 會被分開多行,沒一行至少要縮進一次。若是這樣作,第一個條件 必須 在新的一行。右括號和左大括號 必須 在同一行,並且中間有一個空格。條件中間的布爾控制符 必須 在沒一行的開頭或者結尾,而不是混在一塊兒。
<?php while ( $expr1 && $expr2 ) { // structure body }
一樣的, do while
申明以下。注意括號,空格和大括號的位置。
<?php do { // structure body; } while ($expr);
括號中的表達式 可能 會被分開多行,沒一行至少要縮進一次。若是這樣作,第一個條件 必須 在新的一行。條件中間的布爾控制符 必須 在每一行的開頭或者結尾,而不是混在一塊兒。
<?php do { // structure body; } while ( $expr1 && $expr2 );
for
for
申明以下。注意括號,空格和大括號的位置。
<?php for ($i = 0; $i < 10; $i++) { // for body }
括號中的表達式 可能 會被分開多行,每一行至少要縮進一次。若是這樣作,第一個條件 必須 在新的一行。右括號和左大括號 必須 在同一行,並且中間有一個空格。
<?php for ( $i = 0; $i < 10; $i++ ) { // for body }
foreach
foreach
語句的寫法以下所示。請注意它的圓括號、空格和花括號。
<?php foreach ($iterable as $key => $value) { // 迭代主體 }
try
, catch
, finally
一個 try-catch-finally
模塊包含下面這些內容。請注意它的圓括號、空格和花括號。
<?php try { // try 主體 } catch (FirstThrowableType $e) { // 捕獲異常主體 } catch (OtherThrowableType | AnotherThrowableType $e) { // 捕獲異常主體 } finally { // finally 主體 }
運算符的樣式規則按元數分組(其接受的操做數個數)。
當運算符周圍容許出現空格時, 能夠 出於可讀性目的打多個空格。
全部這裏沒描述的運算符暫不做限定。
遞增 / 遞減運算符和操做數之間 不得 有任何空格。
$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
關鍵字後留有1個空格,而且在 use
關鍵字先後各留有1個空格。
左花括號必須跟隨前文寫在同一行,右花括號必須在函數體後換行放置。
不能在參數和變量的左括號後和右括號前放置空格。
不能在參數和變量的逗號前放置空格,但必須在逗號後放置1個空格。
閉包參數若是有默認值,該參數必須放在參數列表末尾。
若是聲明瞭返回類型,它必須遵循普通函數和方法相同的規則;若是使用 use
關鍵字,冒號必須在 use
右括號後且冒號先後不能有空格。
閉包的聲明方式以下,留意括號,逗號,空格和花括號:
<?php $closureWithArgs = function ($arg1, $arg2) { // 函數體 }; $closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) { // 函數體 }; $closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool { // 函數體 };
參數和變量能夠分多行放置,每一個後續行縮進一次。執行此操做時,列表中的第一項必須放在下一行,而且每行只能有一個參數或變量。
結束多行列表(或者參數,變量)的時候,右括號和左大括號 必須 要放在一行,並且中間有一個空格。
下面是有和沒有多行參數列表與變量列表的閉包示例。
<?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 );
匿名類 必須 遵循上面章節中和閉包同樣的方針和準則。
<?php $instance = new class {};
只要 implements
接口列表不換行,左花括號 能夠 和關鍵字 class
在同一行。若是接口列表換行,花括號 必須 放在最後一個接口的下一行。
<?php // 花括號在同一行 $instance = new class extends \Foo implements \HandleableInterface { // 類內容 }; // 花括號在下一行 $instance = new class extends \Foo implements \ArrayAccess, \Countable, \Serializable { // 類內容 };