PHP 编码风格规范指南

本指罗列了通用的PHP代码格式规则和建议,意在减少不同作者的编码风格差异带来的认知障碍。

  为了尽可能的提升阅读其他人代码时的效率,下面例举了一系列的通用规则,特别是有关于PHP代码风格的。各个成员项目间的共性组成了这组代码规范。当开发者们在多个项目中合作时,本指南将会成为所有这些项目中共用的一组代码规范。
因此,本指南的益处不在于这些规则本身,而在于在所有项目中共用这些规则。

说起码代码,刚上大学那会,老师就教导我们,要严格,规范的,把代码写好。代码如人,工工整整。提起规范化的代码,从一开始用命令行编辑C语言代码就开始控制,强制自己按照相关的标准来,所以,现在写代码,不规范都不行,还是为当时打下的好习惯给自己点个赞。

这里的风格约定衍生自若干成员项目。指南作者们在多个项目中协作,推动了这些指导条款落地。
指南的关键在于共享,而不是规则本身。

1. 概述

  • 代码必须遵守 PSR-1。

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

  • 一行代码的长度不建议有硬限制;软限制必须为120个字符,建议每行代码80个字符或者更少。

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

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

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

  • 所有的属性(property)方法(method) 必须有可见性声明;抽象(abstract)终结(final)声明必须在可见性声明之前;而静态(static)声明必须在可见性声明之后。

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

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

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

现在写到了PHP,对于PHP,是否也有相关的代码规范呢,当然,你或许在阅读其他博客或者PHP相关文档的时候经常提到这几个名词,PSR-1,PSR-2之类的,这是PHP-FIG制定的推荐规范,今天,我们就来讲解下PHP的推荐标准,PSR(PHP
Standards Recommendation)。

文中涉及的关键词 “MUST 必须”, “MUST NOT 必须不”, “REQUIRED 必需”, “SHALL
会”, “SHALL NOT 不会”, “SHOULD 应该”, “SHOULD NOT 不应该”, “RECOMMENDED
推荐的”, “MAY 可能”, 和 “OPTIONAL 可选的” 在RFC 2119 中有具体描述.

1.1. 示例

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

namespace VendorPackage;

use FooInterface;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

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

注:PHP-FIG已经废弃了第一份推荐规范,PSR-0,第一份推荐规范被新发布的PSR-4替代了。

概览

  1. 代码必需遵循 “基础编码标准” PSR [PSR-1]。
  2. 代码缩进必须使用 4 空格,而不是tab。
  3. 行长度必须无硬性限制; 软性限制必须为120字符;应该少于等于80字。
  4. namespace声明后必须有一个空行,use声明后也必须有一个空行。
  5. 类的{ 必须在类名的下一行, }必须在body的下一行。
  6. 方法的 { 必须在方法签名的下一行,} 必须在body的下一行。
  7. 所有的属性和方法都要设置可见性; abstract和
    final必须在可见性之前声明;static 必须在可见性后声明。
  8. 结构控制关键词后必须有一个空格; 方法和函数必须没有空格。
  9. 结构控制的 { 必须在同一行,} 必须在body的下一行。
  10. 结构控制的 ( 后必须有空格, 结构控制的 ) 前必须没有空格。

2. 通则

PSR-1 : 基本的代码风格 :

例子

下面是一个综合的例子,可以帮助你对规则有一个概略的认识。

<?php
namespace VendorPackage;

use FooInterface;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

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()
    {
        // 方法 body
    }
}

2.1 基础代码规范

代码必须遵守 PSR-1 中的所有规则。

图片 1

基本规则

2.2 源文件

所有的PHP源文件必须使用Unix LF(换行)作为行结束符。

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

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

PSR-2 : 严格的代码风格 :

基本编码标准

代码必须遵循PSR-1的条款。

2.3. 行

行长度不可有硬限制。

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

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

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

空行可以用来增强可读性和区分相关代码块。

一行不可多于一个语句。

图片 2

文件

  1. 所有文件必须使用 Unix LF (linefeed) 换行。
  2. 所有PHP文件必须使用单个空行结束。
  3. 只包含PHP的代码必须忽略php结束标记 ? >。

2.4. 缩进

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

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

PSR-3 : 日志记录器接口 :

  1. 行长度必须没有硬性限制。
  2. 长度的软性限制必须为120字符;自动代码风格检查必须将120字设置为警告,必须不能设置为错误。
  3. 行不应该超过80字符;超过这个长度的行应该切分为多个不超过80字符的行。
  4. 非空行的结束必须没有尾随空格。
  5. 为增强可读性,可增加空行来标志代码的关联性。
  6. 每行包含的语句必须不能超过1条。

2.5. 关键字和 True/False/Null

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

PHP常量truefalsenull 必须使用小写字母。

图片 3

缩进

  1. 代码必须使用 4 空格的缩进, 必须不用tab作为缩进。

注意:只使用空格,不用tab,有助于避免diffs,patches,
history和annotations的问题。使用空格也有助于对齐。

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

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

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

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

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

示例:

namespace VendorPackage;

use FooClass;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

// … 其它PHP代码 …

PSR-4 : 自动加载 :

关键词(保留字) 和 true/false/null

  1. PHP保留字必须小写.
  2. PHP常量 true, false和 null 必须小写.

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

术语“类”指所有的类(class)接口(interface)特性(trait)

图片 4

Namespace 和 Use 声明

  1. namespace 声明之后必须有空行。
  2. 所有use 声明,必须在namespace声明之后。
  3. 每个声明必须单独使用一个use。
  4. use声明区之后必须有一个空行。

例如:

<?php
namespace VendorPackage;

use FooClass;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

// ... additional PHP code ...

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

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

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

namespace VendorPackage;

use FooClass;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

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

实现(implement)列表可以被拆分为多个缩进了一次的子行。如果要拆成多个子行,列表的第一项必须要放在下一行,并且每行必须只有一个接口(interface)

namespace VendorPackage;

use FooClass;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

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

上述网址需要连接vpn方能打开,没有vpn?去买一个吧,一年也就几十块钱。

类, 属性 和 方法

这里的“类”包括 class、interface 和 trait。

4.2. 属性(property)

所有的属性(property)必须声明其可见性。

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

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

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

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

namespace VendorPackage;

class ClassName
{
public $foo = null;
}

今天给大家带来的主要是编码规范,PSR-1,PSR-2关于代码风格规范的。

继承 和 实现

extends 和 implements 关键字必须和类名在同一行声明。

类的 { 必须独占一行; } 必须在body的下一行。

<?php
namespace VendorPackage;

use FooClass;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

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

implements
多个接口时,接口列表可以被分到多行,每个子行有一个缩进。如果这么做,第一个接口必须在implements
下一行,每行只能有一个接口。

<?php
namespace VendorPackage;

use FooClass;
use BarClass as Bar;
use OtherVendorOtherPackageBazClass;

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

4.3. 方法(method)

所有的方法(method)必须声明其可见性。

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

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

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

namespace VendorPackage;

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

PSR-1 基本代码风格

属性

所有属性都必须声明 visibility(可见性)。

Var 关键字必须不能用于声明属性。

每行必须只声明一个属性。

不应该通过前缀下划线来标示protected和private的属性。

例:

<?php
namespace VendorPackage;

class ClassName
{
    public $foo = null;
}

4.4. 方法(method)的参数

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

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

namespace VendorPackage;

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

参数列表可以被拆分为多个缩进了一次的子行。如果要拆分成多个子行,参数列表的第一项必须放在下一行,并且每行必须只有一个参数。

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

namespace VendorPackage;

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

总览

  • Files MUST use only<?phpand<?=tags.

  • Files MUST use only UTF-8 without BOM for PHP code.

  • Files SHOULDeitherdeclare symbols (classes, functions, constants,
    etc.)orcause side-effects (e.g. generate output, change .ini
    settings, etc.) but SHOULD NOT do both.

  • Namespaces and classes MUST follow an “autoloading” PSR:
    [PSR-0,PSR-4].

  • Class names MUST be declared inStudlyCaps.

  • Class constants MUST be declared in all upper case with underscore
    separators.

  • Method names MUST be declared incamelCase.

方法

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

不应该通过前缀下划线来标示protected和private的方法。

声明方法时,方法名的后必须没有空格。 { 必须在同一行, }
必须在body的下一行。 (后必须没有空格,) 前必须没有空格。

一个方法声明的例子如下,注意 小括号,逗号,空格 和 花括号 的位置:

<?php
namespace VendorPackage;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

4.5. 抽象(abstract)终结(final)和 静态(static)

当用到抽象(abstract)终结(final)来做类声明时,它们必须放在可见性声明的前面。

而当用到静态(static)来做类声明时,则必须放在可见性声明的后面。

namespace VendorPackage;

abstract class ClassName
{
protected static $foo;

abstract protected function zim();

final public static function bar()
{
// 方法主体部分
}
}

PHP标签

PHP code MUST use the long<?php ?>tags or the short-echo<?= ?>tags;
it MUST NOT use the other tag variations.

方法参数

方法的形参列表中,
每个逗号前必须没有空格。有默认值的参数必须在参数列表的最后。

<?php
namespace VendorPackage;

class ClassName
{
    public function foo($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

参数列表可以切分为多行,每个子行要有一个缩进。如果这么做,第一个参数必须独占一行,每行只能有一个参数。

参数列表切分为多行时,右括号)和左花括号{必须在同一行,之前必须有一个空格。

<?php
namespace VendorPackage;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // method body
    }
}

4.6. 调用方法和函数

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

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

参数列表可以被拆分成多个缩进了一次的子行。如果拆分成子行,列表中的第一项必须放在下一行,并且每一行必须只能有一个参数。

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

编码

PHP code MUST use only UTF-8 without BOM.

abstract, final 和 static

abstract和final声明必须在可见性之前声明。
static声明必须在可见性之后。

<?php
namespace VendorPackage;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

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

5. 控制结构

下面是对于控制结构代码风格的概括:

  • 控制结构的关键词之后必须有一个空格。

  • 控制结构的左括号之后不可有空格。

  • 控制结构的右括号之前不可有空格。

  • 控制结构的右括号和左花括号之间必须有一个空格。

  • 控制结构的代码主体必须进行一次缩进。

  • 控制结构的右花括号必须主体的下一行。

每个控制结构的代码主体必须被括在花括号里。这样可是使代码看上去更加标准化,并且加入新代码的时候还可以因此而减少引入错误的可能性。

作用,类、方法、常量不能让人产生歧义

A file SHOULD declare new symbols (classes, functions, constants, etc.)
and cause no other side effects, or it SHOULD execute logic with side
effects, but SHOULD NOT do both.

The following is an example of a file with both declarations and side
effects; i.e, an example of what to avoid:

<?php// side effect: change ini settingsini_set('error_reporting', E_ALL);// side effect: loads a fileinclude "file.php";// side effect: generates outputecho "<html>n";// declarationfunction foo(){    // function body}

The following example is of a file that contains declarations without
side effects; i.e., an example of what to emulate:

<?php// declarationfunction foo(){    // function body}// conditional declaration is *not* a side effectif (! function_exists('bar')) {    function bar()    {        // function body    }}

方法和函数调用

写方法或函数调用时,方法/函数名 和 左括号( 之间,必须没有空格, 右括号
)
之前必须没有空格。在参数列表中,逗号间必须没有逗号,每个逗号后必须有一个空格。

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

5.1. ifelseifelse

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

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

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

命名空间和类名

Each class is in a file by itself, and is in a namespace of at least one
level: a top-level vendor name.The term “class” refers to all classes,
interfaces, and traits(性状,类的部分实现).

Code written for PHP 5.3 and after
MUST use formal namespaces.

For example:

<?php// PHP 5.3 and later:namespace VendorModel;class Foo{}

控制结构

控制结构通常遵循以下风格:

  1. 控制结构关键词后必须有一个空格。
  2. 左括号后必须没有空格。
  3. 右括号前必须没有空格。
  4. 又括号和左花括号之间必须有一个空格。
  5. body必须有一层缩进。
  6. 右花括号必须在body下一行。
  7. 每个控制结构的body必须用花括号括起来。
    即保证外观统一,又减少了添加新行时引入的错误。

5.2. switchcase

下面是一个switch条件控制结构的示例,注意其中括号,空格和花括号的位置。case语句必须要缩进一级,而break关键字(或其他中止关键字)必须case结构的代码主体在同一个缩进层级。如果一个有主体代码的case结构故意的继续向下执行则必须要有一个类似于// no break的注释。

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;
}

常量

Class constants MUST be declared in all upper case with underscore
separators. (全部大写,下面可以加下划线)For example:

<?phpnamespace VendorModel;class Foo{    const VERSION = '1.0';    const DATE_APPROVED = '2012-06-01';}

if, elseif, else

if 结构如下所示。注意括号、空格、花括号的位置;同时留意 else 和 elseif
与前一部分的 } 在同一行。

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

elseif关键字不应该被 else if 代替。

5.3. whiledo while

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

while ($expr) {
// structure body
}

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

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

变量

This guide intentionally avoids any recommendation regarding the use
of$StudlyCaps,$camelCase, or$under_scoreproperty names.
(枫爷这里建议变量采用下划线,不要使用驼峰命名法)

switch, case

Switch结构如下所示。注意括号、空格和花括号的位置。 case
语句相对于switch必须有一个缩进, break关键字
或者其他终结性的关键字必须和case body在同一缩进层级。在非空的case
body,如果没有终结性语句,必须加上注释 // 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.4. for

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

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

方法

Method names MUST be declared incamelCase().
(方法命名采用驼峰命名法)

while, do while

while结构如下所示。 注意括号、空格和花括号的位置。

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

do-while接口如下所示。 注意括号、空格和花括号的位置。

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

5.5. foreach

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

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

PSR-2 严格代码风格

用官网的话说,这是代码规范,PSR-1只是基本代码规范,如果大家只想要基本的,那下面的内容可以忽略哈,我个人建议还是按照此代码规范来。

for

for 结构如下所示。 注意括号、空格和花括号的位置。

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

5.6. trycatch

下面是一个try catch异常处理控制结构的示例,注意其中括号,空格和花括号的位置。

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

总览

  • Code MUST follow a “coding style guide” PSR [PSR-1].

  • Code MUST use 4 spaces for indenting, not tabs.

  • There MUST NOT be a hard limit on line length; the soft limit MUST
    be 120 characters; lines SHOULD be 80 characters or less.

  • There MUST be one blank line after thenamespacedeclaration, and
    there MUST be one blank line after the block ofusedeclarations.

  • Opening braces for classes MUST go on the next line, and closing
    braces MUST go on the next line after the body.

  • Opening braces for methods MUST go on the next line, and closing
    braces MUST go on the next line after the body.

  • Visibility MUST be declared on all properties and
    methods;abstractandfinalMUST be declared before the
    visibility;staticMUST be declared after the visibility.

  • Control structure keywords MUST have one space after them; method
    and function calls MUST NOT.

  • Opening braces for control structures MUST go on the same line, and
    closing braces MUST go on the next line after the body.

  • Opening parentheses for control structures MUST NOT have a space
    after them, and closing parentheses for control structures MUST NOT
    have a space before.

foreach

foreach 结构如下所示。 注意括号、空格和花括号的位置。

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

6. 闭包

声明闭包时所用的function关键字之后必须要有一个空格,而use关键字的前后都要有一个空格。

闭包的左花括号必须跟其在同一行,而右花括号必须在闭包主体的下一行。

闭包的参数列表和变量列表的左括号后面不可有空格,右括号的前面也不可有空格。

闭包的参数列表和变量列表中逗号前面不可有空格,而逗号后面则必须有空格。

闭包的参数列表中带默认值的参数必须放在参数列表的结尾部分。

下面是一个闭包的示例。注意括号,空格和花括号的位置。

$closureWithArgs = function ($arg1, $arg2) {
// body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// body
};

参数列表和变量列表可以被拆分成多个缩进了一级的子行。如果要拆分成多个子行,列表中的第一项必须放在下一行,并且每一行必须只放一个参数或变量。

当列表(不管是参数还是变量)最终被拆分成多个子行,右括号和左花括号之间必须要有一个空格并且自成一行。

下面是一个参数列表和变量列表被拆分成多个子行的示例。

$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
};

把闭包作为一个参数在函数或者方法中调用时,依然要遵守上述规则。

$foo->bar(
$arg1,
function ($arg2) use ($var1) {
// body
},
$arg3
);

举例

This example encompasses some of the rules below as a quick overview:

<?phpnamespace VendorPackage;use FooInterface;use BarClass as Bar;use OtherVendorOtherPackageBazClass;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    }}

try, catch

try-catch区块如下所示。 注意括号、空格和花括号的位置。

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

7. 结论

本指南有意的省略了许多元素的代码风格。主要包括:

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

  • 函数声明

  • 操作符和赋值

  • 行间对齐

  • 注释和文档块

  • 类名的前缀和后缀

  • 最佳实践

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

基础风格

Code MUST follow all rules outlined inPSR-1.

Closure 闭包

声明闭包必须在function关键字后留一个空格,在use关键字前后各留一个空格。

左花括号必须在同一行, 右花括号必须在body的下一行。

参数或变量列表的左括号后 和 右括号前必须没有空格。

参数和变量列表的逗号前必须没有空格,每个逗号后必须有一个空格。

有默认值的参数必须排在最后。

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

<?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
);

文件

All PHP files MUST use the Unix LF line ending.

All PHP files MUST end with a single blank line.

The closing?>tag MUST be omitted from files containing only PHP.

或许你之前也写过PHP的代码,这里,PHP文件的最后不许要有空行,而且不允许使用?>结尾标签。

结语

本指南刻意忽略了许多风格和实践。包括但不限于:

  • 声明全局变量和全局常量。
  • 声明函数。
  • 操作符和赋值。
  • 行间对齐。
  • 注释和文档区。
  • 类名前后缀。
  • 最佳实践。

Future recommendations MAY revise and extend this guide to address those
or other elements of style and practice.

代码行长度

Lines SHOULD NOT be longer than 80 characters; lines longer than that
SHOULD be split into multiple subsequent lines of no more than 80
characters each.

附录A 调查

In writing this style guide, the group took a survey of member projects
to determine common practices. The survey is retained herein for
posterity.

缩进

Code MUST use an indent of 4 spaces, and MUST NOT use tabs for
indenting.

N.b.: Using only spaces, and not mixing spaces with tabs, helps to avoid
problems with diffs, patches, history, and annotations. The use of
spaces also makes it easy to insert fine-grained sub-indentation for
inter-line alignment.

调查数据

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,http://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

关键字

PHPkeywordsMUST be in lower case.

The PHP constantstrue,false, andnullMUST be in lower case.

调查说明

indent_type: The type of indenting. tab = “Use a tab”, 2 or 4 = “number
of spaces”

line_length_limit_soft: The “soft” line length limit, in characters.
? = not discernible or no response, no means no limit.

line_length_limit_hard: The “hard” line length limit, in characters.
? = not discernible or no response, no means no limit.

class_names: How classes are named. lower = lowercase only,
lower_under = lowercase with underscore separators, studly =
StudlyCase.

class_brace_line: Does the opening brace for a class go on the same
line as the class keyword, or on the next line after it?

constant_names: How are class constants named? upper = Uppercase with
underscore separators.

true_false_null: Are the true, false, and null keywords spelled as all
lower case, or all upper case?

method_names: How are methods named? camel = camelCase, lower_under =
lowercase with underscore separators.

method_brace_line: Does the opening brace for a method go on the same
line as the method name, or on the next line?

control_brace_line: Does the opening brace for a control structure go
on the same line, or on the next line?

control_space_after: Is there a space after the control structure
keyword?

always_use_control_braces: Do control structures always use braces?

else_elseif_line: When using else or elseif, does it go on the same
line as the previous closing brace, or does it go on the next line?

case_break_indent_from_switch: How many times are case and break
indented from an opening switch statement?

function_space_after: Do function calls have a space after the
function name and before the opening parenthesis?

closing_php_tag_required: In files containing only PHP, is the
closing ?> tag required?

line_endings: What type of line ending is used?

static_or_visibility_first: When declaring a method, does static come
first, or does the visibility come first?

control_space_parens: In a control structure expression, is there a
space after the opening parenthesis and a space before the closing
parenthesis? yes = if ( expr),no=if(expr).

blank_line_after_php: Is there a blank line after the opening PHP
tag?

class_method_control_brace: A summary of what line the opening braces
go on for classes, methods, and control structures.

命名空间

When present, there MUST be one blank line after
thenamespacedeclaration.

When present, allusedeclarations MUST go after
thenamespacedeclaration.

There MUST be oneusekeyword per declaration.

There MUST be one blank line after theuseblock.

For example:

<?phpnamespace VendorPackage;use FooClass;use BarClass as Bar;use OtherVendorOtherPackageBazClass;// ... additional PHP code ...

调查结果

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

Extends和Implements

Theextendsandimplementskeywords MUST be declared on the same line as
the class name.

<?phpnamespace VendorPackage;use FooClass;use BarClass as Bar;use OtherVendorOtherPackageBazClass;class ClassName extends ParentClass implements ArrayAccess, Countable{    // constants, properties, methods}

变量

Visibility(public、private、protected) MUST be declared on all
properties.

Thevarkeyword MUST NOT be used to declare a property.

There MUST NOT be more than one property declared per statement.

Property names SHOULD NOT be prefixed with
a single underscore to indicate protected or private
visibility.这里是SHOULD NOT,我个人觉得应该是MUST NOT。

A property declaration looks like the following.

<?phpnamespace VendorPackage;class ClassName{    public $foo = null;}

方法

Visibility MUST be declared on all methods.

Method names SHOULD NOT be prefixed with a single underscore to indicate
protected or private visibility.这里是SHOULD NOT,我个人觉得应该是MUST
NOT。

The opening brace MUST go on its own line, and the closing brace MUST go
on the next line following the body.

<?phpnamespace VendorPackage;class ClassName{    public function fooBarBaz($arg1, &$arg2, $arg3 = [])    {        // method body    }}

方法参数

In the argument list, there MUST NOT be a space before each comma, and
there MUST be one space after each comma.

Method arguments with default values MUST go at the end of the argument
list.

<?phpnamespace VendorPackage;class ClassName{    public function foo($arg1, &$arg2, $arg3 = [])    {        // method body    }}

When the argument list is split across multiple lines, the closing
parenthesis and opening brace MUST be placed together on their own line
with one space between them.

<?phpnamespace VendorPackage;class ClassName{    public function aVeryLongMethodName(        ClassTypeHint $arg1,        &$arg2,        array $arg3 = []    ) {        // method body    }}

abstract, final, and static

When present, theabstractandfinaldeclarations MUST precede the
visibility declaration.

When present, thestaticdeclaration MUST come after the visibility
declaration.

<?phpnamespace VendorPackage;abstract class ClassName{    protected static $foo;    abstract protected function zim();    final public static function bar()    {        // method body    }}

方法调用

When making a method or function call,

there MUST NOT be a space between the method or function name and the
opening parenthesis,

there MUST NOT be a space after the opening parenthesis, and there MUST
NOT be a space before the closing parenthesis.

In the argument list, there MUST NOT be a space before each comma, and
there MUST be one space after each comma.

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

控制结构

  • There MUST be one space after the control structure keyword
  • There MUST NOT be a space after the opening parenthesis
  • There MUST NOT be a space before the closing parenthesis
  • There MUST be one space between the closing parenthesis and the
    opening brace
  • The structure body MUST be indented once
  • The closing brace MUST be on the next line after the body

if, elseif, else

Anifstructure looks like the following. Note the placement of
parentheses, spaces, and braces; and thatelseandelseifare on the
same line as the closing brace from the earlier body.

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

switch, case

Aswitchstructure looks like the following.There MUST be a comment such
as// no breakwhen fall-through is intentional in a
non-emptycasebody.

<?phpswitch ($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

<?phpwhile ($expr) {    // structure body}

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

for, foreach

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

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

try, catch

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

匿名函数

Closures MUST be declared with a space after thefunctionkeyword, and a
space before and after theusekeyword.

The opening brace MUST go on the same
line, and the closing brace MUST go on the next line following
the body.

There MUST NOT be a space after the opening parenthesis of the argument
list or variable list, and there MUST NOT be a space before the closing
parenthesis of the argument list or variable list.

In the argument list and variable list, there MUST NOT be a space before
each comma, and there MUST be one space after each comma.

Closure arguments with default values MUST go at the end of the argument
list.

A closure declaration looks like the following. Note the placement of
parentheses, commas, spaces, and braces:

<?php$closureWithArgs = function ($arg1, $arg2) {    // body};$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {    // body};

那些个参数换行的写法这里就不介绍了,感觉那样子会让代码乱糟糟的,个人不建议那么做,方法的参数一定要写注释,注释相当重要,宁愿舍弃点规范,也要多写注释,规范少写一点,大不了可读性差点,如果注释少些点,那就根本读不了了。

好了,今天关于PSR-1和PSR-2对于代码的规范就说到这,接下来我会给大家带来PSR-3日志规范和PSR-4自动加载器相关内容。良好的开端是成功的基本要素,希望大家能好好遵守代码规范,毕竟代码如人,工工整整嘛。^_^

发表评论

电子邮件地址不会被公开。 必填项已用*标注