PHP规范PSR2
为了尽可能的提升阅读其他人代码时的效率,下面例举了一系列的通用规则,特别是有关于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常量true
, false
和null
必须
使用小写字母。
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. if
,elseif
,else
下面是一个if
条件控制结构的示例,注意其中括号,空格和花括号的位置。同时注意else
和elseif
要和前一个条件控制结构的右花括号在同一行。
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
的注释。
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
循环控制结构的示例,注意其中括号,空格和花括号的位置。
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. try
, catch
下面是一个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. 结论
本指南有意的省略了许多元素的代码风格。主要包括:
全局变量和全局常量的声明
函数声明
操作符和赋值
行间对齐
注释和文档块
类名的前缀和后缀
最佳实践
以后的代码规范中可能
会修正或扩展本指南中规定的代码风格。
PHP规范PSR2的更多相关文章
- PHP编码规范PSR-2
.note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...
- PHP中PSR-[0-4]代码规范
PHP-FIG 在说啥是PSR-[0-4]规范的之前,我觉得我们有必要说下它的发明者和规范者:PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR-[0-4] ...
- PSR : php编码规范
诸王混战 关于开发标准这块,可以说一直都是风格迥异,各家都有各家的玩法,民间更是个人玩个人的.目前我们国内比较出名的几个框架(Yii,Laravel) 都已经支持Composer并且加入了PHP-FI ...
- 【PSR规范专题(1)】PSR-0+namespace+spl_autoload_register实现框架模型
了解命名空间 namespace是PHP5.3版本加入的新特性,用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题: 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/ ...
- php规范
PSR-0 自动加载 PSR-1 基本代码规范 PSR-2 代码样式 PSR-3 日志接口
- PSR-4——新鲜出炉的PHP规范
FIG 制定的PHP规范,简称PSR,是PHP开发的事实标准. PSR原本有四个规范,分别是: PSR-0 自动加载 PSR-1 基本代码规范 PSR-2 代码样式 PSR-3 日志接口 2013年底 ...
- php设计模式--面向对象编程规范PSR
php业界提出大家要遵循的面向对象编码规范,下面一一列出. PSR-0: 1.命名空间必须与绝对路径一致 2.类的首字母必须大写 3.出入口文件外,其他‘.php’必须只有一个类 PSR-1:基础编码 ...
- PSR-PHP开发规范(本文版权归作者:luluyrt@163.com)
遵循PSR-4的自动加载 一.简介 首先这里要了解PSR,Proposing a Standards Recommendation(提出标准建议)的缩写,就是一种PHP开发规范,让我们研发出来的代码更 ...
- [转载]PHP中PSR-[0-4]规范
PHP是世界上最伟大的语言,这一点是毋庸置疑的吧.哈哈哈哈哈哈 .这个霸气的开头不错!(^__^) 但是正是因为伟大,所以用的人也就多了,人一多,再牛逼再伟大的东西,都会产生问题,逐渐就造成了很多 ...
随机推荐
- 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。
ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...
- c#方法
1.引用型参数: 关键字:ref 2.输出型参数 关键字:out 例: double area(out double p) { double t=3.14*10; p=2*t*3.14; return ...
- Angular使用$compile为从Ajax加载的HTML绑定ng-click事件
这是一个Angular使用$compile为从Ajax加载的HTML绑定ng-click事件的实现方式,由于近期忙碌,就先放代码.代码如下: <table data-ng-table=" ...
- ArchLinux+Win10双系统的Grub配置
解决:ArchLinux+Win10双系统,Grub设置 原装的Win10,装完ArchLinux后,要进入Win10一段时间只能通过boot选择. Grub的菜单里并没有.Grub安装过程是参考wi ...
- Javascript刷题 》 查找数组元素位置
找出元素 item 在给定数组 arr 中的位置 输出描述: function indexOf(arr, item) { ..... } 如果数组中存在 item,则返回元素在数组中的位置,否则返回 ...
- Torch学习笔记1--Torch简介
Torch是什么 Torch是一个由Lua语言开发的深度学习框架,目前支持Mac OS X 和Ubuntu 12及以上,官网 ,github地址. 具有如下特点: 交互式开发工具 可视化式的工具 第三 ...
- isPrototypeOf&&getPrototypeOf
在JavaScript这个一切皆为对象的世界里,难免会判断原型链的问题.那么我们就有必要了解了解isPrototypeOf和getPrototypeOf这两个方法咯. 1.isPrototypeOf ...
- 【前端性能】必须要掌握的原生JS实现JQuery
很多时候,我们经常听见有人说jquery有多快多快.在这个各种类库满天飞的时候,不得不说的是,能有原生JS快吗? 是的,明显原生JS要更快,因为诸如JQuery这样的库必须要兼容各种浏览器和低版本和许 ...
- C#开发微信公众平台-就这么简单(附Demo)
写在前面 阅读目录: 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件响应) 示例Demo下载 后记 最近公司在做微信开发,其实就是接口开发,网上找了很多资料, ...
- PHP过滤各种HTML标签
$str=preg_replace("/<\s*img\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i&q ...