目录
前言:............................................................................................. 3
一、 PHP文件说明................................................................................... 3
1.1 PHP标签.................................................................................... 3
1.2 字符编码................................................................................... 3
二、PHP命名规则.................................................................................... 3
2.1 变量命名................................................................................... 3
2.2 常量命名................................................................................... 3
2.3 函数命名................................................................................... 3
2.4 目录文件命名............................................................................... 4
2.5 命名空间和类.............................................................................. 4
三、 PHP的书写格式约定............................................................................. 5
3.1 使用大括号................................................................................. 5
3.2大括号的位置................................................................................ 5
3.3数组格式.................................................................................... 5
3.4 在运算符之间使用空格....................................................................... 6
3.5 运算符优先级............................................................................... 7
3.6 条件语句................................................................................... 7
3.7 语法结构................................................................................... 7
3.8 类......................................................................................... 8
3.9 namespace 以及 use 声明................................................................... 8
3.10 扩展与继承................................................................................ 9
3.11 属性...................................................................................... 9
3.12方法...................................................................................... 10
3.13方法的参数................................................................................ 10
3.14 abstract 、 final 、 以及 static........................................................ 11
3.15 行....................................................................................... 12
3.16 从属效应(副作用)....................................................................... 12
四、PHP的注释..................................................................................... 13
4.1功能说明部分............................................................................... 14
4.2包含声明部分:............................................................................. 14
4.3具体的业务逻辑............................................................................. 14
4.4自定义函数部分:........................................................................... 15
4.5类的注释方式............................................................................... 15
五、Subverion操作约定:........................................................................... 16
- 本规范的目的是让保证team成员编码的统一。
- 本规范的核心规则就是驼峰方式的命名规则。
一、 PHP文件说明
1.1 PHP标签
PHP代码必须使用 <?php ?>
长标签 或 <?= ?>
短输出标签;
一定不可使用其它自定义标签。
1.2 字符编码
PHP代码必须且只可使用不带
BOM
的
UTF-8
编码。
二、PHP命名规则
2.1 变量命名
- 采用驼峰方式。首字母小写,后面的字母按照大小写间隔的方式加以区分,例如userName, serviceID
- 如果有单词缩写,则采用大写形式。如:PID 。
- 应该避免大写的单词在一起,因为无法直接判断单词的分割,例如IMGFile,应该写成imgFile。
- SQL 查询语句中关键词使用大写。 例如:SELECT * FROM userList WHERE
2.2 常量命名
- 采用大写单词与下划线间隔的方式,例如IMATCH_DISPATCHER_API。
2.3 函数命名
- 采用驼峰方式,动词加名词,动词小写,后面的名词用大小写间隔。例如: getAdInfo()
- 如果需要,可以增加小写的前缀,这时动词则大写开始。例如: imGetAdInfo()
- 类的方法命名规则与此相同,不过类的方法一般不需要增加前缀了。
2.4 目录文件命名
- 目录一般采用小写的格式,文件一般采用首字母大写的格式,尽量使用两个以内的单词表达。
- 不建议使用下划线间隔的方式。但如果目录或者文件名过长,无法使用少量单词表达时,应当使用下划线。
- 不建议使用大写字母,但如果要表达的名称是大家约定俗称的,应尊重旧有的习惯。
2.5 命名空间和类
- 一个完全合格的命名空间和类名必须有以下的结构“\<提供者名称>\(<命名空间>\)*<类名>”
- 每个命名空间必须有顶级的命名空间(“提供者”)
- 每个命名空间可以有任意多个子命名空间
- 每个命名空间在被从文件系统加载时必须被转换为“操作系统路径分隔符”(DIRECTORY_SEPARATOR )
- 每个“_”字符在“类名”中被转换为DIRECTORY_SEPARATOR 。“_”符号在命名空间中没有这个含义
- 符合命名标准的命名空间和类名必须以“.php”结尾来加载文件
- 提供商名称,命名空间,类名可以由大小写字母组成,其中命名空间和类名是大小写敏感的以保证多系统兼容性
- 如果文件不存在需要返回false
- 类的命名必须 遵循 StudlyCaps 大写开头的驼峰命名规范。
例如
\Doctrine\Common\IsolatedClassLoader=>/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
\Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
\Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php
下划线在命名空间和类名中的使用
\namespace\package\Class_Name=>/path/to/project/lib/vendor/namespace/package/Class/Name.php
\namespace\package_name\Class_Name=>/path/to/project/lib/vendor/namespace/package_name/Class/Name.php
根据规范,每个类都独立为一个文件,且命名空间至少有一个层次:顶级的组织名称(vendor name)。
三、 PHP的书写格式约定
3.1 使用大括号
在语言结构(if,else,while,switch,for,foreach)中请在陈述与执行的代码分行,执行的代码放到大括号中,大括号不可省略。
例如:
/* 错误示例. */
if (condition) do_stuff();
/* 正确示例. */
if (condition)
{
do_stuff ();
}
3.2大括号的位置
在语言结构(if,else,while,switch,for,foreach)中和类(class)、函数(function)、方法(method)中,左、右大括号必须单独占一行,与其声明处在相同的缩进级别。
例如:
/* 错误示例. */
for ($i = 0;$i < $size;$i++) {
...
}
/* 正确示例. */
for ($i = 0;$i < $size;$i++)
{
...
}
3.3数组格式
对于数组的定义,可以使用分行表述每个"key => value,",每行开头使用四个空格进行缩进。右括号和该array(的起始行保持对齐。
例如:
$arr = [
'name' => '张三', //姓名
'gender' => '男', //性别
'user_id' => 120, //用户ID
];
对于key值命名 采取下划线命名规则例如user_id,不能用userId,UserId这样的命名规则
3.4 在运算符之间使用空格
在比较运算符(>、<、>=、<=、==、===、!=、<>、!==)、赋值运算符(=)、数学运算符(+、-、*、/、%)、位运算符(&、|、^、~、>>、<<)、逻辑运算符(!、&&、||)、冒号(:)、问号(?)、字符串连接运算符(.)、字符串连接赋值运算符(.=)前后,以及左括号(()前(函数调用例外)、逗号(,)后请使用空格进行间隔。
例如:
/* 错误示例. */
$i=0;
/* 正确示例. */
$i = 0;
/* 错误示例. */
if($i<7) ...
/* 正确示例. */
if ($i < 7) ...
/* 错误示例. */
if ( ($i < 7)&&($j > 8) ) ...
/* 正确示例. */
if (($i < 7) && ($j > 8)) ...
/* 错误示例. */
do_stuff($i,"foo",$b);
/* 正确示例. */
do_stuff($i, "foo", $b);
/* 错误示例. */
for($i=0; $i<$size; $i++) ...
/* 正确示例. */
for ($i = 0;$i < $size;$i++) ...
//* 错误示例. */
$i=($j < $size)?0:1;
/* 正确示例. */
$i = ($j < $size) ? 0 : 1;
3.5 运算符优先级
对于容易引起迷惑的表达式中不同运算符的优先级,请使用括号来区分优先级。
例如:
/* 看起来是不是有点费解? */
$bool = ($i < 7 && $j > 8 || $k == 4);
/* 看起来是不是清晰多了? */
$bool = (($i < 7) && (($j < 8) || ($k == 4)))
3.6 条件语句
建议在条件陈述中使用&&和||,不要使用and和or。
例如:
/* 错误示例. */
if (($i < 7) and ($j > 8)) ...
/* 正确示例. */
if (($i < 7) && ($j > 8)) ...
多重if...elseif...else最好换用选择结构体(switch...case)。
3.7 语法结构
- 在PHP中echo、exit(die)、return、continue、break、include、include_once、require、require_once等都属于语法结构,大部分语法结构都有两种形式:
echo 'This is a string';
echo('This is a string');
- 在PHP规定的允许使用的格式下,尽可能使用前一种语法结构的格式,而不要使用函数参数/表达式的形式,仅在参数包含表达式时才需要用括号将其括起来。当返回一个变量时通常不用括号,也建议不要用,这样既可以降低 PHP 的负担,又可以避免一些错误(见下)。
注意: exit(die)只能使用括号结构
- 对于return(),当用引用返回值时永远不要使用括号,只能通过引用返回变量,而不是语句的结果。如果使用 return ($a); 时其实不是返回一个变量,而是表达式 ($a) 的值(当然,此时该值也正是 $a 的值)。
- 由于echo()是语法结构、没有返回值,所以速度比print()快。在输出多个字符串时,请使用echo的多参数方式(逗号,间隔),会比字符串连接方式 (点.间隔)有更好的性能。
3.8 类
- 必须使用PHP5的__construct()和__destruct()方式,禁止使用PHP4的用与类同名函数的方式构造。
- 尽量避免使用魔术方法__get, __set, __autoload 。
- 在类里面多加函数不会影响性能。
- 子类的方法比基类执行得更快。
- 执行一个拥有一个参数和空函数体的函数相当于7-8次局部变量自增操作$localvar++ ,一个相似的方法调用当然就相当于15次局部变量自增操作$localvar++。
- 别在对象构造函数中做实际的工作,构造函数应该包含变量的初始化,但不会发生失败的操作。即构造不能返回错误。例如
class Device
{
public function __construct($param)
{
//这里的代码应该不发生失败
}
public function open()
{
//这里的代码返回失败和成功
}
}
3.9 namespace 以及 use 声明
- namespace 声明后 必须 插入一个空白行。
- 所有 use 必须 在 namespace 后声明。
- 每条 use 声明语句 必须 只有一个 use 关键词。
- use 声明语句块后 必须 要有一个空白行。
例如:
<?php namespace Vendor\Package;
use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass;
|
3.10 扩展与继承
- 关键词 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 { // 常量, 属性, 方法 }
|
3.11 属性
- 每个属性都必须添加访问修饰符。
- 一定不可使用关键字 var 声明一个属性。
- 每条语句一定不可定义超过一个属性。
- 不要使用下划线作为前缀,来区分属性是 protected 或 private。
以下是属性声明的一个范例:
<?php namespace Vendor\Package;
class ClassName { public $foo = null; } |
3.12方法
- 所有方法都必须添加访问修饰符。
- 不要使用下划线作为前缀,来区分方法是 protected 或 private。
- 方法名称后一定不能有空格符,其开始花括号必须独占一行,结束花括号也必须在方法主体后单独成一行。参数左括号后和右括号前一定不能有空格。
一个标准的方法声明可参照以下范例,留意其括号、逗号、空格以及花括号的位置。
<?php namespace Vendor\Package;
class ClassName { public function fooBarBaz($arg1, &$arg2, $arg3 = []) { // 方法内容 } }
|
3.13方法的参数
- 参数列表中,每个参数后面必须要有一个空格,而前面一定不能有空格。
- 有默认值的参数,必须放到参数列表的末尾。
<?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 = [] ) { // 方法内容 } }
|
3.14 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() { // 方法内容 } }
|
3.15 行
- 行的长度一定不能有硬性的约束。
- 软性的长度约束一定要限制在120个字符以内,若超过此长度,带代码规范检查的编辑器一定要发出警告,不过一定不可发出错误提示。
- 每行不应该多于80个字符,大于80字符的行应该折成多行。
- 非空行后一定不能有多余的空格符。
- 空行可以使得阅读代码更加方便以及有助于代码的分块。
- 每行一定不能存在多于一条语句。
3.16 从属效应(副作用)
- 一份PHP文件中应该要不就只定义新的声明,如类、函数或常量等不产生从属效应的操作,要不就只有会产生从属效应的逻辑操作,但不该同时具有两者。
- “从属效应”(side effects)一词的意思是,仅仅通过包含文件,不直接声明类、
函数和常量等,而执行的逻辑操作。 - “从属效应”包含却不仅限于:生成输出、直接的 require 或 include、连接外部服务、修改 ini 配置、抛出错误或异常、修改全局或静态变量、读或写文件等。
以下是一个反例,一份包含声明以及产生从属效应的代码:
<?php // 从属效应:修改 ini 配置 ini_set('error_reporting', E_ALL);
// 从属效应:引入文件 include "file.php";
// 从属效应:生成输出 echo "<html>\n"; // 声明函数 function foo() { // 函数主体部分 }
|
下面是一个范例,一份只包含声明不产生从属效应的代码:
<?php // 声明函数 function foo() { // 函数主体部分 }
// 条件声明**不**属于从属效应 if (! function_exists('bar')) { function bar() { // 函数主体部分 } } |
四、PHP的注释
- 每个文件按照以下顺序排列:功能说明部分、包含声明部分、具体的业务逻辑、自定义函数部分。
- 注释按照phpdoc的标准进行,这样可以和c++程序统一起来。 http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.pkg.html
4.1功能说明部分
在每一个文件的开头部分,要包含这个程序的简要说明、详细说明以及作者和最后修改时间。注释采用phpdoc的注释方式。
<?
/**
* 监控程序(简单注释)
*
* 此脚本程序用来监控搜索所建索引的完整性、一致性、正确性。(详细说明,可选。)。
* @author hemengqiang<hemengqiang@163.com>
* @version $Id$
* @since 2015-12-14 创建日期
*/
?>
说明:
- 详细说明部分是可选的,如果某个文件的逻辑比较复杂,可以在详细说明部分加以解释。
- 其中的$Id$会被自动替换成subverion的相应信息,其中包含文件名、日期、修改者等信息。
4.2包含声明部分:
在每个文档的开头部分包含此程序所用到的包含文件。如:
include 'init.php';
include 'func/common.php';
4.3具体的业务逻辑
- 注释的原则是将问题解释清楚,并不是越多越好。
- 若干语句作为一个逻辑代码块,这个块的注释可以使用/* */方式。
- 具体到某一个语句的注释,可以使用行尾注释:// 或者#,但应当保持风格一致。
/* 生成配置文件、数据文件。*/
$this->setConfig();
$this->clearCache(); # 清除缓存文件。
$this->createDataFiles(); // 生成数据文件。
4.4自定义函数部分:
- 如果当前PHP脚本需要定义一个函数,则在文件头部声明。
- 凡有两个以上文件用到的函数,应将其定义在一个公共的函数库文件中。例如function.php中。
- 自定义函数需包含以下几个部分:函数功能描述、函数参数说明、返回值说明。示例:
<?php
/**
* 数据库连接函数(简单说明)
*
* 通过这个函数链接到数据库,并返回相信的链接标识符。(详细的说明)
* @since 2015-12-18 函数创建日期
* @author hemengqiang 作者
* @global string 数据库服务器(全局变量声明,无需指定变量名,顺序对应)
* @param string $SQL 连接成功以后执行的查询语句,默认为空。(变量声明)
* @return array 返回数据库连接信息。(返回值说明)
*/
function dbConnect ($SQL="")
{
global $mysql;
xxxx;
xxxx;
}
4.5类的注释方式
<?php
/**
* 项目管理 (类的基本说明)
*
* @author hemengqiang 作者
* @package Project 属于哪个模块(部分)
* @version $Id$ 版本
* @date 2015-12-14 创建日期
*/
/* xxx类。*/
class xxx
{
public $binRoot; # xxx运行的根目录。
public $dataRoot; # xxx数据文件所在的目录。
public $configFile; # xxx的配置文件。
/* 构造函数,初始化各个变量。*/
public function xxxx($clearCache = true)
{
/* 设置基本的参数。*/
$this->binRoot = $CFG['binRoot'];
$this->dataRoot = $this->binRoot . 'data/';
}
……
}
- API接口输出
输出结构字段的类型必须统一,否则当强类型语言对接API接口时会出现序列化异常,在PHP中array类型序列化为JSON字符串时会有两种情形:数组、对象。
当要返回的是一个对象时,要判断是否为空数组,如果是,则返回null。
$data = $server->getData();
if(empty($data)){
$data = null;
}
$result = array("code"=>200,"msg"=>"ok","data"=>$data);
- 在程序中需要从数据库获取多条数据明细时,不能使用遍历方式单个的获取数据,必须使用批量方式获取数据。
注意:在使用批量方式获取数据时,注意数据库的限制情况:
SqlServer 对语句的条数和参数的数量都有限制,分别是 1000 和 2100。
Mysql 对语句的长度有限制,默认是 4M。
- 不允许将生产环境的账号密码写在代码中,应通过配置方式读取,以及进行可逆加密。
- 对于输入的字符串,必须进行长度限制,防止写入数据库出现异常。
- 不使用魔法值,应该改用枚举值或常量
正例:
const decimal MAX_ALLOW_WEIGHT = 10;
if ($weight > MAX_ALLOW_WEIGHT)
{
....
}
if($user->userStatus == UserStatus::Enable)
{
....
}
反例:
if ($weight > 10)
{
....
}
if($user->userStatus == 0)
{
....
}
六、Subverion操作约定:
- commit的时候一定要写注释,注释的内容必须是此版本的修改信息。注释信息请按照下面的说明进行:
+ 表示新增功能
* 表示修改功能
- 表示删除的功能; - + - * 前后都有一个空格。