PHP最全编码规约

一、 编码规约

1.1 标签

(1)【强制】PHP 程序可以使用或来界定 PHP 代码,在 HTML 页面中嵌入纯变量时,可以使用这样的形式,不可使用其他的标签变种。

正例:

<?php
/**
 * 编码规约
 * Created by PhpStorm.
 * User: liyh@51cto.com
 * Date: 2022/03/01 16:05
 * Description:
 */

$param1 = 'Hello World!';

?>
<html>
    <title>测试</title>
    <body>
        <div><?php echo $param1?></div>
        <div><?=$param1?></div>
    </body>
</html>

(2)【强制】纯 PHP 类文件,文件最后一个?>省略。

正例:

<?php
/**
 * 纯php文件
 * Created by PhpStorm.
 * User: liyh@51cto.com
 * Date: 2022/03/01 17:15
 * Description:
 */

class RuleController
{
    public function __construct()
    {
        echo "Hello World!";
    }
}

1.2 编码

(1)【强制】PHP 代码必须只使用不带 BOM 的 UTF-8。

1.3 注释

对于注释的要求:第一、能够准确反应设计思想和代码逻辑;第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。

好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的 一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。

所有多行注释都必须带有author和date两个属性。

1)单行注释:在语句结尾用双反斜杠“//”注释

2)多行注释:多行注视以“/*”或“/**”符号开头,以“*/”符号作为注释结束符。

需要生成文档的注释必须是以“/**”开头,以“*/”结尾。主流的 IDE 开发工具(如 Eclipse,PHPStorm等)会用不同的颜色来区分下面的几种注释。

1.3.1 文件注释

(1)【推荐】生成文件时,在文件头部处,需要添加文件描述、创建者和创建时间的多行注释,以/**开头,以*/结尾。

正例:

<?php
/**
 * 编码规约【文件描述】
 * Created by PhpStorm.
 * User: liyh@51cto.com【创建者】
 * Date: 2022/03/01 16:05【创建时间】
 * Description:
 */

1.3.2 类注释

(1)【强制】生成类时,在文件头部处,需要添加类描述、创建者(@author)、创建时间(@date)以及类属性(@property)的多行注释,以/**开头,以*/结尾。

正例:

/**
 * 类概要描述
 * 类详细的描述
 *
 * @author liyh@51cto.com【创建者】
 * @date 2022-03-04【创建时间】
 *
 * @property integer $id 认证ID【属性类型+变量名+描述】
 * @property integer $userId 用户ID【属性类型+变量名+描述】
 */
class TestController
{}

1.3.3 方法注释

(1)【强制】新建方法时,在方法申明头部处,需要添加方法描述、创建者(@author)、创建时间(@date)、参数(@param 类型、变量名、描述、可能的值)及返回结果(@return 类型、变量名、描述、可能的值)的多行注释,以/**开头,以*/结尾。

正例:

/**
 * 方法描述
 * @author liyh@51cto.com【创建者】
 * @date 2022-02-08【创建时间】
 * @param array $params 参数1【参数类型+参数名+参数描述,如果是多层结构,需要将基础结构和对应的字段写出来】
 * array(
 *     "medal_id" => array(),//勋章ID数组
 *     "user_id" => array(),//用户ID数组
 * )
 * @param int $userId 用户ID
 * @return array $return 返回结果【需要返回结果的基础结构和对应的字段描述写出来】
 * array(
 *     "ret" => "0",//错误码,0是成功,其他失败
 *     "reason" => "success",//错误描述
 *     "data" => array(
 *         "user_id" => "用户ID",
 *         ....
 *     )
 * )
 */
public static function run($params, $userId)
{
    $return = [
        'ret' => 0,
        'reason' =>'success',
        'data' => []
    ];
    return $return;
}

1.3.4 属性注释

(1)【推荐】新建类属性时,在属性申明头部处,需要属性描述(@var 类型、变量名、描述、可能的值)的多行注释,以/**开头,以*/结尾。

正例:

/**
 * @var int $public 公共属性
 */
public $public = 0;
/**
 * @var string $private 私有属性
 */
private $private = "";

1.3.5 方法内部注释

(1)【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/* */注释,注意与代码对齐。

正例:

//这是单行注释
$test = 1;
/*
 * 这是多行注释
 */
$rule = 2; //这是单行注释
//逻辑有错,修改 by liyh@51cto.com 2022-03-01
$url = 1;

1.3.6 其它

1、【推荐】待办事宜(TODO):( 标记人,标记时间,[预计处理时间])

表示需要实现,但目前还未实现的功能,但已经被广泛使用。只能应用于类,接口和方法。

正例:

//TODO 待处理逻辑,需要及时处理消除逻辑  by liyh@51cto.com  2022-03-04

2、【强制】错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])

在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。

正例:

//FIXME 标记修复错误代码 by liyh@51cto.com 2022-03-04

3、【强制】谨慎注释掉代码。在上方详细说明,而不是简单地注释掉。如果无用,则删除。说明:代码被注释掉有两种可能性:1)后续会恢复此段代码逻辑。2)永久不用。前者如果没有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。

正例:

/*
临时注释代码后续用于恢复
如果永久不适用,直接删掉   by liyh@51cto.com 2022-03-04
$a = 1;
$b = 2;
*/
$a = 2;
$b = 3;
$c = $a + $b;

反例:

    $a = 2;
    $b = 3;
//    $c = $a + $b;
    $d = $a - $b;
    echo $d;

4、【强制】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改。

说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后,就失去了导航的意义。

5、【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途。

正例:

const STATUS_ON = 1;//启用
const STATUS_OFF = 0;//禁用

const LEVEL1 = 1;//等级1
const LEVEL2 = 2;//等级2
const LEVEL3 = 3;//等级3
const LEVEL4 = 4;//等级4
const LEVEL5 = 5;//等级5
const LEVEL6 = 6;//等级6
const LEVEL7 = 7;//等级7

反例:

const LEVEL1 = 1; 
const LEVEL2 = 2; 
const LEVEL3 = 3; 
const LEVEL4 = 4; 
const LEVEL5 = 5; 
const LEVEL6 = 6; 
const LEVEL7 = 7;

1.4 命名规则

Pascal命名法:所有单词第一个字母大写,其他字母小写。

Camel命名法(驼峰命名法) :除了第一个单词,所有单词第一个字母大写,其他字母小写。

1)【强制】采用英文单词或其组合,便于记忆和阅读,切忌使用汉语拼音来命名;

正例:validCateMedalList(有效分类勋章列表)

反例:yxflxz

2)【强制】杜绝完全不规范的缩写,避免望文不知义;此类随意缩写严重降低了代码的可阅读性;

正例:AbstractClass condition

反例:AbsClass condi

3)【强制】为了达到代码自解释的目标,任何自定义编程元素在命名时,使用尽量完整的单词组合来表达其意,不要嫌名字长;

正例:haveLightNextLevelMedalProgressValueList(已点亮下级勋章进度列表)

反例:list

4)【强制】代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。

正例:haveLightNextLevelMedalProgressValueList(已点亮下级勋章进度列表)

反例:dlxzjdList 中文

说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。

1.4.1 文件

1)【强制】类文件的名称和类名一致;

正例:HelloWorld.php(文件名)=> HelloWorld(类名)

反例:Hello.php(文件名)=> HelloWorld(类名)

2)【推荐】配置文件名小写,多个单词用-分割开;

正例:config.php config-prod.php

反例:Config.php configProd.php

3)【推荐】嵌套 php 的 view 文件使用小写,多个单词用-分隔开;

正例:add-app.php

反例:addApp.php

1.4.2 类

类命名采用 Pascal 命名方法,类名应该和文件名相匹配,如HelloWorld;

正例:HelloWorld

反例:helloWorld helloworld hello-world hello_world

1.4.3 函数/方法

1)【强制】通常方法一般为一个动作或行为动词,函数/方法的命名采用 Camel命名方法;

正例:runAction()

反例:RunAction() run-action() run_action()

2)【强制】尽量用有意义,描述性的词语来命名;

正例:checkForErrors() dumpDataToFile() getUserList()

反例:errorCheck() dataFile() user()

3)【强制】有时前缀名是有用的:

is - 含义为问一个关于某样事物的问题。无论何时,当人们看到 is 就会知道这是一个问题。

get - 含义为取得一个数值。

set - 含义为设定一个数值

update–含义为更新数据

insert/add/save–含义为插入数据

remove/delete–含义为删除数据

count – 含义为计算总数

list – 含义为获取多个对象列表

例如:isHitRetryLimit

正例:isHitRetryLimit() updateUserInfo() getUserInfo() insertUser() countStatusOnUser() listUser() getUserList()

反例:retryLimit() userInfo() userList() statusOn()

4)【推荐】内部成员函数命名应该是以 “_”开始;

正例:function _isUserTicket()

1.4.4 变量名

1)【强制】命名采用 Camel命名方法;

正例:userListuserList userListtestData

反例:user−listuser-list user−listuser_list $UserList

2)【强制】用有意义的,描述性的词语来命名变量;

正例:$haveLightNextLevelMedalProgressValueList(已点亮下级勋章进度列表)

反例:$list

3)【强制】别用缩写。用 name, address, salary 等代替nam, addr, sal,全局变量以”g_”开头;

正例:haveLightNextLevelMedalProgressValueList(已点亮下级勋章进度列表)haveLightNextLevelMedalProgressValueList(已点亮下级勋章进度列表) haveLightNextLevelMedalProgressValueList(已点亮下级勋章进度列表)g_user

反例:$dlxzmedlprosList 中文

4)【强制】别使用单个字母的变量象 i, n, x 等. 使用 index, temp 等 ,用于循环迭代的变量;

正例:for (index=0;index = 0; index=0;index < count;count; count;index++) {... }

反例:for (i=0;i = 0; i=0;i < count;count; count;i++) {... }

1.4.5 常量名

常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不允许出现小写字母,不要嫌名字长。

正例:MAX_STOCK_COUNT

反例:MAX_COUNT

1.5 书写规则

1.5.1 文件

1)【强制】所有的 PHP 文件必须使用 Unix LF(换行)作为行结束符。

2)【强制】所有 PHP 文件必须以一个空行结束。

3)【强制】纯 PHP 代码的文件关闭标签?>必须省略

1.5.2 行

1)【推荐】行长度不可有硬限制。

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

4)【推荐】空行可以用来改善可读性和区分相关的代码块。

正例:

//第一段代码
if ($a = 1) {
    $a = 1;
    $b = 2;
    echo 3;
}

//第二段代码
$d = 1;
$c = 2;
echo $d + $c;

5)【强制】一行不应多于一个语句。

正例:

if ($a = 1) {
    $a = 1; 
    $b = 2; 
    echo 3;
}

反例:

if ($a = 1) {$a = 1; $b = 2; echo 3;}

1.5.3 缩进

每个缩进的单位约定是4个空格的缩进,并且不可使用制表符作为缩进,需每个参与项目的开发人员在编辑器(Eclipse、EditPlus、Zend Studio、PhpStorm 等)中进行强制设定将 TAB 转化为 4 个空格,以防在编写代码时遗忘而造成格式上的不规范。

1.5.4 命名空间

1)【强制】namespace声明之后必须存在一个空行。

2)【强制】所有的use声明必须位于namespace声明之后。

3)【强制】每条use声明必须只有一个use关键字。

4)【强制】use语句块之后必须存在一个空行

正例:(涉及1-4点)

namespace backend\controllers;

use backend\model\BaseBackendController;

class ClassWorkController extends BaseBackendController
{
    
}

反例:(涉及1-4点)

namespace backend\controllers;
use backend\model\BaseBackendController;
class ClassWorkController extends BaseBackendController
{
    
}

1.5.5 控制结构

对于控制结构的样式规则概括如下:

1)【强制】控制结构关键词(if/elseif/else/switch/case/while/for/foreach/try/catch)之后必须有一个空格

2)【强制】左括号之后不可有空格

3)【强制】右括号之前不可有空格

4)【强制】在右括号和左花括号之间必须有一个空格

5)【强制】代码主体必须有一次缩进

6)【强制】右花括号必须主体的下一行

7)【强制】每个结构的主体必须被括在花括号里。这结构看上去更标准化,并且当加新行的时候可以减少引入错误的可能性。

正例:(涉及1-7点)

public static function main() { 
    // 缩进 4 个空格 运算符前后都有空格
    $flag = 0;
    // 关键词 if 与括号之间必须有一个空格,括号内的 $ 与左括号,0 与右括号不需要空格 
    if ($flag == 0) { 
        echo 0;
    }
    
    // 左大括号前加空格且不换行;左大括号后换行 
    if ($flag == 1) {
        echo 1;
    // 右大括号前换行,右大括号后有 else,不用换行 
    } else {
        echo 0;
    // 在右大括号后直接结束,则必须换行 
    }
}

1.5.5.1 if,elseif,else

1)【强制】一个if结构看起来应该像下面这样。注意[括号],[空格],[花括号]的位置;并且 else 和 elseif和前一个主体的右花括号在同一行。

2)【强制】关键词 elseif 应该替代 else if 使用以保持所有的控制关键词像一个单词。

正例:

$flag = 0;
// 关键词 if 与括号之间必须有一个空格,括号内的 $ 与左括号,0 与右括号不需要空格
if ($flag == 0) {
    echo 0;
}

// 左大括号前加空格且不换行;左大括号后换行
if ($flag == 1) {
    echo 1;
// 右大括号前换行,右大括号后有 else,不用换行
} else {
    echo 0;
// 在右大括号后直接结束,则必须换行
}

1.5.5.2 switch, case

1)【强制】一个 switch 结构看起来应该像下面这样。注意[括号],[空格]和[花括号]。case 语句必须从 switch 处缩进,并且 break 关键字(或其他中止关键字)必须和 case 主体缩进在同级。如果一个非空的 case 主体往下落空则必须有一个类似// no break 的注释。

正例:

//关键词 switch 与括号之间必须有一个空格,括号内的 $ 与左括号,2 与右括号不需要空格
switch ($expr2) {//左大括号前加空格且不换行;左大括号后换行
    //缩进4个空格,关键词case与0之间必须有一个空格
    case 0://冒号前没空格,冒号后换行
        //主体缩进4个空格
        echo 'First case, with a break';
    //case主体内容必须有break作为结尾
        break;
    case 1:
        echo 'Second case, which falls through';
        //没有break必须得no break注释
        // no break case 1:
    case 2:
         echo 'Third case, return instead of break'; 
        //用return代替break;
         return;
    default:
        //默认case
        echo 'Default case'; 
        break;
}

1.5.5.3 while, do while

1)【强制】一个 while 语句看起来应该像下面这样。注意括号,[空格]和[花括号]的位置。

正例:

//关键词while与左括号之间必须有一个空格,$与左括号,1与有括号之间不需要空格
while ($expr1) {//左大括号前加空格且不换行,左大括号后换行
    //缩进四个空格
    echo 1;
}

2)【强制】同样的,一个 do while 语句看起来应该像下面这样。注意[括号],[空格]和[花括号]的位置。

正例:

//关键词do与左大括号之间必须有一个空格
do {//左大括号直接换行
    //缩进4个空格
    echo 1;
} while ($expr1);//关键词while与右大括号之间有一个空格且不换行,与左括号之间必须有一个空格,$与左括号,1与有括号之间不需要空格

1.5.5.4 for

1)【强制】一个for 语句看起来应该像下面这样。注意[括号],[空格]和[花括号]的位置。

正例:

//关键词for与左括号之间必须有一个空格,$与左括号,+与有括号之间不需要空格,分号后有一个空格
for ($index = 0; $index < 10; $index++) {//左大括号前加空格且不换行;左大括号后换行,运算符两侧都有空格
    //缩进4个空格
    echo 1;
}

1.5.5.5 foreach

1)【强制】一个foreach 语句看起来应该像下面这样。注意[括号],[空格]和[花括号]的位置。

正例:

$iterable = [1,2,3,4];
//关键词foreach与左括号之间必须有一个空格,$与左括号,e与有括号之间不需要空格
foreach ($iterable as $key => $value) {//左大括号前加空格且不换行;左大括号后换行,as和=>两侧都有空格
    echo 1;
}

1.5.5.6 try, catch

1)【强制】一个try catch 语句看起来应该像下面这样。注意[括号],[空格]和[花括号]的位置。

正例:

//关键词try与左大括号之间必须有一个空格
try {//左大括号后面直接换行
    //缩进4个空格
    echo '1';
//关键词catch两侧都有一个空格,F与左括号,e与右括号之间没有空格
} catch (FirstExceptionType $e) {//右括号与左大括号之间有空格,右大括号后换行
    echo 2;
} catch (OtherExceptionType $e) {
    echo 3;
}

1.5.6 运算符

1)【强制】每个运算符与两边参与运算的值或表达式中间要有一个空格;

正例:a=1;a = 1; a=1;c > d;d; d;a == b;b; b;a = b;b; b;c = a+a + a+b;

反例:b=1;b=1; b=1;c>d;d; d;a==b;b; b;a=b;b; b;c=a+a+a+b;

1.5.7 引号

1)【推荐】在绝大多数可以使用单引号的场合,禁止使用双引号(性能考虑)。可以或必须使用单引号的情况包括但不限于下述:

u 字符串为固定值,不包含“\t”等特殊转义字符;

u 数组的固定下标,例如$array['key'];

u 表达式中不需要带入变量,例如string=′test′;,而非string = 'test';,而非string=′test′;,而非string = "test$var";

正例:array\['key'\]; a = 'test'; a="testtrn";a = "test\\t\\r\\n"; a="testtrn";b = "test$b";

反例:array\["key"\]; a = "test"; a=′testtrn′;a = 'test\\t\\r\\n '; a=′testtrn′;a = ' test$b ';

1.5.8 关键词

1)【强制】PHP keywords 必须使用小写。

正例:for public foreach static use extends

反例:FOR PUBLIC FOREACH STATIC USE EXTENDS

2)【强制】PHP 常量 true, false 和 null 必须使用小写。

正例:true false null

反例:TRUE FALSE NULL

1.5.9 函数

和3.5.12类似,只是不需要申明可见性

1.5.10 类

1)【强制】类必须单独一个源文件,并且类名和文件名相同。

2)【强制】类的左花括号必须放到下一行,右花括号必须放在类主体的下一行。

3)【强制】类文件“?>”结束标记去掉

4)【强制】一个类的 extends 和 implements 关键词必须和类名在同一行。

5)【强制】implements 一个列表可以被拆分为多个有一次缩进的后续行。如果这么做,列表的第一项必须要放在下一行,并且每行必须只有一个接口。

正例:(涉及1-7点)

// extends 和 implements 关键词必须和类名在同一行
class ClassName extends ParentClass implements
    //接口列表拆分成多个换行,每行只能有一个接口
   ArrayAccess, 
   Countable, 
   Serializable
{//花括号单独占一行,左花括号后换行
   //缩进4个空格
   public function test()
    {

    }
}

1.5.11 属性

1)【强制】所有的属性必须声明可见性。

2)【强制】var 关键词不可用来声明属性。

3)【强制】一个语句不可声明多个属性。

4)【推荐】属性名称可以使用单个下划线作为前缀来表明保护或私有的可见性。

正例:(涉及1-4点)

class ClassName
{
    //public设置为公有属性,必须的设置属性的可见性
    public $foo = null;
    //可以用_前缀来标识内部变量
    private $_bar = 1;
}

反例:(涉及1-4点)

class ClassName
{
    //没有申明属性可见性
    $foo = null;
    //不能使用var来申明属性
    var $foo = 1;
    //一条语句不能申明两个属性
    public $a,$b;
}

1.5.12 方法

1)【强制】所有的方法必须声明可见性。

2)【强制】不超过200行代码,尽可能的拆分、复用。

3)【推荐】方法名不应只使用单个下划线来表明是保护或私有的可见性。

4)【强制】方法名在声明之后不可跟随一个空格。左花括号必须放在下面自成一行,并且右花括号必须放在方法主体的下面自成一行。左括号后面不可有空格,右括号前面不可有空格。

5)【强制】在参数列表中,逗号之前不可有空格,逗号之后必须要有一个空格。

6)【强制】方法中有默认值的参数必须放在参数列表的最后面。

7)【强制】参数列表可以被分为多个有一次缩进的多个后续行。如果这么做,列表的第一项必须放在下一行,并且每行必须只放一个参数。

8)【强制】当参数列表被分为多行,右括号和左花括号必须夹带一个空格放在一起自成一行。

9)【强制】如果存在,abstract 和 final 声明必须放在可见性声明前面。

10)【强制】如果存在,static 声明必须跟着可见性声明。

正例:(涉及1-10点)

class Test
{
    //声明必须放在可见性声明前面 static必须放在可见性申明之后,$与左括号,]与右括号之间都没有空格
    abstract public static function hello($arg1, &$arg2, $arg3 = [])//参数后紧跟逗号,逗号后有一个空格,默认参数放在最后
    {//左花括号必须单独成一行
        //缩进8个空格
        echo 1;
    }
    //多个参数换行
    abstract public static function test(
        //参数列表换行 列表的第一项必须放在下一行,并且每行必须只放一个参数
        $arg1,
         &$arg2,
         array $arg3 = []
    ) {
        //当参数列表被分为多行,右括号和左花括号必须夹带一个空格放在一起自成一行
        echo 2;
    }
}
posted @ 2022-08-05 17:09  存活至此的李元霸  阅读(257)  评论(0编辑  收藏  举报