PSR-2:编码风格指南

编码风格指南

本指南扩展和扩展了基本编码标准PSR-1

本指南的目的是在扫描来自不同作者的代码时减少认知摩擦。它通过枚举一组共享规则和对如何格式化PHP代码的期望来实现。

这里的风格规则源于各个成员项目之间的共性。当各个作者跨多个项目进行协作时,在所有这些项目中使用一套指南会很有帮助。因此,本指南的好处不在于规则本身,而在于共享这些规则。

本文件中的关键词“必须”,“不得”,“必须”,“应该”,“不应该”,“应该”,“不应该”,“推荐”,“可以”和“可选”按照RFC 2119中的描述进行解释

1.概述

  • 代码必须遵循“编码风格指南”PSR [ PSR-1 ]。

  • 代码必须使用4个空格进行缩进,而不是制表符。

  • 线路长度不得有硬性限制; 软限制必须是120个字符; 线条不应该是80个字符或更少。

  • namespace声明后必须有一个空白行,并且声明块之后必须有一个空行use

  • 打开类的大括号必须在下一行,并且关闭大括号必须在主体之后的下一行。

  • 打开方法的大括号必须在下一行,并且关闭大括号必须在主体后面的下一行。

  • 必须在所有属性和方法上声明可见性; abstract并且 final必须在能见度之前宣布; 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 sampleMethod($a, $b = null)
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

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

2.一般

2.1。基本编码标准

代码必须遵循PSR-1中列出的所有规则

2.2。

所有PHP文件必须使用Unix LF(换行)行结尾。

所有PHP文件必须以一个空行结束。

?>必须从仅包含PHP的文件中省略结束标记。

2.3。

线路长度不得有硬性限制。

线长的软限制必须是120个字符; 自动样式检查器必须警告但不得在软限制上出错。

线条不应超过80个字符; 超过的行应该被分成多个后续行,每行不超过80个字符。

在非空白行的末尾不得有尾随空格。

可以添加空行以提高可读性并指示相关的代码块。

每行不得超过一个语句。

2.4。缩进

代码必须使用4个空格的缩进,并且不得使用制表符进行缩进。

Nb:仅使用空格,而不是将空格与制表符混合,有助于避免差异,补丁,历史记录和注释的问题。空间的使用还使得易于插入细粒度的子压痕用于线间对齐。

2.5。关键字和真/假/空

PHP 关键字必须是小写的。

PHP的常量truefalse以及null必须是小写。

3.命名空间和使用声明

如果存在,namespace声明后必须有一个空行

如果存在,所有use声明必须在namespace 声明之后。

use每个声明必须有一个关键字。

use之后必须有一个空行

例如:

<?php
namespace Vendor\Package;

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

// ... additional PHP code ...

4.类,属性和方法

术语“类”指的是所有类,接口和特征。

4.1。扩展和实施

extendsimplements关键字必须在同一行类名来声明。

班级的开口支架必须自成一线; 班级的结束括号必须在身体后面的下一行。

<?php
namespace Vendor\Package;

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

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}

implementsMAY 列表分为多行,每行后续行缩进一次。这样做时,列表中的第一项必须在下一行,并且每行必须只有一个接口。

<?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关键字不能被用于声明属性。

每个声明不得超过一个属性。

属性名称不应以单个下划线为前缀,以指示受保护或私有可见性。

属性声明如下所示。

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}

4.3。方法

必须在所有方法上声明可见性。

方法名称不应以单个下划线为前缀,以指示受保护或私有可见性。

方法名称不得在方法名称后面用空格声明。开口支撑必须沿着它自己的线,并且闭合支撑必须在身体后面的下一行。在左括号后面不能有空格,并且在右括号之前不能有空格。

方法声明如下所示。请注意括号,逗号,空格和大括号的位置:

<?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声明必须在可见性声明之后。

<?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。if,elseif,else

if结构如下所示。注意括号,空格和大括号的位置; 并且elseelseif早期身体的右大括号位于同一条线上。

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

elseif应该使用关键字而不是else if使所有控制关键字看起来像单个单词。

5.2。开关,案例

一个switch结构如下所示。请注意括号,空格和大括号的位置。case语句必须是从一次缩进switchbreak关键字(或其它终端关键字)必须在相同的水平缩进case体。必须有一个评论,例如 // no break在非空case中有意识地跌倒时

<?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。同时,做

一个while声明如下所示。请注意括号,空格和大括号的位置。

<?php
while ($expr) {
    // structure body
}

同样,do while语句如下所示。请注意括号,空格和大括号的位置。

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

5.4。对于

一个for声明如下所示。请注意括号,空格和大括号的位置。

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

5.5。的foreach

一个foreach声明如下所示。请注意括号,空格和大括号的位置。

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

5.6。试着抓

一个try catch块如下所示。请注意括号,空格和大括号的位置。

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

6.关闭

闭包必须在function关键字之后用空格声明,并关键字之前和之后用空格声明use

开口支撑必须在同一条线上,并且闭合支撑必须在身体后面的下一行。

在参数列表或变量列表的左括号之后不能有空格,并且在参数列表或变量列表的右括号之前不能有空格。

在参数列表和变量列表中,每个逗号前不能有空格,每个逗号后必须有一个空格。

具有默认值的闭包参数必须位于参数列表的末尾。

闭包声明如下所示。请注意括号,逗号,空格和大括号的位置:

<?php
$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.调查

在撰写本风格指南时,该小组对成员项目进行了调查,以确定常见做法。该调查在此保留给后人。

A.1。调查数据

url,http://www.horde.org/apps/horde/docs/CODING_STANDARDS,http://pear.php.net/manual/en/standards.php,http://solarphp.com/manual/appendix-standards.style,http://framework.zend.com/manual/en/coding-standard.html,https://symfony.com/doc/2.0/contributing/code/standards.html,http://www.ppi.io/docs/coding-standards.html,https://github.com/ezsystems/ezp-next/wiki/codingstandards,http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html,https://github.com/UnionOfRAD/lithium/wiki/Spec%3A-Coding,http://drupal.org/coding-standards,http://code.google.com/p/sabredav/,http://area51.phpbb.com/docs/31x/coding-guidelines.html,https://docs.google.com/a/zikula.org/document/edit?authkey=CPCU0Us&hgd=1&id=1fcqb93Sn-hR9c0mkN6m_tyWnmEvoswKBtSc0tKkZmJA,http://www.chisimba.com,n/a,https://github.com/Respect/project-info/blob/master/coding-standards-sample.php,n/a,Object Calisthenics for PHP,http://doc.nette.org/en/coding-standard,http://flow3.typo3.org,https://github.com/propelorm/Propel2/wiki/Coding-Standards,http://developer.joomla.org/coding-standards.html
voting,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,no,no,no,?,yes,no,yes
indent_type,4,4,4,4,4,tab,4,tab,tab,2,4,tab,4,4,4,4,4,4,tab,tab,4,tab
line_length_limit_soft,75,75,75,75,no,85,120,120,80,80,80,no,100,80,80,?,?,120,80,120,no,150
line_length_limit_hard,85,85,85,85,no,no,no,no,100,?,no,no,no,100,100,?,120,120,no,no,no,no
class_names,studly,studly,studly,studly,studly,studly,studly,studly,studly,studly,studly,lower_under,studly,lower,studly,studly,studly,studly,?,studly,studly,studly
class_brace_line,next,next,next,next,next,same,next,same,same,same,same,next,next,next,next,next,next,next,next,same,next,next
constant_names,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper,upper
true_false_null,lower,lower,lower,lower,lower,lower,lower,lower,lower,upper,lower,lower,lower,upper,lower,lower,lower,lower,lower,upper,lower,lower
method_names,camel,camel,camel,camel,camel,camel,camel,camel,camel,camel,camel,lower_under,camel,camel,camel,camel,camel,camel,camel,camel,camel,camel
method_brace_line,next,next,next,next,next,same,next,same,same,same,same,next,next,same,next,next,next,next,next,same,next,next
control_brace_line,same,same,same,same,same,same,next,same,same,same,same,next,same,same,next,same,same,same,same,same,same,next
control_space_after,yes,yes,yes,yes,yes,no,yes,yes,yes,yes,no,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes
always_use_control_braces,yes,yes,yes,yes,yes,yes,no,yes,yes,yes,no,yes,yes,yes,yes,no,yes,yes,yes,yes,yes,yes
else_elseif_line,same,same,same,same,same,same,next,same,same,next,same,next,same,next,next,same,same,same,same,same,same,next
case_break_indent_from_switch,0/1,0/1,0/1,1/2,1/2,1/2,1/2,1/1,1/1,1/2,1/2,1/1,1/2,1/2,1/2,1/2,1/2,1/2,0/1,1/1,1/2,1/2
function_space_after,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no
closing_php_tag_required,no,no,no,no,no,no,no,no,yes,no,no,no,no,yes,no,no,no,no,no,yes,no,no
line_endings,LF,LF,LF,LF,LF,LF,LF,LF,?,LF,?,LF,LF,LF,LF,?,,LF,?,LF,LF,LF
static_or_visibility_first,static,?,static,either,either,either,visibility,visibility,visibility,either,static,either,?,visibility,?,?,either,either,visibility,visibility,static,?
control_space_parens,no,no,no,no,no,no,yes,no,no,no,no,no,no,yes,?,no,no,no,no,no,no,no
blank_line_after_php,no,no,no,no,yes,no,no,no,no,yes,yes,no,no,yes,?,yes,yes,no,yes,no,yes,no
class_method_control_brace,next/next/same,next/next/same,next/next/same,next/next/same,next/next/same,same/same/same,next/next/next,same/same/same,same/same/same,same/same/same,same/same/same,next/next/next,next/next/same,next/same/same,next/next/next,next/next/same,next/next/same,next/next/same,next/next/same,same/same/same,next/next/same,next/next/next

A2。调查传奇

indent_type:缩进的类型。tab=“使用标签”,24=“空格数”

line_length_limit_soft:“软”行长度限制,以字符为单位。?=无法辨别或没有回应,no意味着没有限制。

line_length_limit_hard:“硬”行长度限制,以字符为单位。?=无法辨别或没有回应,no意味着没有限制。

class_names:如何命名类。lower=仅小写,lower_under=带下划线分隔符的小写,studly= StudlyCase。

class_brace_line:一个类的左大括号是same作为类关键字出现next在行上还是在它之后行上?

constant_names:类常量如何命名?upper=带有下划线分隔符的大写。

true_false_null:是truefalsenull关键字拼写为所有的lower情况下,或所有upper的情况下?

method_names:如何命名方法?camel= camelCaselower_under=带下划线分隔符的小写。

method_brace_line:方法的左括号是same作为方法名称还是next在行上?

control_brace_line:控制结构的开口支撑是same在线上还是next在线上?

control_space_after:控制结构关键字后面有空格吗?

always_use_control_braces:控制结构总是使用大括号吗?

else_elseif_line:当使用else或者elseif,它是否same作为前一个结束括号上next线,或者它是否在线上?

case_break_indent_from_switch开头陈述中有多少次casebreak缩进switch

function_space_after:函数调用在函数名后面和左括号之前有空格吗?

closing_php_tag_required:在仅包含PHP的文件中,是否?>需要结束标记?

line_endings:使用什么类型的行结尾?

static_or_visibility_first:当声明一个方法时,确实static是第一个,或者可见性是第一个?

control_space_parens:在控制结构表达式中,左括号后面是空格还是右括号前有空格?yes= if ( $expr )no= if ($expr)

blank_line_after_php:打开PHP标签后是否有空行?

class_method_control_brace:关于类,方法和控制结构的开头括号的内容摘要。

A.3。调查结果

indent_type:
    tab: 7
    2: 1
    4: 14
line_length_limit_soft:
    ?: 2
    no: 3
    75: 4
    80: 6
    85: 1
    100: 1
    120: 4
    150: 1
line_length_limit_hard:
    ?: 2
    no: 11
    85: 4
    100: 3
    120: 2
class_names:
    ?: 1
    lower: 1
    lower_under: 1
    studly: 19
class_brace_line:
    next: 16
    same: 6
constant_names:
    upper: 22
true_false_null:
    lower: 19
    upper: 3
method_names:
    camel: 21
    lower_under: 1
method_brace_line:
    next: 15
    same: 7
control_brace_line:
    next: 4
    same: 18
control_space_after:
    no: 2
    yes: 20
always_use_control_braces:
    no: 3
    yes: 19
else_elseif_line:
    next: 6
    same: 16
case_break_indent_from_switch:
    0/1: 4
    1/1: 4
    1/2: 14
function_space_after:
    no: 22
closing_php_tag_required:
    no: 19
    yes: 3
line_endings:
    ?: 5
    LF: 17
static_or_visibility_first:
    ?: 5
    either: 7
    static: 4
    visibility: 6
control_space_parens:
    ?: 1
    no: 19
    yes: 2
blank_line_after_php:
    ?: 1
    no: 13
    yes: 8
class_method_control_brace:
    next/next/next: 4
    next/next/same: 11
    next/same/same: 1
    same/same/same: 6