A.1.1 常规
对于只包含PHP代码的文件,结束标志("?>")是不允许存在的,否则会导致文件末尾被意外地注入空白并显示输出。
由__HALT_COMPILER()允许的任意的二进制代码的内容被Zend Framework PHP文件或由它们产生的文件禁止。这个功能只对特殊的安装脚本开放。
A.1.2 缩进
使用4个空格的缩进,而不使用制表符TAB。
A.1.3 行的最大长度
一行在80个字符以内比较合适,长些也可以,但最多为120个字符。
A.1.4 行结束标志
行结束标志只能是标准的UNIX文本文件的换行,换行符在文件中表示为10,或十六进制的0x0A。
不要使用Macintosh的回车,如(0x0D)。
不要使用Windows的回车换行组合,如(0x0D,0x0A)。
A.1.5 引号
PHP中单引号和双引号具有不同的含义,主要区别如下:
单引号中,任何变量($var)、特殊转义字符(如"\t \r \n"等)不会被解析,因此PHP的解析速度更快,转义字符仅支持"\'"和"\"这样对单引号和反斜杠本身的转义。
双引号中,变量($var)值会代入字符串中,特殊转义字符也会被解析成特定的单个字符,还有一些专门针对上述两项特性的特殊转义,如"\$"和"{$array['key']}"。这样虽然程序编写更加方便,但PHP的解析也很慢。
数组中,如果下标不是整型,而是字符串类型,必须使用单引号将下标括起,正确的写法为$array['key'],而不是$array[key]。不正确的写法将导致PHP解析器认为key是一个常量,进而先判断常量是否存在,不存在时才以key作为下标传入表达式中,同时触发错误事件,产生一条Notice级错误。
因此,在绝大多数可以使用单引号的场合,都禁止使用双引号。根据上述分析,应该或必须使用单引号的情况如下:
字符串为固定值,不包含"\t"等特殊转义字符。
数组的固定下标,如$array['key']。
表达式中不需要传入变量,如$string = 'string',而非$string = 'string$var'。
还有一些特例,在正则表达式(preg_系列函数和ereg系列函数)中全部使用双引号,这是为了人工分析和编写的方便,并保持正则表达式的统一,减少不必要的分析混淆。
数据库SQL语句中,所有数据都不得加单引号,但是在进行SQL查询之前必须经过intval函数处理;所有字符串都必须加单引号,以避免出现SQL注入漏洞。在SQL查询语句中的正确写法如下:
$user_id = intval($user_id);
select * form tb_user where user_name='
$username' and user_id=$user_id;
缓存文件中,一般对缓存数据的值采用addcslashes($string, '\'\')进行转义。
A.1.6 运算符、小括号、空格和关键词
每个运算符与参与运算的值或表达式之间要有一个空格,唯一的特例是字符连接运算符号两边不加空格。
左括号"("应和函数关键词紧贴在一起,除此以外,应当使用空格将"("同前面内容分开。
右括号")"除后面是")"或者"."以外,其他情况下一律用空格分隔。
除非字符串中有特殊情况,否则,在程序以及HTML中不允许出现两个连续的空格。
任何情况下,PHP程序中的空白行应当不包含任何TAB或空格。同时,任何程序行尾也不能出现多余的TAB或空格。多数编辑器具有自动去除行尾空格的功能,如果未养成良好的编程习惯,可临时使用它,以避免产生多余空格。
每段较大的程序体,上、下应当加入空白行,两个程序块之间只使用一个空行,禁止使用多行。
程序块划分尽量合理,过大或者过小的分割都会影响他人对代码的阅读和理解,一般以较大函数定义、逻辑结构、功能结构来进行划分。少于15行的程序块,可不加上下空白行。
说明或显示部分中,内容如中文、数字、英文单词混杂,应当在数字或者英文单词的前后加入空格。
符合上述编码规范的示例代码如下:
$result = (($a + 1) * 3 / 2 + $num)).'Test';
$condition ? func1($var) : func2($var);
$condition ? $long_statement
: $another_long_statement;
if ($flag)
{
//Statements
//More than 15 lines
}
Showmessage('请使用 restore.php 工具恢复数据。');
A.2.1 类
类名只允许有字母和数字字符,但不鼓励使用数字。下划线只允许作为路径分隔符,如Zend/ Db/Table.php文件中对应的类名称是Zend_Db_Table。
如果类名包含多个单词,每个单词的第一个字母必须大写,连续的大写是不允许的,例如,Zend_PDF是不允许的,而Zend_Pdf是可接受的。
由 Zend 或其参与Zend Framework项目的伙伴公司发行的类必须以Zend_开头并且必须按等级顺序放在Zend/目录下。
A.2.2 接口
接口类也必须遵循同样的约定(如上所述),但必须以Interface结尾,例如:
Zend_Log_Adapter_Interface
Zend_Controller_Dispatcher_Interface
A.2.3 文件名
包含任何PHP代码的任何文件必须以.php扩展名结尾。
函数库和类库程序,应以小写.func.php和.class.php作为扩展名。
流程性程序,以小写.inc.php作为扩展名。
缓存文件,此类文件为系统自动生成,以cache_xxx.php、usergroup_xxx.php、style_xxx.php等类似形式命名,存放于./data/cache目录下。
文件名必须遵循上述的对应类名的规则。
A.2.4 函数和方法
函数名只能包含字母和数字字符,但不鼓励使用数字,不允许使用下划线。
函数名总是以小写字母开头,当函数名包含多个单词时,每个单词的首字母必须大写,这就是所谓的"驼峰"格式。
鼓励使用冗长的名字,这样容易理解代码。下面是符合约定的命名:
filterInput()
getElementById()
widgetFactory()
对于面向对象编程,对象的访问器总是以get或set为前缀。当使用设计模式如单态模式(singleton)或工厂模式(factory)时,方法的名字应当包含模式的名字,这样容易从名字识别设计模式。
在对象中的方法,声明为private或protected的,名称的首字符必须是一个单独的下划线,这是唯一的下划线在方法名字中的用法。声明为public的方法不以下划线开头。
允许但不鼓励全局函数(floating functions),建议把这类函数封装到静态类中。
以标准计算机英文为蓝本,尽量避免使用拼音或拼音英文混合的命名方式。
函数的名字和变量的命名规范一致。
函数定义中的左小括号与函数名之间无空格。
开始的左大括号另起一行。
具有默认值的参数应该位于参数列表的后面。
函数定义与调用的参数之间加入一个空格。
尽量避免函数起始缩进位置与结束缩进位置不同。
符合上述书写规则的函数定义方法如下:
function authcode($string, $operation, $key = '')
{
if($flag)
{
//Statement
}
//函数体
}
A.2.5 变量
变量只包含数字和字母字符,不鼓励使用数字,不允许为下划线。
声明为private或protected的类成员变量名必须以一个单独的下划线开头,这是唯一的下划线在变量名中的用法。声明为public的变量从不以下划线开头。
与函数名一样,变量名总以小写字母开头并遵循"驼峰式"命名约定。
鼓励使用冗长的名字,这样容易理解代码。除在小循环中以外,不鼓励使用简洁的名字(如$i和$n)。如果一个循环超过20行代码,索引的变量名必须是具有描述意义的名字。
变量命名只能使用项目中有据可查的英文缩写方式,例如,可以使用$data而不可使用$data1、$data2这样容易产生混淆的形式,应当使用$username、$password这样能使人一目了然容易理解的形式。
可以合理地对过长的命名进行缩写,如$bio($biography)、$tpp($threadsPerPage),前提是英文中存在这样既有的缩写形式,或字母符合英文缩写规范。
必须清楚所使用英文单词的词性,在权限相关的范围内,大多使用$enable、$is的形式,前者后面接动词,后者后面接形容词。
下面是一些基本的命名规则:
名称的开头不能使用数字及特殊符号。
"·"及类型声明等专用语不能作为名称。
变量或程序名的长度必须在255个字符以内。
和保留字相同的名称不能使用。
A.2.6 常量
常量包含数字、字母和下划线,数字允许作为常量名。
常量名的所有字母必须大写。
为加强可读性,常量中的单词必须以下划线分隔,例如,可以使用EMBED_SUPPRESS_EMBED_ EXCEPTION,但是不允许使用EMBED_SUPPRESSEMBEDEXCEPTION。
常量必须通过const定义为类的成员,不鼓励使用define定义的全局常量。
A.2.7 数据库表和字段
表和字段的命名以命名原则中定义的规范为依据。
所有数据表名称,只要其名称是可数名词,应尽量以复数方式命名;存储多项内容的字段,或代表数量的字段,也应当以复数方式命名,如hits(查看次数)、items(内容数量)。
当几个表间的字段有关联时,要注意表与表之间关联字段命名的统一,如forum_articles表中的articleid与forum_restores表中的articleid。
代表ID自增量的字段,通常用以下几种形式:
一般情况下,使用全称的形式,如userid、articleid。
没有功能性作用,只为管理和维护方便而设的ID,可以使用全称的形式,也可只将其命名为ID。
A.3.1 PHP代码划分(Demarcation)
PHP代码总是用完整的标准的PHP标签定界:
<!--?php?-->
短标签(<? ?>)是不允许的,只包含PHP代码的文件不要结束标签。
A.3.2 字符串
1.字符串文字
如果字符串是文字(不包含变量),则用单引号(apostrophe)引起来:
$a = 'Example String';
2.包含单引号(')的字符串文字
如果文字字符串包含单引号(apostrophe),就用双引号引起来,特别是在SQL语句中:
$sql = "SELECT 'id', 'name' from 'people'
WHERE 'name'='Fred' OR 'name'='Susan'";
在转义单引号时,上述语法是首选。
3.变量替换
变量替换有下面两种形式:
$greeting = "Hello $name, welcome back!";
$greeting = "Hello {$name}, welcome back!";
为保持一致,下面的形式是不允许的:
$greeting = "Hello ${name}, welcome back!";
4.字符串连接
字符串用"."操作符连接,在它的前后加上空格以提高可读性:
$project = 'PHP' . ' ' . 'Zend';
当用"."操作符连接字符串时,代码可以分成多个行,目的也是为了提高可读性。在这些例子中,每个连续的行应当由whitespace来填补,如"."和"="对齐:
$sql = "SELECT 'id', 'name' FROM 'tb_admin ' "
. "WHERE 'name' = 'Susan' "
. "ORDER BY 'name' ASC ";
A.3.3 数组
1.数字索引数组
索引不能为负数。
建议数组索引从0开始。
用array声明有索引的数组,在每个逗号的后面间隔空格以提高可读性:
$exampleArray = array(a, b, c, 'PHP', 'Studio');
也可以用array声明多行有索引的数组,在每个连续行的开头要用空格填补对齐:
$exampleArray = array(a, b, c, 'PHP', 'Studio',
$a, $b, $c,
56.44, $d, 500);
2.关联数组
用array声明关联数组,鼓励把代码分成多行,在每个连续行的开头用空格填补以便对齐键和值:
$exampleArray = array('firstKey' => 'firstValue',
'secondKey' => 'secondValue');
A.3.4 类
1.类的声明
用下面的约定来命名类:
花括号总是从类名下一行开始。
每个类必须有一个符合PHP编码标准的文档块。
4个空格的缩进。
每个PHP文件中只有一个类。
在类中允许放置另外的代码,但不鼓励这样做。在这些文件中,通过两行空格来分隔类和其他代码。示例如下:
/**
* Documentation Block Here
*/
class ExampleClass
{
// entire content of class
// must be indented four spaces
}
2.类成员变量
必须用下面的变量名约定来命名类成员变量:
变量的声明必须在类的顶部,要先于方法的声明。
不允许使用var,应使用private、protected或public。
A.3.5 函数和方法
1.函数和方法声明
必须用下面的变量名约定来命名函数:
在类中的函数必须用private、protected或public声明其可见性。
和类一样,花括号从函数名的下一行开始,函数名与包括参数的圆括号中间没有空格。
不能使用全局函数。
示例如下:
/**
* Documentation Block Here
*/
class Euspice
{
/**
* Documentation Block Here
*/
public function cattle()
{
// entire content of function
// must be indented four spaces
}
}
2.函数和方法的用法
函数的参数用逗号和空格将紧接着的参数分隔。下面例子中的函数带有3个参数:
threeArguments(1, 2, 3);
传值方式在调用时是禁止的。
带有数组参数的函数,函数的调用可包括array并分成多行来提高可读性,同时,书写数组的标准仍然适用:
threeArguments(array(1, 2, 3), 2, 3);
threeArguments(array(1, 2, 3, 'Zend', 'Studio',
$a, $b, $c,
56.44, $d, 500), 2, 3);
A.3.6 控制语句
1.if/else/elseif
使用if/else/elseif的控制语句时,在条件语句的圆括号前后都必须有一个空格。
在圆括号中的条件语句,操作符必须用空格分开,鼓励使用多重圆括号以便在复杂的条件中划分逻辑组合。
前花括号必须和条件语句在同一行,后花括号单独在最后一行,其中的内容用4个空格缩进。
if ($a != 2) {
$a = 2;
}
下面的例子应用if、else和elseif,符合上述格式约定:
if ($a != 2) {
$a = 2;
} else {
$a = 7;
}
if ($a != 2) {
$a = 2;
} elseif ($a == 3) {
$a = 4;
} else {
$a = 7;
}
在有些情况下,PHP允许这些语句不用花括号,但在ZF代码标准里,if、elseif或else语句必须使用花括号。
elseif是允许的但强烈不鼓励使用,最好使用else if组合。
2.switch
在switch结构的控制语句中,条件语句的圆括号前后都必须有一个单独的空格。
switch中的代码必须有4个空格缩进,在case中的代码再缩进4个空格。
switch ($numPeople) {
case 1:
break;
case 2:
break;
default:
break;
}
switch语句中必须有default。
A.3.7 数据库
A.3.8 注释文档
程序注释中要用简单、明了、精确的语言表达出程序的处理说明。应避免每行程序都使用注释,可以在一段程序的前面加一段注释,要具有明确的处理逻辑。注释虽然必不可少,但也不应过多,不要被动地为写注释而写注释。
1.文件
每个包含PHP代码的文件必须至少在文件顶部包含这些phpDocumentor标签:
/**
* 文件的简短描述
*
* 文件的详细描述(如果有的话)... ...
*
* LICENSE: 一些 license 信息
*
* @copyright 2005 Zend Technologies
* @license http://www.zend.com/license/3_0.txt PHP License 3.0
* @version $Id:$
* @link http://dev.zend.com/package/PackageName
* @since File available since Release 1.2.0
*/
2.类
每个类必须至少包含这些phpDocumentor标签:
/**
* 类的简述
*
* 类的详细描述 (如果有的话)... ...
*
* @copyright 2005 Zend Technologies
* @license http://www.zend.com/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://dev.zend.com/package/PackageName
* @since Class available since Release 1.2.0
* @deprecated Class deprecated in Release 2.0.0
*/
3.函数
每个函数,包括对象方法,必须有最少包含下列内容的文档块(docblock):
函数的描述。
所有参数。
所有可能的返回值。
因为访问级已经通过public、private或protected声明,所以不需要使用@access。
如果函数/方法抛出一个异常,使用@throws:
@throws exceptionclass [description]
4.块注释
块注释通常用于提供对文件、方法、数据结构和算法的描述。块注释被置于每个文件的开始处以及每个方法之前,也可以被用于其他地方,如方法内部。在功能和方法内部的块注释应该和它们所描述的代码具有一样的缩进格式。
块注释起始处应该有一个空行,用于把块注释和代码分隔开,例如:
/*
* 这里是块注释
*/
5.单行注释
短注释可以显示在一行内,并与其后的代码具有一样的缩进层级。如果一个注释不能在一行内写完,就应采用块注释。单行注释之前应该有一个空行。以下是一个代码中单行注释的例子:
If (condition) {
/* 以下代码运行的条件 */
...
}
6.尾端注释
极短的注释可以与其所要描述的代码位于同一行,但是应该有足够的空白来分开代码和注释。若有多个短注释出现于大段代码中,它们应该具有相同的缩进。
以下是一个代码中尾端注释的例子:
If ($a == 2) {
return TRUE; /* 对单一条件的说明 */
} Else {
return isPrime($a); /* 其余的条件 */
}
7.行末注释
注释界定符"//",可用于注释整行或者一行中的一部分。
If ($Euspice > 1) {
... //注释用法
}
参考: