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

1. 概述

  • 代码必须遵守 PSR-1。

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

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

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

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

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

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

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

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

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

1.1. 示例

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

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常量truefalsenull 必须使用小写字母。

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

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

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

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

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

示例:

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)主体的后面自成一行。

namespace Vendor\Package;

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

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

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

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)声明看起来应该像下面这样。

namespace Vendor\Package;

class ClassName
{
public $foo = null;
}

4.3. 方法(method)

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

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

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

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

namespace Vendor\Package;

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

4.4. 方法(method)的参数

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

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

namespace Vendor\Package;

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

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

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

namespace Vendor\Package;

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

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

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

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

namespace Vendor\Package;

abstract class ClassName
{
protected static $foo;

abstract protected function zim();

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

4.6. 调用方法和函数

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

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

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

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

5. 控制结构

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

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

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

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

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

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

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

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

5.1. ifelseifelse

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

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

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

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

5.3. whiledo while

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

while ($expr) {
// structure body
}

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

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

5.4. for

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

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

5.5. foreach

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

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

5.6. trycatch

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

try {
// try body
} catch (FirstExceptionType $e) {
// catch body
} catch (OtherExceptionType $e) {
// catch 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
);

7. 结论

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

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

  • 函数声明

  • 操作符和赋值

  • 行间对齐

  • 注释和文档块

  • 类名的前缀和后缀

  • 最佳实践

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

PSR2规范的更多相关文章

  1. 【PSR规范专题(3)】PSR-2 代码风格规范

    [PSR规范专题(3)]PSR-2 代码风格规范 标签(空格分隔): PHP 转载自:https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-2-cod ...

  2. PHP中PSR-[0-4]代码规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...

  3. 漫谈PHP代码规范

    前言 虽说PHP是世界上最好的语言,但是写出来的PHP代码却往往不是最美观的.究其原因,可能正式因为PHP简单易上手,适合快速迭代的特性,导致了我们沉浸在迅速完成需求迭代的窃喜中,却忘记了规范性.忽略 ...

  4. [转载]PHP中PSR-[0-4]规范

      PHP是世界上最伟大的语言,这一点是毋庸置疑的吧.哈哈哈哈哈哈 .这个霸气的开头不错!(^__^) 但是正是因为伟大,所以用的人也就多了,人一多,再牛逼再伟大的东西,都会产生问题,逐渐就造成了很多 ...

  5. PHP中PSR-[0-4]规范(转)

    PHP中PSR-[0-4]规范 更好排版:https://www.zybuluo.com/phper/note/65033 PHP是世界上最伟大的语言,这一点是毋庸置疑的吧.哈哈哈哈哈哈 .这个霸气的 ...

  6. PHP-PSR-[0-4]代码规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...

  7. PHP编码风格规范

    由于PHP的灵活性,很多人写起代码来也不讲求一个好的代码规范,使得本就灵活的PHP代码看起来很乱,其实PSR规范中的PSR-1和PSR-2已经定义了在PHP编码中的一些规范,只要我们好好遵守这些规范, ...

  8. PHP 的一些开发规范

    均需要遵守 PSR规范 变量命名 不用拼音 驼峰或下划线风格要一致 单词要有意义 不用关键字 常量全大写用下划线连接 代码注释 尽量让代码可读性提高,减少代码上的注释 函数头部可以描述参数和返回值及功 ...

  9. 转载:PHP编程规范

    PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...

随机推荐

  1. 何时使用[self release]

    这样的语句   [self release]; 乍看上去让人很困惑. 从release方法本身的作用上来说,就是给self的引用技术减一,就像release对其他对象所做的一样. 一般来说,唯一用到, ...

  2. Leader/Follower多线程网络模型介绍

    之前分享过<轻量级 web server Tornado代码分析>,介绍了目前我们采用nginx + tornado的方式搭建升级.配管.数据中心等各类服务组建客户端迭代体系.最近注意到, ...

  3. linux 搭建php网站许愿墙

    网站素材在:https://i.cnblogs.com/Files.aspx 首先需要搭建本地yum源,详情参考: http://www.cnblogs.com/jw35/p/5967677.html ...

  4. GNOME桌面的安装

    首先搭建yum仓库 http://www.cnblogs.com/jw35/p/5967677.html yum grouplist                     #列出yum仓库里的软件组 ...

  5. handsontable-cell type

    在单元格中呈现自定义的元素:不能使用html元素 var data = [ { title: "<a href='http://www.amazon.com/Professional- ...

  6. NideShop项目的安装部署教程

    本文档为微信小程序商城NideShop项目的安装部署教程,欢迎star NideShop商城api服务:https://github.com/tumobi/nideshop NideShop微信小程序 ...

  7. [leetcode] 9. Binary Tree Level Order Traversal

    跟第七题一样,把最后的输出顺序换一下就行... Given a binary tree, return the level order traversal of its nodes' values. ...

  8. Sqler-Monitor

    针对Sqler Monitor 功能做了整理 ##SqlServices ## Cluster. Alwayson Single ##Replicaion ##: 1:undelivedcmds mo ...

  9. c# 多线程线程池基础

    线程池的作用        在上一篇中我们了解了创建和销毁线程是一个昂贵的操作,要耗费大量的时间,太多的线程会浪费内存资源,当线程数量操作计算机CPU的数量后操作系统必须调度可运行的线程并执行上下文切 ...

  10. trace sql log

    C:\Windows\system32>cd /d  d:\PSSDIAG\pssd_2k12_x64 d:\PSSDIAG\pssd_2k12_x64>pssdiag.cmd 2014/ ...