PHP-代码规范(V1.0.0)


time 20191209

author Venki


参考链接

目录指引
基础编码规范

回到顶部

本篇规范制定了代码基本元素的相关标准,以确保共享的PHP代码间具有较高程度的技术互通性。本文件中的必须,不得,需要,应,不应,应,不应该,推荐,可能 和 可选 等能愿动词按照 RFC 2119 中的描述进行解释。
  1. 概览
  • PHP 代码文件 必须 以 <?php 或 <?= 标签开始
  • PHP 代码文件 必须 以 不带 BOM 的 UTF-8 编码
  • PHP 代码中 应该 只定义类、函数、常量等声明,或其他会产生副作用的操作(如:生成文件输出以及修改 .ini 配置文件等),二者只能选其一
  • 命名空间以及类 必须 符合 PSR 的自动加载规范PSR-4
  • 类中的常量所有字母都 必须 大写,单词间用下划线分隔
  • 方法名称 必须 符合 camelCase 式的小写开头驼峰命名规范
  1. 文件
  • PHP 代码 必须 使用 <?php ?> 长标签 或 <?= ?> 短输出标签;一定不可 使用其它自定义标签
  • PHP 代码 必须 且只可使用 不带 BOM 的 UTF-8 编码
  • 一份 PHP 文件中 应该 要不就只定义新的声明,如类、函数或常量等不产生 副作用 的操作,要不就只书写会产生 副作用 的逻辑操作,但 不该 同时具有两者
    • 「副作用」(side effects) 一词的意思是,仅仅通过包含文件,不直接声明类、函数和常量等,而执行的逻辑操作
    • 「副作用」包含却不仅限于:生成输出,明确使用 require 或 include,连接到外部服务,修改 ini 设置,发出错误或异常,修改全局或静态变量,读取或写入一个文件,等等

以下是一个 反例,一份包含「函数声明」以及产生「副作用」的代码

<?php
// 「副作用」:修改 ini 配置
ini_set('error_reporting', E_ALL);

// 「副作用」:引入文件
include "file.php";

// 「副作用」:生成输出
echo "<html>\n";

// 声明函数
function foo()
{
    // function body
}

下面是一个范例,一份只包含声明不产生「副作用」的代码

<?php
// 声明函数
function foo()
{
    // 函数主体部分
}

// 条件声明 **不** 属于「副作用」
if (! function_exists('bar')) {
    function bar()
    {
        // 函数主体部分
    }
}

3 命名空间和类名

  • 命名空间和类名 必须 遵循『自动加载』规范

  • 这意味着每个类都独立为一个文件,并且至少在一个层次的命名空间内,那就是:顶级组织名(vendor name)

  • 类名 必须 以类似 StudlyCaps 形式的大写开头的驼峰命名方式声明

  1. 类的常量、属性和方法
  • 此处的「类」指代所有的类、接口以及可复用代码块(traits)

  • 常量

类的常量中所有字母都 必须 大写,词间以下划线分隔。例如:

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}
  • 属性

类的属性命名 可以 遵循:(本规范不做强制要求,但无论遵循哪种命名方式,都 应该 在一定的范围内保持一致。这个范围可以是整个团队、整个包、整个类或整个方法)

大写开头的驼峰式 ($StudlyCaps)
小写开头的驼峰式 ($camelCase)
下划线分隔式 ($under_score)
  • 方法

方法名称 必须 符合 camelCase() 式的小写开头驼峰命名规范

自动加载规范

回到顶部

为了避免歧义,文档大量使用了「能愿动词」,对应的解释如下:
- 必须 (MUST):绝对,严格遵循,请照做,无条件遵守 - 一定不可 (MUST NOT):禁令,严令禁止 - 应该 (SHOULD) :强烈建议这样做,但是不强求 - 不该 (SHOULD NOT):强烈不建议这样做,但是不强求 - 可以 (MAY) 和 可选(OPTIONAL)选择性高一点,在这个文档内,此词语使用较少
编码风格规范

回到顶部

  1. 概览
  • 代码 必须 遵循 [PSR-1] 中的编码规范

  • 代码 必须 使用 4 个空格符而不是「Tab 键」进行缩进

  • 每行的字符数 应该 软性保持在 80 个之内,理论上 一定不可 多于 120 个,但 一定不可 有硬性限制

  • 每个 namespace 命名空间声明语句和 use 声明语句块后面,必须 插入一个空白行

  • 类的开始花括号({) 必须 写在类声明后自成一行,结束花括号(})也 必须 写在类主体后自成一行

  • 方法的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行

  • 类的属性和方法 必须 添加访问修饰符(private、protected 以及 public),abstract 以及 final 必须 声明在访问修饰符之前,而 static 必须 声明在访问修饰符之后

  • 控制结构的关键字后 必须 要有一个空格符,而调用方法或函数时则 一定不可

  • 控制结构的开始花括号({) 必须 写在声明的同一行,而结束花括号(}) 必须 写在主体后自成一行

  • 控制结构的开始左括号后和结束右括号前,都 一定不可 有空格符

示例1

<?php
namespace Vendor\Package;

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

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()
    {
        // 方法体
    }
}
  1. 通则

文件

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

  • 所有 PHP 文件 必须 以一个空白行作为结束

  • 纯 PHP 代码文件 必须 省略最后的 ?> 结束标签

  • 行的长度 一定不可 有硬性的约束。

  • 软性的长度约束 必须 要限制在 120 个字符以内,若超过此长度,带代码规范检查的编辑器 必须 要发出警告,不过 一定不可 发出错误提示。

  • 每行 不该 多于 80 个字符,大于 80 字符的行 应该 折成多行。

  • 非空行后 一定不可 有多余的空格符。

  • 空行 可以 使得阅读代码更加方便以及有助于代码的分块。

  • 每行 一定不可 存在多于一条语句

缩进

  • 代码 必须 使用 4 个空格来进行缩进, 并且 一定不能 使用 tab 键来缩进

    注:仅使用空格,而不是使用空格和 tab 键混在一起, 能帮助避免在查看代码差异,打补丁,查看提交历史,以及进行注解时产生问题。使用空格也使得代码对齐更轻松

  1. 命名空间和使用声明
  • namespace 声明之后 必须 存在一个空行
  • 所有的 use 声明 必须 位于 namespace 声明之后
  • 每条 use 声明 必须 只有一个 use 关键字
  • use 语句块之后 必须 存在一个空行
<?php
namespace Vendor\Package;

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

// ... 其他 PHP 代码 ...
  1. 类、属性和方法

此处的「类」泛指所有的「class 类」、「接口」以及「traits 可复用代码块」

扩展与继承

  • 关键词 extends 和 implements 必须 写在类名称的同一行

  • 类的开始花括号 必须 独占一行,结束花括号也 必须 在类主体后独占一行

<?php
namespace Vendor\Package;

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

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // 这里面是常量、属性、类方法
}
  • implements 的继承列表也 可以 分成多行,这样的话,每个继承接口名称都 必须 分开独立成行,包括第一个
<?php
namespace Vendor\Package;

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

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

属性

  • 每个属性都 必须 添加访问修饰符

  • 一定不可 使用关键字 var 声明一个属性

  • 每条语句 一定不可 定义超过一个属性

  • 不该 使用下划线作为前缀,来区分属性是 protected 或 private

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}

方法

  • 所有方法都 必须 添加访问修饰符

  • 不该 使用下划线作为前缀,来区分方法是 protected 或 private 访问修饰符

  • 方法名称后 一定不可 有空格符,其开始花括号 必须 独占一行,结束花括号也 必须 在方法主体后单独成一行。参数左括号后和右括号前 一定不可 有空格

<?php
namespace Vendor\Package;

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

方法的参数

  • 参数列表中,每个逗号后面 必须 要有一个空格,而逗号前面 一定不可 有空格

  • 有默认值的参数,必须 放到参数列表的末尾

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

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

方法及函数调用

  • 方法及函数调用时,方法名或函数名与参数左括号之间 一定不可 有空格,参数右括号前也 一定不可 有空格。每个逗号前 一定不可 有空格,但其后 必须 有一个空格
<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
  • 参数 可以 分列成多行,此时包括第一个参数在内的每个参数都 必须 单独成行
<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
  1. 控制结构

控制结构的基本规范如下

  • 控制结构关键词后 必须 有一个空格
  • 左括号 ( 后 一定不可 有空格
  • 右括号 ) 前也 一定不可 有空格
  • 右括号 ) 与开始花括号 { 间 必须 有一个空格
  • 结构体主体 必须 要有一次缩进
  • 结束花括号 } 必须 在结构体主体后单独成行
  • 每个结构体的主体都 必须 被包含在成对的花括号之中

if, elseif, else

  • 标准的 if 结构如下代码所示,请留意「括号」、「空格」以及「花括号」的位置
  • 注意 else 和 elseif 都与前面的结束花括号在同一行
  • 应该 使用关键词 elseif 代替所有 else if ,以使得所有的控制关键字都像是单独的一个词
<?php
if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}

switch, case

  • 标准的 switch 结构如下代码所示,留意「括号」、「空格」以及「花括号」的位置
  • case 语句 必须 相对 switch 进行一次缩进,而 break 语句以及 case 内的其它语句都 必须 相对 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;
}

while, do while

  • 一个规范的 while 语句应该如下所示,注意其「括号」、「空格」以及「花括号」的位置
<?php
while ($expr) {
    // 结构体
}
  • 标准的 do while 语句如下所示,同样的,注意其「括号」、「空格」以及「花括号」的位置
<?php
do {
    // 结构体
} while ($expr);

for

  • 标准的 for 语句如下所示,注意其「括号」、「空格」以及「花括号」的位置
<?php
for ($i = 0; $i < 10; $i++) {
    // for 循环主体
}

foreach

  • 标准的 foreach 语句如下所示,注意其「括号」、「空格」以及「花括号」的位置
<?php
foreach ($iterable as $key => $value) {
    // foreach 主体
}

try, catch

  • 标准的 try catch 语句如下所示,注意其「括号」、「空格」以及「花括号」的位置
<?php
try {
    // try 主体
} catch (FirstExceptionType $e) {
    // catch 主体
} catch (OtherExceptionType $e) {
    // catch 主体
}

闭包

  • 闭包声明时,关键词 function 后以及关键词 use 的前后都 必须 要有一个空格

  • 开始花括号 必须 写在声明的同一行,结束花括号 必须 紧跟主体结束的下一行

  • 参数列表和变量列表的左括号后以及右括号前,一定不可 有空格

  • 参数和变量列表中,逗号前 一定不可 有空格,而逗号后 必须 要有空格

  • 闭包中有默认值的参数 必须 放到列表的后面

  • 标准的闭包声明语句如下所示,注意其「括号」、「空格」以及「花括号」的位置

<?php
$closureWithArgs = function ($arg1, $arg2) {
    // 主体
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // 主体
};
  • 参数列表以及变量列表 可以 分成多行,这样,包括第一个在内的每个参数或变量都 必须 单独成行,而列表的右括号与闭包的开始花括号 必须 放在同一行
<?php
$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
    // 主体
};

$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // 主体
};

$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // 主体
};

$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
    // 主体
};

$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // 主体
};
  • 注意,闭包被直接用作函数或方法调用的参数时,以上规则仍然适用
<?php
$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // 主体
    },
    $arg3
);

日志接口规范

回到顶部

  1. 基本规范
  • LoggerInterface 接口对外定义了八个方法,分别用来记录 RFC 5424 中定义的八个等级的日志:debug、 info、 notice、 warning、 error、 critical、 alert 以及 emergency
  • 第九个方法 —— log,其第一个参数为记录的等级。可使用一个预先定义的等级常量作为参数来调用此方法,必须与直接调用以上八个方法具有相同的效果。如果传入的等级常量参数没有预先定义,则 必须 抛出 Psr\Log\InvalidArgumentException 类型的异常。在不确定的情况下,使用者 不该 使用未支持的等级常量来调用此方法
  1. 日志级别
<?php

namespace Psr\Log;

/**
 * 日志等级常量定义
 */
class LogLevel
{
    const EMERGENCY = 'emergency';
    const ALERT     = 'alert';
    const CRITICAL  = 'critical';
    const ERROR     = 'error';
    const WARNING   = 'warning';
    const NOTICE    = 'notice';
    const INFO      = 'info';
    const DEBUG     = 'debug';
}

知识辅助

回到顶部

  1. 碎知识
  • final—用于类、方法前
  • final类—不可被继承
  • final方法—不可被覆盖
  1. 参考链接
  • 代码开发规范点我 阅读

  • 微信公众平台开发文档点我 阅读

  • 微信小程序平台开发文档点我 阅读

  • 微信开放平台开发文档点我 阅读

  • 支付宝开放平台开发文档点我 阅读

  • Git中文文档点我 阅读

  • Git简单使用点我 阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈文小超_自律

努力自己,幸福他人

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值