翻译:薛粲
受权许可: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
代码必须遵循一份 PSR 编码样式指南 PSR-1。编码
代码必须使用 4 个空格而不是制表符做为缩进。spa
不得对行宽进行硬性限制;软性限制必须是 120 个字符;每行应该包含 80 个或者更少的字符。翻译
在 namespace
声明以后必须有一个空行,在 use
声明以后也必须有一个空行。设计
类的左花括号必须在下一行,右花括号必须在内容后的下一行。code
方法的左花括号必须在下一行,右花括号必须在内容后的下一行。
必须为全部属性和方法声明访问控制;abstract
和 final
必须在访问控制以前;static
必须在访问控制以后。
在控制结构的保留字后必须有一个空格;在方法和函数调用以后不得有空格。
控制结构的左花括号必须在同一行,右花括号必须在内容后的下一行。
控制结构的左括号以后不得有空格,右括号以前不得有空格。
这个例子做为一个简明的示例,涵盖了一些后面说起的规则:
<?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() { // 方法内容 } }
代码必须遵循 PSR-1 规范列出的全部规则。
全部 PHP 源文件必须使用 Unix LF (linefeed) 做为换行符。
全部 PHP 源文件必须以一个空行结束。
对于只包含 PHP 的文件,必须省略用于指示 PHP 段结束的 ?>
标记。
不得对行宽设置硬性限制。
对行宽的软性限制必须是 120 个字符;超出时自动样式检查必须发出警告但不得产生错误。
行不该该超过 80 个字符;超过的行应该分割为多个不超过 80 个字符的行。
非空的行不得以空白字符结束。
能够添加空行用于指出代码块的关联性以提高代码的可读性。
一行不得包含超过一个语句。
代码必须使用 4 个空格用于缩进,不得使用制表符用于缩进。
只使用空格,不混用空格和制表符,可以帮助避免查看差别、打补丁、查看历史以及批注时潜在的问题。使用空格还让跨行对齐时插入细粒度的子缩进更加容易。
PHP 保留字必须使用小写。
PHP 常量 true
、false
以及 null
必须使用小写。
若是存在,必须在 namespace
声明后加一个空行。
若是存在,全部 use
声明必须在 namespace
声明以后。
每一个声明必须要有一个 use
保留字。
在 use
块以后必须有一个空行。
例如:
<?php namespace Vendor\Package; use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; // ... additional PHP code ...
术语“类”指代全部的类、接口和 trait。
保留字 extends
和 implements
必须与类名位于同一行。
类的起始花括号必须独自一行;结束花括号必须在内容结束后的下一行。
<?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 }
必须为全部属性声明访问控制。
不得使用保留字 var
声明属性。
一条语句不得声明超过一个属性。
不该该使用单个下划线做为 protected
或 private
属性的访问控制的前缀。
属性声明看相似下面的例子。
<?php namespace Vendor\Package; class ClassName { public $foo = null; }
必须为全部方法声明访问控制。
不该该使用单个下划线做为 protected
或 private
方法的访问控制的前缀。
方法名后不得使用空格。左花括号必须独占一行,右花括号必须在内容以后的行。左括号后不得紧接一个空格,右括号前不得放置一个空格。
方法的声明相似下面的示例。请留意其中括号、逗号、空格以及花括号的位置:
<?php namespace Vendor\Package; class ClassName { public function fooBarBaz($arg1, &$arg2, $arg3 = []) { // method body } }
参数列表中,每一个逗号以前不得有空格,逗号以后必须跟着一个空格。
具备默认值的方法参数必须位于参数列表的最后面。
<?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 } }
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 } }
当进行一个方法或函数调用时,在方法名或函数名与左括号之间不得用空格隔开,左括号以后不得有空格。参数列表中,每一个逗号前不得有空格,每一个逗号以后必须有个空格。
<?php bar(); $foo->bar($arg1); Foo::bar($arg2, $arg3);
参数列表能够分割为多行,这些行只需缩进一次。当使用这种方式的时候,列表中的第一个参数必须位于新行,且每行必须只包含一个参数。
<?php $foo->bar( $longArgument, $longerArgument, $muchLongerArgument );
与控制结构相关的基本样式原则以下:
控制结构保留字以后必须有一个空格
左括号以后不得有空格
右括号以前不得有空格
右括号和左花括号直接必须有一个空格
结构体必须缩进一次
右花括号必须在内容后的下一行
每一个结构的内容必须使用花括号包裹。这能让控制结构看起来更加标准,并能减小向结构体中加入新语句致使错误的可能性。
if
、elseif
和 else
一个 if
结构看起来形以下面的示例。请留意其中括号、空格以及花括号的位置;留意 else
和 elseif
与以前内容的右花括号位于同一行。
<?php if ($expr1) { // if body } elseif ($expr2) { // elseif body } else { // else body; }
应该使用保留字 elseif
代替 else if
,这样,全部控制结构的保留字看起来都是单个单词。
switch
和 case
一个 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; }
while
和 do while
一个 while
语句看起来形以下面的示例。请留意其中括号、空格以及花括号的位置。
<?php while ($expr) { // structure body }
相似的,do while
语句看起来形以下面的示例。请留意其中括号、空格以及花括号的位置。
<?php do { // structure body; } while ($expr);
for
一个 for
语句看起来形以下面的示例。请留意其中括号、空格以及花括号的位置。
<?php for ($i = 0; $i < 10; $i++) { // for body }
foreach
一个 foreach
语句看起来形以下面的示例。请留意其中括号、空格以及花括号的位置。
<?php foreach ($iterable as $key => $value) { // foreach body }
try
和 catch
一个 try catch
块看起来形以下面的示例。请留意其中括号、空格以及花括号的位置。
<?php try { // try body } catch (FirstExceptionType $e) { // catch body } catch (OtherExceptionType $e) { // catch body }
闭包声明中保留字 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 );
这份规范有意的忽略了一些样式和实践准则,这些内容包括但不限于:
全局变量和全局常量的声明
函数的声明
操做符和赋值
跨行对齐
注释和文档块
类名的前缀和后缀
最佳实践
后续的推荐标准能够修订和扩展这份指南来涵盖这部分或更多其它的样式和实践准则。
在起草这份指南是,PHP FIG 小组对其有成员项目进行了问卷调查以决定哪些实践行为是最广泛的。原文在附录中包含了问卷调查的状况,译文略。