文件
- PHP 文件 必须 且只可使用
不带BOM的UTF-8编码。 - PHP 代码 必须 使用
<?php ?>长标签 或<?= ?>短输出标签; - PHP 文件 必须 省略最后的
?>结束标签。 - PHP 文件 必须 以一个空白行作为结束。
- PHP 文件 必须 使用
Unix LF (linefeed)作为行的结束符。 - PHP 文件 应该 要不就只定义新的声明,如类、函数或常量等不产生
副作用的操作,要不就只书写会产生副作用的逻辑操作,但 不该 同时具有两者。
副作用包含却不仅限于:- 生成输出
- 直接的
require或include - 连接外部服务
- 修改 ini 配置
- 抛出错误或异常
- 修改全局或静态变量
- 读或写文件等
行
- 行的长度 一定不可 有硬性的约束,软性的长度约束 必须 要限制在 120 个字符以内;每行 不该 多于 80 个字符,大于 80 字符的行 应该 折成多行。
- 非空行后 一定不可 有多余的空格符。
- 空行 可以 使得阅读代码更加方便以及有助于代码的分块。
- 每行 一定不可 存在多于一条语句。
- 代码 必须 使用 4 个空格符的缩进,一定不可 用
tab键。
关键字 以及 True/False/Null
- PHP 所有 关键字 必须 全部小写。
- 常量
true、false和null也 必须 全部小写。
namespace 以及 use 声明
namespace声明后 必须 插入一个空白行。- 所有
use必须 在namespace后声明。 - 每条
use声明语句 必须 只有一个use关键词。 use声明语句块后 必须 要有一个空白行。
<?phpnamespace Vendor\Package;use FooClass;use BarClass as Bar;use OtherVendor\OtherPackage\BazClass;// ... 更多的 PHP 代码在这里 ...
类的命名
此处的「类」泛指所有的「Class 类」、「接口」、「traits 可复用代码块」以及其它类似结构。
- 每个类都独立为一个文件。
- 一个完整的类名需具有以下结构:
\<命名空间>(\<子命名空间>)*\<类名>
- 完整的类名 必须 要有一个顶级命名空间,被称为 “vendor namespace”;
- 完整的类名 可以 有一个或多个子命名空间;
- 完整的类名 必须 有一个最终的类名;
- 完整的类名中任意一部分中的下滑线都是没有特殊含义的;
- 完整的类名 可以 由任意大小写字母组成;
- 所有类名都 必须 是大小写敏感的。
- 类的命名 必须 遵循
StudlyCaps大写开头的驼峰命名规范。
- PHP 5.3 及以后版本的代码 必须 使用正式的命名空间。(5.2.x 及之前的版本 应该 使用伪命名空间的写法,约定俗成使用顶级的组织名称(vendor name)如 Vendor_ 为类前缀)
<?php// 5.2.x及之前版本的写法class Vendor_Model_Foo{}
类的自动加载
- 完整的类名中,去掉最前面的命名空间分隔符,前面连续的一个或多个命名空间和子命名空间,作为「命名空间前缀」,其 必须 与至少一个「文件基目录」相对应;
- 紧接命名空间前缀后的子命名空间 必须 与相应的「文件基目录」相匹配,其中的命名空间分隔符将作为目录分隔符。
- 末尾的类名 必须 与对应的以 .php 为后缀的文件同名。
- 自动加载器(autoloader)的实现 一定不可 抛出异常、一定不可 触发任一级别的错误信息以及 不应该 有返回值。
| 完整类名 | 命名空间前缀 | 文件基目录 | 文件路径 |
|---|---|---|---|
| \Acme\Log\Writer\File_Writer | Acme\Log\Writer | ./acme-log-writer/lib/ | ./acme-log-writer/lib/File_Writer.php |
| \Aura\Web\Response\Status | Aura\Web | /path/to/aura-web/src/ | /path/to/aura-web/src/Response/Status.php |
| \Symfony\Core\Request | Symfony\Core | ./vendor/Symfony/Core/ | ./vendor/Symfony/Core/Request.php |
| \Zend\Acl | Zend | /usr/includes/Zend/ | /usr/includes/Zend/Acl.php |
类的扩展与继承
- 关键词
extends和implements必须 写在类名称的同一行。 - 类的开始花括号 必须 独占一行,结束花括号也 必须 在类主体后独占一行。
class ClassName extends ParentClass implements \ArrayAccess, \Countable{// 这里面是常量、属性、类方法}
- implements 的继承列表也 可以 分成多行,这样的话,每个继承接口名称都 必须 分开独立成行,包括第一个。
class ClassName extends ParentClass implements\ArrayAccess,\Countable,\Serializable{// 这里面是常量、属性、类方法}
类的常量
类的常量中所有字母都 必须 大写,单词间以下划线分隔。
<?phpnamespace Vendor\Model;class Foo{const VERSION = '1.0';const DATE_APPROVED = '2012-06-01';}
类的属性
- 每个属性都 必须 添加访问修饰符。
- 一定不可 使用关键字
var声明一个属性。 - 每条语句 一定不可 定义超过一个属性。
- 不该 使用下划线作为前缀,来区分属性是
protected或private。 - 类的属性命名 可以 遵循(不做强制要求,但无论遵循哪种命名方式,都 应该 在一定的范围内保持一致。这个范围可以是整个团队、整个包、整个类或整个方法):
- 大写开头的驼峰式 (
$StudlyCaps) - 小写开头的驼峰式 (
$camelCase) - 下划线分隔式 (
$under_score)
- 大写开头的驼峰式 (
<?phpnamespace Vendor\Package;class ClassName{public $foo = null;}
类的方法
- 所有方法都 必须 添加访问修饰符。
- 不该 使用下划线作为前缀,来区分方法是
protected或private。 - 方法名称后 一定不可 有空格符,其开始花括号 必须 独占一行,结束花括号也 必须 在方法主体后单独成一行。
- 方法名称 必须 符合
camelCase()式的小写开头驼峰命名规范。
<?phpnamespace Vendor\Package;class ClassName{public function fooBarBaz($arg1, &$arg2, $arg3 = []){// method body}}
方法的参数
- 参数列表中,每个逗号后面 必须 要有一个空格,而逗号前面 一定不可 有空格。
- 有默认值的参数,必须 放到参数列表的末尾
- 参数列表 可以 分列成多行,这样,包括第一个参数在内的每个参数都 必须 单独成行。
- 拆分成多行的参数列表后,结束括号以及方法开始花括号 必须 写在同一行,中间用一个空格分隔
<?phpnamespace Vendor\Package;class ClassName{public function fooBarBaz($arg1, &$arg2, $arg3 = []){// method body}}
修饰符
需要添加 abstract 或 final 声明时,必须 写在访问修饰符前,而 static 则 必须 写在访问修饰符后
<?phpnamespace Vendor\Package;abstract class ClassName{protected static $foo;abstract protected function zim();final public static function bar(){// method body}}
方法及函数调用
- 方法及函数调用时,方法名或函数名与参数左括号之间 一定不可 有空格,参数右括号前也 一定不可 有空格。
参数列表中,每个逗号后面 必须 要有一个空格,而逗号前面 一定不可 有空格。
<?phpbar();$foo->bar($arg1);Foo::bar($arg2, $arg3);
参数 可以 分列成多行,此时包括第一个参数在内的每个参数都 必须 单独成行。
<?php$foo->bar($longArgument,$longerArgument,$muchLongerArgument);
控制结构
- 控制结构关键词后 必须 有一个空格。
- 左括号
(后 一定不可 有空格。 - 右括号
)前也 一定不可 有空格。 - 右括号
)与开始花括号{间 必须 有一个空格。 - 结构体主体 必须 要有一次缩进。
- 结束花括号
}必须 在结构体主体后单独成行。 - 每个结构体的主体都 必须 被包含在成对的花括号之中,这能让结构体更加结构化,以及减少加入新行时,出错的可能性。
if 、elseif 和 else
- 应该 使用关键词
elseif代替所有else if else和elseif都与前面的结束花括号在同一行。
<?phpif ($expr1) {// if body} elseif ($expr2) {// elseif body} else {// else body;}
switch 和 case
case语句 必须 相对switch进行一次缩进,而break语句以及case内的其它语句都 必须 相对case进行一次缩进。- 如果存在非空的
case直穿语句,主体里 必须 有类似// no break的注释。
<?phpswitch ($expr) {case 0:echo 'First case, with a break';break;case 1:echo 'Second case, which falls through';// no breakcase 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
<?phpfor ($i = 0; $i < 10; $i++) {// for body}
foreach
<?phpforeach ($iterable as $key => $value) {// foreach body}
try, catch
<?phptry {// try body} catch (FirstExceptionType $e) {// catch body} catch (OtherExceptionType $e) {// catch body}
闭包
- 闭包声明时,关键词
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);
本文根据 PHP标准规范 的PSR-1,PSR-2,PSR-4整理汇总