文章轉(zhuǎn)發(fā)自專業(yè)的Laravel開(kāi)發(fā)者社區(qū)卓起,原始鏈接:https://learnku.com/laravel/t/35080
編碼風(fēng)格擴(kuò)充指南
文章中的關(guān)鍵詞 MUST
磷蜀, MUST NOT
亮靴, REQUIRED
, SHALL
, SHALL NOT
坪仇, SHOULD
,
SHOULD NOT
垃你, RECOMMENDED
椅文, MAY
,和 OPTIONAL
都在 RFC 2119 中進(jìn)行來(lái)解釋惜颇。
摘要
此規(guī)范起到繼承皆刺,擴(kuò)展和替換 [PSR-2][] 的作用, 同時(shí)編碼風(fēng)格遵守 [PSR-1][] 這個(gè)基礎(chǔ)編碼標(biāo)準(zhǔn)凌摄。
和 [PSR-2][] 一樣羡蛾, 此規(guī)范的目的是減少不同人在閱讀代碼時(shí)認(rèn)知沖突。 它通過(guò)列舉一套如何格式化 PHP
代碼的公共的規(guī)則和期望來(lái)實(shí)現(xiàn)這個(gè)目標(biāo)锨亏。 PSR
力圖提供一套方法痴怨,編碼風(fēng)格工具可以利用忙干,項(xiàng)目可以遵守,開(kāi)發(fā)人員可以方便的在不同的項(xiàng)目中使用浪藻。當(dāng)各個(gè)的開(kāi)發(fā)人員在進(jìn)行多項(xiàng)目合作的時(shí)候捐迫,它可以幫助在這些項(xiàng)目中提供一套通用的指導(dǎo)。所以爱葵,本指南的價(jià)值不是規(guī)則本身施戴,而是這些規(guī)則的共享。
[PSR-2][] 在 2012 年被接受萌丈,隨后 PHP
經(jīng)歷了很多變化赞哗,影響了編碼風(fēng)格。同時(shí) [PSR-2] 是 PHP
編碼時(shí)候的基礎(chǔ)功能辆雾,被廣泛的采用肪笋。因此,PSR
力圖通過(guò)一種更加現(xiàn)代的方式說(shuō)明 PSR-2
的內(nèi)容和新功能度迂,并對(duì) PSR-2
進(jìn)行更正涂乌。
以前的語(yǔ)言版本
在整個(gè)文檔中,任何說(shuō)明都可以被忽略英岭,如果它們不存在于你項(xiàng)目所支持的 PHP 版本中湾盒。
例如
此示例包含以下一些規(guī)則作為快速概述:
<?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()
{
// 方法內(nèi)容
}
}
2. 總則
2.1 基本編碼標(biāo)準(zhǔn)
代碼必須遵循[PSR-1]中列出的所有規(guī)則。
PSR-1中的術(shù)語(yǔ) 'StudlyCaps' 必須解釋為 PascalCase (帕斯卡命名法:大駝峰式命名法)诅妹,其中每個(gè)單詞的第一個(gè)字母大寫罚勾,包括第一個(gè)字母。
2.2 文件
所有 PHP 文件只能使用Unix LF (換行符) 結(jié)尾吭狡。
所有的 PHP 文件都必須以非空行結(jié)尾尖殃,以一個(gè) LF 結(jié)尾。
在僅包含 PHP 代碼的文件中划煮,必須省略結(jié)尾的 送丰?>
標(biāo)記。
2.3 代碼行
行長(zhǎng)度不得有硬限制器躏。
行長(zhǎng)度的軟限制必須為120個(gè)字符。
行的長(zhǎng)度不應(yīng)超過(guò)80個(gè)字符揽浙;超過(guò)該長(zhǎng)度的行應(yīng)拆分為多個(gè)后續(xù)行馅巷,每個(gè)行的長(zhǎng)度不應(yīng)超過(guò)80個(gè)字符走敌。
行尾不能有尾隨空格。
可以添加空行以提高可讀性并指示相關(guān)的代碼塊,除非明確禁止纲刀。
每行不能有多個(gè)語(yǔ)句示绊。
2.4 縮進(jìn)
代碼必須為每個(gè)縮進(jìn)級(jí)別使用4個(gè)空格的縮進(jìn)面褐,并且不能使用縮進(jìn)標(biāo)簽展哭。
2.5 關(guān)鍵詞和類型
PHP 的所有關(guān)鍵字和類型 [1][2] 都必須使用小寫匪傍。
PHP未來(lái)版本中新加的所有關(guān)鍵字和類型也都必須使用小寫役衡。
類型關(guān)鍵字必須使用縮寫。使用 bool
而不是 boolean
柑船,使用 int
而不是 integer
等等。
3. 聲明及塘、命名空間以及導(dǎo)入
一個(gè)PHP文件的頭部可能會(huì)包含多個(gè)塊笙僚。如果包含多個(gè)塊肋层,則每個(gè)塊都必須用空白行和其他塊分隔,并且塊內(nèi)不能包含空白行栋猖。所有的塊都必須按照下面的順序排列汪榔,如果不存在該塊則忽略蒲拉。
- PHP文件開(kāi)始標(biāo)簽:
<?php
痴腌。 - 文件級(jí)文檔塊雌团。
- 一個(gè)或多個(gè)聲明語(yǔ)句。
- 命名空間聲明語(yǔ)句士聪。
- 一個(gè)或多個(gè)基于類的
use
聲明語(yǔ)句。 - 一個(gè)或多個(gè)基于方法的
use
聲明語(yǔ)句雨涛。 - 一個(gè)或多個(gè)基于常量的
use
聲明語(yǔ)句。 - 其余代碼。
當(dāng)文件包含HTML和PHP的混合代碼時(shí)胀糜,可以使用上面列出的任何部分距帅。如果是這種情況的話,即時(shí)代碼的其他部分包含有PHP結(jié)束符括堤,然后再包含HTML和PHP代碼碌秸,聲明绍移、命名空間和導(dǎo)入語(yǔ)句塊也必須放在文件的頂部。
什么時(shí)候開(kāi)始 <讥电?php
標(biāo)簽位于文件的第一行蹂窖,它必須位于自己的行,沒(méi)有其他語(yǔ)句恩敌,除非它是一個(gè)包含 PHP 之外的標(biāo)記的文件打開(kāi)和關(guān)閉標(biāo)記瞬测。
import語(yǔ)句不能以前導(dǎo)反斜杠開(kāi)頭,因?yàn)樗鼈儽仨毷冀K完全合格纠炮。
以下示例演示了所有塊的完整列表:
<?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代碼 ...
}
深度不能超過(guò)兩層的復(fù)合名稱空間月趟,因此以下展示了允許的最大復(fù)合深度。
<?php
use Vendor\Package\SomeNamespace\{
SubnamespaceOne\ClassA,
SubnamespaceOne\ClassB,
SubnamespaceTwo\ClassY,
ClassZ,
};
并且不允許以下內(nèi)容:
<?php
use Vendor\Package\SomeNamespace\{
SubnamespaceOne\AnotherNamespace\ClassA,
SubnamespaceOne\ClassB,
ClassZ,
};
當(dāng)希望在 PHP 外部包含標(biāo)記的文件中聲明嚴(yán)格類型時(shí)打開(kāi)和關(guān)閉標(biāo)簽恢口,聲明必須寫在文件的第一行并且包含在一個(gè)開(kāi)始的 PHP 標(biāo)簽孝宗,以及嚴(yán)格的類型聲明和結(jié)束標(biāo)簽。
例如:
<?php declare(strict_types=1) ?>
<html>
<body>
<?php
// ... 其他 PHP 代碼 ...
?>
</body>
</html>
聲明語(yǔ)句不能包含空格弧蝇,并且必須完全是 declare(strict_types=1)
(帶有可選的分號(hào)終止符)。
允許使用塊聲明語(yǔ)句折砸,并且必須按照以下的格式設(shè)置看疗。注意的位置括號(hào)和間距:
declare(ticks=1) {
// 一些代碼
}
4. 類,屬性睦授,和方法
這里的『類』指的是所有類两芳,接口,以及 trait 去枷。
任何注釋和語(yǔ)句 不得 跟在其右花括號(hào)后的同一行怖辆。
當(dāng)實(shí)例化一個(gè)類時(shí),后面的圓括號(hào) 必須 寫出來(lái)删顶,即使沒(méi)有參數(shù)傳進(jìn)其構(gòu)造函數(shù)竖螃。
new Foo();
4.1 繼承和實(shí)現(xiàn)
關(guān)鍵字 繼承
和 實(shí)現(xiàn)
必須 在類名的同一行聲明。
類的左花括號(hào) 必須 另起一行逗余;右花括號(hào) 必須 跟在類主體的下一行特咆。
類的左花括號(hào) 必須 獨(dú)自成行,且 不得 在其上一行或下一行存在空行录粱。
右花括號(hào) 必須 獨(dú)自成行腻格,且 不得 在其上一行存在空行。
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
// 常量啥繁,屬性菜职,方法
}
如果有接口, 實(shí)現(xiàn)
接口和 繼承
父類 可以 分為多行旗闽,前者每行需縮進(jìn)一次酬核。當(dāng)這么做時(shí)蜜另,第一個(gè)接口 必須 寫在下一行,且每行 必須 只能寫一個(gè)接口愁茁。
<?php
namespace Vendor\Package;
use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// 常量蚕钦,屬性,方法
}
4.2 使用 trait
在類里面用于實(shí)現(xiàn) trait 的關(guān)鍵字 use
必須 在左花括號(hào)的下一行聲明鹅很。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
}
每個(gè)導(dǎo)入類的 trait 必須 每行一個(gè)包含聲明嘶居,且每個(gè)包含聲明 必須 有其 use
導(dǎo)入語(yǔ)句。
<?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'之后沒(méi)有其他內(nèi)容了 邮屁,類名右大括號(hào)必須另起一行。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
}
如有其他內(nèi)容菠齿,兩者之間需空一行佑吝。
<?php
namespace Vendor\Package;
use Vendor\Package\FirstTrait;
class ClassName
{
use FirstTrait;
private $property;
}
當(dāng)使用' insteadof '和' as '運(yùn)算符時(shí),它們必須如圖所示使用绳匀,注意縮進(jìn)芋忿、間距和另起一行。
<?php
class Talker
{
use A, B, C {
B::smallTalk insteadof A;
A::bigTalk insteadof C;
C::mediumTalk as FooBar;
}
}
4.3 屬性和常量
所有屬性 必須 聲明可見(jiàn)性疾棵。
如果你的項(xiàng)目 PHP 最小版本支持常量可見(jiàn)性( PHP 7.1 或以上)戈钢,所有常量 必須 聲明可見(jiàn)性。
關(guān)鍵字 var
不得 用于聲明屬性是尔。
每條聲明語(yǔ)句 不得 聲明多于一個(gè)屬性殉了。
屬性名 不得 用單個(gè)下劃線開(kāi)頭表明其受保護(hù)的或私有的可見(jiàn)性。也就是說(shuō)拟枚,一個(gè)下劃線開(kāi)頭顯然是沒(méi)有意義的薪铜。
類型聲明和屬性名之間 必須 有一個(gè)空格。
一個(gè)屬性聲明看上去如下所示:
<?php
namespace Vendor\Package;
class ClassName
{
public $foo = null;
public static int $bar = 0;
}
4.4 方法和函數(shù)
所有的方法 必須 事先聲明類型恩溅。
方法命名 一定不可 用單個(gè)下劃線來(lái)區(qū)分是 protected
或 private
類型隔箍。也就是說(shuō),不要用一個(gè)沒(méi)有意義的下劃線開(kāi)頭脚乡。
方法和函數(shù)名稱中鞍恢,方法命名后面 一定不可 使用空格。方法開(kāi)始的花括號(hào) 必須 寫在方法聲明后自成一行每窖, 結(jié)束花括號(hào)也 必須 寫在方法后面自成一行帮掉。開(kāi)始左括號(hào)后和結(jié)束右括號(hào)前,都 一定不可 有空格符窒典。
一個(gè)方法的聲明應(yīng)該如下所示蟆炊。注意括號(hào),逗號(hào)瀑志,空格和花括號(hào)的位置:
<?php
namespace Vendor\Package;
class ClassName
{
public function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// 方法主體
}
}
一個(gè)函數(shù)的聲明應(yīng)該如下所示涩搓。注意括號(hào)污秆,逗號(hào),空格和花括號(hào)的位置:
<?php
function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
// 函數(shù)主體
}
4.5 方法和函數(shù)參數(shù)
在參數(shù)列表中昧甘, 不得 在每個(gè)逗號(hào)前存在空格良拼,且 必須 在每個(gè)逗號(hào)后有一個(gè)空格。
方法和函數(shù)中帶有默認(rèn)值的參數(shù) 必須 放在參數(shù)列表的最后充边。
<?php
namespace Vendor\Package;
class ClassName
{
public function foo(int $arg1, &$arg2, $arg3 = [])
{
// 方法主體
}
}
參數(shù)列表 可以 分為多行庸推,每行參數(shù)縮進(jìn)一次。當(dāng)這么做時(shí)浇冰,第一個(gè)參數(shù) 必須 放在下一行贬媒,且每行 必須 只能有一個(gè)參數(shù)。
當(dāng)參數(shù)列表分成多行時(shí)肘习,右圓括號(hào)和左花括號(hào) 必須 放在同一行且單獨(dú)成行际乘,兩者之間存在一個(gè)空格。
<?php
namespace Vendor\Package;
class ClassName
{
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = []
) {
// 方法主體
}
}
當(dāng)你定義一個(gè)返回值類型聲明時(shí)漂佩,冒號(hào)后面的類型聲明 必須 用空格符隔開(kāi)脖含。冒號(hào)和聲明 必須 在同一行,且跟參數(shù)列表后的結(jié)束括號(hào)之間沒(méi)有空格投蝉。
<?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';
}
}
在可空類型聲明中养葵,問(wèn)號(hào)和類型聲明之間不能有空格。
<?php
declare(strict_types=1);
namespace Vendor\Package;
class ReturnTypeVariations
{
public function functionName(?string $arg1, ?int &$arg2): ?string
{
return 'foo';
}
}
當(dāng)在參數(shù)之前使用引用運(yùn)算符 &
時(shí)墓拜,引用運(yùn)算符之后不能有空格港柜,例如上面的示例请契。
可變參數(shù)聲明的三個(gè)點(diǎn)和參數(shù)名稱之間不能有空格:
public function process(string $algorithm, ...$parts)
{
// 函數(shù)體
}
當(dāng)同時(shí)使用引用運(yùn)算符和可變參數(shù)運(yùn)算符時(shí)咳榜,它們之間不能有任何空格:
public function process(string $algorithm, &...$parts)
{
// 函數(shù)體
}
4.6 abstract
, final
, and static
如果是 abstract
and final
,那么申明的時(shí)候必須是可見(jiàn)性聲明爽锥。
如果是 static
涌韩,聲明必須位于可見(jiàn)性聲明之后。
<?php
namespace Vendor\Package;
abstract class ClassName
{
protected static $foo;
abstract protected function zim();
final public static function bar()
{
// 請(qǐng)求體
}
}
4.7 方法和函數(shù)的調(diào)用
當(dāng)我們?cè)谶M(jìn)行方法或者函數(shù)調(diào)用的時(shí)候氯夷,方法或函數(shù)與左括號(hào)之間不能出現(xiàn)空格臣樱,在右括號(hào)之后也不能出現(xiàn)空格,并且在右括號(hào)之前也一定不能有空格腮考。在參數(shù)列表中雇毫,每個(gè)逗號(hào)前面一定不能有空格,每個(gè)逗號(hào)后面也一定不能有空格踩蔚。
<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
參數(shù)列表可以分為多行棚放,每行后面縮進(jìn)一次。這個(gè)做之后馅闽,列表中的第一行必須位于下一行飘蚯,并且每一行必須只有一個(gè)參數(shù)馍迄。跨多個(gè)行拆分單個(gè)參數(shù)(就像匿名函數(shù)或者數(shù)組那樣)并不構(gòu)成拆分參數(shù)列表本身局骤。
<?php
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
<?php
somefunction($foo, $bar, [
// ...
], $baz);
$app->get('/hello/{name}', function ($name) use ($app) {
return 'Hello ' . $app->escape($name);
});
5. 流程控制
如下是主要的流程控制風(fēng)格規(guī)則:
- 流程控制關(guān)鍵詞之后 必須 要有一個(gè)空格
- 左括號(hào)后面 不能 有空格
- 右括號(hào)前面 不能 有空格
- 右括號(hào)與左大括號(hào)之間 必須 要有一個(gè)空格
- 流程主體 必須 要縮進(jìn)一次
- 流程主體 必須 在左大括號(hào)之后另起一行
- 右大括號(hào) 必須 在流程主體之后另起一行
每個(gè)流程控制主體 必須 以封閉的括號(hào)結(jié)束攀圈。這將標(biāo)準(zhǔn)化流程結(jié)構(gòu),同時(shí)減少由于流程中添加新的內(nèi)容而引入錯(cuò)誤的可能性峦甩。
5.1 if
, elseif
, else
if
結(jié)構(gòu)如下赘来。注意括號(hào),空格穴店,和大括號(hào)的位置撕捍;else
和 elseif
都在同一行,和右大括號(hào)一樣在主體的前面泣洞。
<?php
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
關(guān)鍵詞 elseif
應(yīng)該 替換 else if
忧风,這樣控制關(guān)鍵詞看起來(lái)像一個(gè)詞。
括號(hào)中的表達(dá)式 可能 會(huì)被分開(kāi)為多行球凰,每一行至少縮進(jìn)一次狮腿。如果這樣做,第一個(gè)條件 必須 在新的一行呕诉。右括號(hào)和左大括號(hào) 必須 在同一行缘厢,而且中間有一個(gè)空格。條件中間的布爾控制符 必須 在每一行的開(kāi)頭或者結(jié)尾甩挫,而不是混在一起贴硫。
<?php
if (
$expr1
&& $expr2
) {
// if body
} elseif (
$expr3
&& $expr4
) {
// elseif body
}
5.2 switch
, case
switch
結(jié)構(gòu)如下。注意括號(hào)伊者,空格和大括號(hào)的位置英遭。case
必須 縮進(jìn)一次從switch
開(kāi)始, break
關(guān)鍵詞 (或者其他終止關(guān)鍵詞) 必須 縮進(jìn)和 care
主體保持一致亦渗。必須 要有一個(gè)像 // 不終止
這樣的注釋在不為空且繼續(xù)的 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;
}
括號(hào)中的表達(dá)式 可能 會(huì)被分開(kāi)多行,每一行至少要縮進(jìn)一次法精。如果這樣做多律,第一個(gè)條件 必須 在新的一行。右括號(hào)和左大括號(hào) 必須 在同一行搂蜓,而且中間有一個(gè)空格狼荞。條件中間的布爾控制符 必須 在沒(méi)一行的開(kāi)頭或者結(jié)尾,而不是混在一起帮碰。
<?php
switch (
$expr1
&& $expr2
) {
// structure body
}
5.3 while
, do while
while
結(jié)構(gòu)如下相味。注意括號(hào),空格和大括號(hào)的位置收毫。
<?php
while ($expr) {
// structure body
}
括號(hào)中的表達(dá)式 可能 會(huì)被分開(kāi)多行攻走,沒(méi)一行至少要縮進(jìn)一次殷勘。如果這樣做,第一個(gè)條件 必須 在新的一行昔搂。右括號(hào)和左大括號(hào) 必須 在同一行玲销,而且中間有一個(gè)空格。條件中間的布爾控制符 必須 在沒(méi)一行的開(kāi)頭或者結(jié)尾摘符,而不是混在一起贤斜。
<?php
while (
$expr1
&& $expr2
) {
// structure body
}
同樣的, do while
申明如下逛裤。注意括號(hào)瘩绒,空格和大括號(hào)的位置。
<?php
do {
// structure body;
} while ($expr);
括號(hào)中的表達(dá)式 可能 會(huì)被分開(kāi)多行带族,沒(méi)一行至少要縮進(jìn)一次锁荔。如果這樣做,第一個(gè)條件 必須 在新的一行蝙砌。條件中間的布爾控制符 必須 在每一行的開(kāi)頭或者結(jié)尾阳堕,而不是混在一起。
<?php
do {
// structure body;
} while (
$expr1
&& $expr2
);
5.4 for
for
申明如下择克。注意括號(hào)恬总,空格和大括號(hào)的位置。
<?php
for ($i = 0; $i < 10; $i++) {
// for body
}
括號(hào)中的表達(dá)式 可能 會(huì)被分開(kāi)多行肚邢,每一行至少要縮進(jìn)一次壹堰。如果這樣做,第一個(gè)條件 必須 在新的一行骡湖。右括號(hào)和左大括號(hào) 必須 在同一行贱纠,而且中間有一個(gè)空格。
<?php
for (
$i = 0;
$i < 10;
$i++
) {
// for body
}
5.5 foreach
foreach
語(yǔ)句的寫法如下所示勺鸦。請(qǐng)注意它的圓括號(hào)并巍、空格和花括號(hào)目木。
<?php
foreach ($iterable as $key => $value) {
// 迭代主體
}
5.6 try
换途, catch
, finally
一個(gè) try-catch-finally
模塊包含下面這些內(nèi)容刽射。請(qǐng)注意它的圓括號(hào)军拟、空格和花括號(hào)。
<?php
try {
// try 主體
} catch (FirstThrowableType $e) {
// 捕獲異常主體
} catch (OtherThrowableType | AnotherThrowableType $e) {
// 捕獲異常主體
} finally {
// finally 主體
}
6. 運(yùn)算符
運(yùn)算符的樣式規(guī)則按元數(shù)分組(其接受的操作數(shù)個(gè)數(shù))誓禁。
當(dāng)運(yùn)算符周圍允許出現(xiàn)空格時(shí)懈息, 可以 出于可讀性目的打多個(gè)空格。
所有這里沒(méi)描述的運(yùn)算符暫不作限定摹恰。
6.1. 一元運(yùn)算符
遞增 / 遞減運(yùn)算符和操作數(shù)之間 不得 有任何空格辫继。
$i++;
++$j;
類型轉(zhuǎn)換運(yùn)算符的圓括號(hào)內(nèi)部 不得 有任何空格:
$intValue = (int) $input;
6.2. 二元運(yùn)算符
所有二進(jìn)制 算術(shù)怒见,比較,賦值姑宽,按位遣耍,邏輯、字符串和類型運(yùn)算符必須在前后跟至少一個(gè)空格:
if ($a === $b) {
$foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
$foo = $a + $b * $c;
}
6.3. 三元運(yùn)算符
條件運(yùn)算符炮车,也稱為三元運(yùn)算符舵变,必須在 ?
和 :
這兩個(gè)字符之間:
$variable = $foo ? 'foo' : 'bar';
如果省略條件運(yùn)算符的中間操作數(shù),運(yùn)算符必須遵循與其他二進(jìn)制比較運(yùn)算符相同的樣式規(guī)則:
$variable = $foo ?: 'bar';
7. 閉包(Closures)
閉包聲明時(shí)必須在 function
關(guān)鍵字后留有1個(gè)空格瘦穆,并且在 use
關(guān)鍵字前后各留有1個(gè)空格纪隙。
左花括號(hào)必須跟隨前文寫在同一行,右花括號(hào)必須在函數(shù)體后換行放置扛或。
不能在參數(shù)和變量的左括號(hào)后和右括號(hào)前放置空格绵咱。
不能在參數(shù)和變量的逗號(hào)前放置空格,但必須在逗號(hào)后放置1個(gè)空格熙兔。
閉包參數(shù)如果有默認(rèn)值麸拄,該參數(shù)必須放在參數(shù)列表末尾。
如果聲明了返回類型黔姜,它必須遵循普通函數(shù)和方法相同的規(guī)則;如果使用 use
關(guān)鍵字秆吵,冒號(hào)必須在 use
右括號(hào)后且冒號(hào)前后不能有空格淮椰。
閉包的聲明方式如下,留意括號(hào)纳寂,逗號(hào)主穗,空格和花括號(hào):
<?php
$closureWithArgs = function ($arg1, $arg2) {
// 函數(shù)體
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// 函數(shù)體
};
$closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool {
// 函數(shù)體
};
參數(shù)和變量可以分多行放置,每個(gè)后續(xù)行縮進(jìn)一次毙芜。執(zhí)行此操作時(shí)忽媒,列表中的第一項(xiàng)必須放在下一行,并且每行只能有一個(gè)參數(shù)或變量腋粥。
結(jié)束多行列表(或者參數(shù)晦雨,變量)的時(shí)候,右括號(hào)和左大括號(hào) 必須 要放在一行隘冲,而且中間有一個(gè)空格闹瞧。
下面是有和沒(méi)有多行參數(shù)列表與變量列表的閉包示例。
<?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
};
注意格式化規(guī)則也適用一個(gè)閉包在一個(gè)方法或者操作中作為參數(shù)被直接引用展辞。
<?php
$foo->bar(
$arg1,
function ($arg2) use ($var1) {
// body
},
$arg3
);
8. 匿名類
匿名類 必須 遵循上面章節(jié)中和閉包一樣的方針和準(zhǔn)則奥邮。
<?php
$instance = new class {};
只要 implements
接口列表不換行,左花括號(hào) 可以 和關(guān)鍵字 class
在同一行。如果接口列表?yè)Q行洽腺,花括號(hào) 必須 放在最后一個(gè)接口的下一行脚粟。
<?php
// 花括號(hào)在同一行
$instance = new class extends \Foo implements \HandleableInterface {
// 類內(nèi)容
};
// 花括號(hào)在下一行
$instance = new class extends \Foo implements
\ArrayAccess,
\Countable,
\Serializable
{
// 類內(nèi)容
};