PHP 代码风格规范 PSR-2 (中文版)

PHP 代码风格规范 PSR-2

本篇规范是 PSR-1 基本代码规范的继承与扩展。 本规范但愿经过制定一系列规范化PHP代码的规则,以减小在浏览不一样做者的代码时,因代 码风格的不一样而形成不便。 当多名程序员在多个项目中合做时,就须要一个共同的编码规范, 而本文中的风格规范源自 于多个不一样项目代码风格的共同特性, 所以,本规范的价值在于咱们都遵循这个编码风格, 而不是在于它自己。php

关键词 “必须”("MUST")、“必定不可/必定不能”("MUST NOT")、“需 要”("REQUIRED")、 “将会”("SHALL")、“不会”("SHALL NOT")、“应 该”("SHOULD")、“不应”("SHOULD NOT")、 “推荐”("RECOMMENDED")、“可 以”("MAY")和”可选“("OPTIONAL")的详细描述可参见 RFC 2119 。程序员

1. 概述

  • 代码必须遵照 PSR-1。闭包

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

  • 每行应该保持在80个字符之内,软限制必须是120个字符,但必定不能有硬性限制。编码

  • 在命名空间(namespace)的声明下面必须有一行空行,而且在导入(use)的声明下面也必须有一行空行。spa

  • 类(class)的左花括号({)必须放到其声明下面自成一行,右花括号(})则必须放到类主体下面自成一行。代码规范

  • 方法(method)的左花括号({)必须放到其声明下面自成一行,右花括号(})则必须放到方法主体的下一行。code

  • 在全部的属性和方法上都必须声明可见性(译者注:privateprotected以及public);abstractfinal必须声明在可见性以前;static必须声明在可见性以后。继承

  • 在控制结构关键字的后面必须有一个空格;而方法(method)和函数(function)的关键字的后面不可有空格。接口

  • 控制结构的左花括号必须跟其放在同一行,右花括号必须放在该控制结构代码主体的下一行。

  • 控制结构的左括号以后不可有空格,右括号以前也不可有空格。

1.1. 示例

这个示例中简单展现了上文中提到的一些规则:

<?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()
    {
        // 方法主体
    }
}

2. 通则

2.1 基础代码规范

代码必须遵照 PSR-1 中的全部规则。

2.2 源文件

全部的PHP源文件必须使用Unix LF(换行)做为行结束符。

全部PHP源文件必须以一个空行结束。

纯PHP代码源文件的关闭标签?> 必须省略。

2.3. 行

行长度不可有硬限制。

行长度的软限制必须是120个字符;对于软限制,代码风格检查器必须警告但不可报错。

一行代码的长度不建议超过80个字符;较长的行建议拆分红多个不超过80个字符的子行。

在非空行后面不可有空格。

空行能够用来加强可读性和区分相关代码块。

一行不可多于一个语句。

2.4.

缩进

代码必须使用4个空格,且不可以使用制表符来做为缩进。

注意:代码中只使用空格,且不和制表符混合使用,将会对避免代码差别,补丁,历史和注解中的一些问题有帮助。空格的使用还可使经过调整细微的缩进来改进行间对齐变得更加的简单。

2.5.

关键字和 True/False/Null

PHP关键字(keywords)必须使用小写字母。

PHP常量true, false和null 必须使用小写字母。

3. 命名空间(Namespace)和导入(Use)声明

命名空间(namespace)的声明后面必须有一行空行。

全部的导入(use)声明必须放在命名空间(namespace)声明的下面。

一句声明中,必须只有一个导入(use)关键字。

在导入(use)声明代码块后面必须有一行空行。

示例:

<?php
namespace Vendor\Package;

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

// ... 其它PHP代码 ...

4. 类(class),属性(property)和方法(method)

术语“类”指全部的类(class),接口(interface)和特性(trait)。

4.1. 扩展(extend)和实现(implement)

一个类的扩展(extend)和实现(implement)关键词必须和类名(class name)在同一行。

类(class)的左花括号必须放在下面自成一行;右花括号必须放在类(class)主体的后面自成一行。

<?php
namespace Vendor\Package;

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

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // 常量、属性、方法
}

实现(implement)列表能够被拆分为多个缩进了一次的子行。若是要拆成多个子行,列表的第一项必需要放在下一行,而且每行必须只有一个接口(interface)。

<?php
namespace Vendor\Package;

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

class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // 常量、属性、方法
}

4.2. 属性(property)

全部的属性(property)都必须声明其可见性。

变量(var)关键字不可用来声明一个属性(property)。

一条语句不可声明多个属性(property)。

属性名(property name) 不推荐用单个下划线做为前缀来代表其保护(protected)或私有(private)的可见性。

一个属性(property)声明看起来应该像下面这样。

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}

4.3. 方法(method)

全部的方法(method)都必须声明其可见性。

方法名(method name) 不推荐用单个下划线做为前缀来代表其保护(protected)或私有(private)的可见性。

方法名(method name)在其声明后面不可有空格跟随。其左花括号必须放在下面自成一行,且右花括号必须放在方法主体的下面自成一行。左括号后面不可有空格,且右括号前面也不可有空格。

一个方法(method)声明看来应该像下面这样。 注意括号,逗号,空格和花括号的位置:

<?php
namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // 方法主体部分
    }
}

4.4. 方法(method)的参数

在参数列表中,逗号以前不可有空格,而逗号以后则必需要有一个空格。

方法(method)中有默认值的参数必须放在参数列表的最后面。

<?php
namespace Vendor\Package;

class ClassName
{
    public function foo($arg1, &$arg2, $arg3 = [])
    {
        // 方法主体部分
    }
}

参数列表能够被拆分为多个缩进了一次的子行。若是要拆分红多个子行,参数列表的第一项必须放在下一行,而且每行必须只有一个参数。

当参数列表被拆分红多个子行,右括号和左花括号之间必须又一个空格而且自成一行。

<?php
namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // 方法主体部分
    }
}

4.5. 抽象(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()
    {
        // 方法主体部分
    }
}

4.6.

调用方法和函数

调用一个方法或函数时,在方法名或者函数名和左括号之间不可有空格,左括号以后不可有空格,右括号以前也不可有空格。参数列表中,逗号以前不可有空格,逗号以后则必须有一个空格。

<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);


参数列表能够被拆分红多个缩进了一次的子行。若是拆分红子行,列表中的第一项必须放在下一行,而且每一行必须只能有一个参数。

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

5.

控制结构

下面是对于控制结构代码风格的归纳: 控制结构的关键词以后必须有一个空格。控制结构的左括号以后不可有空格。控制结构的右括号以前不可有空格。控制结构的右括号和左花括号之间必须有一个空格。控制结构的代码主体必须进行一次缩进。控制结构的右花括号必须主体的下一行。 每一个控制结构的代码主体必须被括在花括号里。这样但是使代码看上去更加标准化,而且加入新代码的时候还能够所以而减小引入错误的可能性。

5.1. if,elseif,else

下面是一个if条件控制结构的示例,注意其中括号,空格和花括号的位置。同时注意else和elseif要和前一个条件控制结构的右花括号在同一行。

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

推荐用elseif来替代else if,以保持全部的条件控制关键字看起来像是一个单词。

5.2. switch,case

下面是一个switch条件控制结构的示例,注意其中括号,空格和花括号的位置。case语句必需要缩进一级,而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;
}

5.3. while,do

while

下面是一个while循环控制结构的示例,注意其中括号,空格和花括号的位置。

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

下面是一个do while循环控制结构的示例,注意其中括号,空格和花括号的位置。

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

5.4. for

下面是一个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

下面是一个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.

以上规范不免有疏忽,其中包括但不只限于:

  • 全局变量和全局常量的声明

  • 函数声明

  • 操做符和赋值

  • 行间对齐

  • 注释和文档块

  • 类名的前缀和后缀

  • 最佳实践

之后的代码规范中可能会修正或扩展本指南中规定的代码风格。

相关文章
相关标签/搜索