PHP 代码规范

FIG 制定的 PHP 规范,简称 PSR,是 PHP 开发的事实标准。FIGFramework Interoperability Group (框架可互用小组) 的缩写,由几位开源框架的开发者成立于 2009 年。该组织的目的在于:以最低程度的限制,来统一各个项目的编码规范,避免各家自行发展的风格阻碍了程序设计师开发的困扰。PSRProposing a Standards Recommendation (提出标准建议) 的缩写。

PSR 原来有五个规范,分别是:

  • PSR-0 (Autoloading Standard) 自动加载标准。
  • PSR-1 (Basic Coding Standard) 基础编码标准。
  • PSR-2 (Coding Style Guide) 编码风格向导。
  • PSR-3 (Logger Interface) 日志接口。
  • PSR-4 (Improved Autoloading) 自动加载的增强版,可以替换掉 PSR-0 了。

今天我们的代码规范是基于以上规范进行了整理。

1、PHP 源文件只能使用 <?php<?= 这两种标签

<?php 标签通常用于纯 PHP 的脚本当中,而 <?= 通常用于模板当中。

2、PHP 源文件必须是不带 BOMUTF-8 编码的文件

BOM(Byte Order Mark),字节顺序标记,出现在文本文件头部,Unicode 编码标准中用于标识文件是采用哪种格式的编码。

3、PHP 源文件缩进采用 4 个空格

很多编辑器使用 Tab 作为缩进。会造成空格性问题。

4、纯 PHP 代码的源文件关闭标签 ?> 必须省略

PHP 解析器在对文件进行解释的时候,会有性能提升。并且,这能一定程序避免在 ?> 之后有多余的空格导致程序报错。

5、请严格控制每行 120 个字符

过长的代码会导致多种分辨率的显示器造成兼容问题。并且,过长的代码也会造成难以阅读理解。如果实在太长,请把代码换行。

6、所有的类必须设定一个命令空间

命令空间给代码结构有较强的说明性,以及杜绝同名类的冲突问题。同时,也能用到 Composer 的自动加载优势特性。

<?php
namespace core;

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

空行会让代码看起来更加清晰容易阅读。

<?php
namespace core;

use common;

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

这样会让代码结构变得清晰容易阅读。

<?php
namespace core;

use common;

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

虽然 PHP 允许一行代码当中允许使用多个 use 关键字导入一个类。但是,这会使代码阅读造成障碍。

错误:

<?php
namespace core;

use common, library;

正确:

<?php
namespace core;

use common;
use library;

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

空行让代码结构变得容易理解。

<?php
namespace core;

use common;
use library;

class Person {
    
}

11、PHP 关键字必须小写

PHP 的关键字,必须小写,boolean 值:true,false,null 也必须小写。下面的关键字,也必须小写:

'__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor'

12、继承(extends) 和实现(implement) 必须和 class name 写在一行,切花括号要换行写。

<?php
namespace Lib\Databaes;
 
class Mysql extends ParentClass implements \PDO, \DB // 写一行
{ // 换行写{
     
}

13、成员属性访问修饰符必须显示声明不能省略

成员属性有三种访问修饰符:publicprotectedprivate。不能使用老式的 var 来声音成员属性。

<?php
namespace Lib\Databaes;
 
class Mysql extends ParentClass implements \PDO, \DB // 写一行
{
    public    $foo  = null;
    private   $name = 'sam';
    protected $age  = '17';
}

14、成员方法访问修饰符必须显示声明不能省略

成员方法有三种访问修饰符:publicprotectedprivate

错误:

<?php
namespace Lib\Databases;

class MySQL
{
    function fetchOne()
    {
        // ......
    }
}

正确:

<?php
namespace Lib\Databases;

class MySQL
{
    public function fetchOne()
    {
        // ......
    }
}

15、方法的参数有多个的时候,每个参数的逗号后面必须加个空格

namespace Lib\Databaes;
 
class Mysql extends ParentClass implements \PDO, \DB // 写一行
{
    public getInfo ($name, $age, $gender = 1)
    {
    }
}

16、当用到抽象(abstract)和终结(final)来做类声明时,它们必须放在可见性声明(public 还是protected还是private)的前面。而当用到静态(static)来做类声明时,则必须放在可见性声明的后面。

<?php
namespace Vendor\Package;
 
abstract class ClassName
{
    protected static $foo; // static 放后面
 
    abstract protected function zim(); // abstract 放前面
 
    final public static function bar() // final 放前面,static 放最后。
    {
        // 方法主体部分
    }
}

17、控制结构花括号、换行、空格等规范

if、else、elseif、switch、for、foreach、case、while、go、try、catch 等关键词后面必须加空格。可以说,没有特殊说明的情况下,基本上所有的 PHP 关键词后面都必须加空格。

流程控制语句起始的花括号是不需要另起一行。

if ($expr1) { // 左右空格
    // if body
} elseif ($expr2) { // elesif 连着写
    // elseif body
} else {
    // else body;
}

switch ($expr) { // 左右空格
    case 0:
        echo 'First case, with a break'; // 对齐
        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 ($expr) { // 左右空格
    // structure body
}
 
do {
    // structure body; // 左右空格
} while ($expr);

for ($i = 0; $i < 10; $i++) { // 注意几个参数之间的空格
    // for body
}

foreach ($iterable as $key => $value) { // 还是空格问题
    // foreach body
}

try {
    // try body
} catch (FirstExceptionType $e) { // 同样也是注意空格。
    // catch body
} catch (OtherExceptionType $e) {
    // catch body
}

18、类名必须与文件名一样

这个很容易理解,没啥好补充说明的。除非框架有特殊的加载规则。

19、类的命名必须遵循 StudlyCaps 大写开头的驼峰命名规范

StudlyCaps 即单词首字母大写风格。有些人也称它为大驼峰。

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

camelCase 即第一个单词首字母小写后面的单词首字母大写的风格。

21、类中的常量所有字母都必须大写,单词间用下划线分隔

CONST ORDER_STATUS = 1;

22、变量必须使用小驼峰命名风格

$cardNo   = ''; // 卡号。 
$idCardNo = ''; // 身份证号。

23、参数必须使用驼峰命名风格

参数也是变量的一种。故与变量的命名风格一致。

24、所有方法的起始花括号必须另起一行。

虽然以下两种在实际开发中都是允许的。但是,为了保持代码一致。所以,必须强制使用。

错误:

<?php

class MySQL
{
    public function fetchOne() {
        
    }
}

正确:

<?php

class MySQL
{
    public function fetchOne() 
    {
        
    }
}

25、直接在方法中写数组参数时格式如下

$object->callFunc([
    'userId'   => 1,
    'username' => 'sam',
    'age'      => 20,
    'sex'      => 'male'
]);

26、方法参数注释

/**
 * 管理后台获取优惠券发送记录。
 *
 * @author 7031 2018-02-23
 * @modify 7031 2019-02-25 修复了 SQL 性能问题。
 *
 * @param int    $couponId      优惠券ID。
 * @param string $username      用户名。
 * @param string $mobilephone   用户手机号。
 * @param int    $page          当前分页页码。
 * @param int    $count         每页显示条数。
 * @param array  $data          请求参数。
 *
 * ------------------- eg:start ---------------------
 * $data = [
 *     'username' => '用户账号,没有时传空字符串',
 *     'age'      => '用户年龄,没有时传0',
 * ];
 * ------------------- eg:end -----------------------
 *
 * @return array
 */
public static function getBackendSendHistory($couponId = -1, $username, $mobilephone, $page, $count, $data) {

}

可以看出,有以下几个注释特点:

1)方法说明。

2)创建方法的同事编号以及时间。

3)修改方法的同事编号以及时间与修改的内容。

4)参数注释:类型、名称、参数说明。参数与其他注释之间要有空行。

5)参数示例:如果参数当中有复杂的参数。可以在参数下方给出示例以增强说明。

6)返回值。需要给出返回的类型。

27、方法的代码行数不能超过一屏

每个人的显示器分辨率不一样。既然不超过一屏也会出现别的同事一屏会超出的情况。所以,即使未超过一屏,也尽量保证代码行在 40 行以内。如果发现自己的代码超过了 40 行,那么就需要考虑自己的代码是不是有拆分不合理的地方。特殊情况允许超过 40 行。但是,整个方法里面的代码必须是简单的判断逻辑。不包含复杂的业务判断逻辑。因为,不同的业务判断最佳实践是单独封装一个方法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 我们写代码的时候,一个好的编码规范,对我们来说能够起到很多意向不到的效果: 1、提高我们的编码效率。 2、提高代码...
    赵客缦胡缨v吴钩霜雪明阅读 795评论 2 11
  • PHP 代码文件 必须以<?php 开头,不能用<? 以免配置为short_open_tag = off 时造成出...
    Rohn阅读 452评论 0 4
  • 作者:Scholer's Blog原文地址:http://0x1.im/blog/php/tidy-your-ph...
    IT程序狮阅读 738评论 0 4
  • 什么是PSR? PSR是PHP Standards Recommendation的简称,这个是php-fig[ht...
    正义的程序员阅读 47,272评论 4 34
  • “诡”附体 “完了完了!都11点了,今天的面试又要泡汤了,这破手机的闹铃就没准过!” 我急急忙忙起床洗漱完毕,就赶...
    國風千寻阅读 661评论 3 9