为了让我们的代码更具可读性以及维护性,同时也为了少写注释,我们希望通过规范的命名以及代码的书写达到 "Code as Document" 的目的。翼高电子商务系统中所有的 PHP 文件必须遵循该文档中规定的编码规范。同时,我们在SVN的服务器端增加了规范检查,如提交的代码中存在不符合规范的代码,SVN会返回错误提示。请仔细 阅读SVN的错误提示,提示中会有详细的出错文件、行数以及不符合规范的描述。
对于第三方的类库,如有必要请和项目管理人联系。
编辑器设置
- 代码缩进:所有的缩进使用空格取代Tab制表符,每一个缩进含有 4 个空格。
- 文件编码:所有PHP文件均保存为 UTF-8 ( No BOM )的字符编码,不允许使用 ANSI 。
命名约定
变量命名
变量名已驼峰方式进行命名,首字母小写,之后的单词的首字母大写。例如:
$currentUser 是正确的, 但是 $currentuser
和 $current_user
就不正确。
$requestUrl 是正确的, 但是 $requestURL
就不正确。
名称应当是描述性的,并且简明。我们自然不希望使用冗长的句子作为变量名,但是多输入几个字符总好于疑惑于某个变量到底是干什么用的。
常量命名
常量命名采用全部大写字母以及下划线(_)组成,例如 ORDER_TYPE。
循环计数器
允许使用一个单字符变量名的唯一情形是当它作为一个循环计数器的时候。在这种情况下,外层循环的计数器应当始终是 $i。如果有一个循环处于这个循环的内部,它的计数器应当是 $j,进而是 $k,等等。如果循环的计数器是一个已经存在并且名字有意义的变量,本规范并不适用。
for ($i = 0; $i < $outerSize; $i++) { for ($j = 0; $j < $innerSize; $j++) { foo($i, $j); } }
函数名称
函数也应该描述性地命名。这里我们并非在用 C 编程,我们不希望写出诸如“stristr()”此类的函数来。同上,单词间用驼峰方式区分。函数名称中某处最好有一个动词。较好的函数名称如printLoginStatus(), getUserData(),等等。
函数参数
参数遵循和变量名字相同的约定。我们不希望一堆这样的函数:doStuff($a, $b, $c)。在大部分情况下,我们希望仅仅看看函数的声明,就知道怎样使用它。参数数量需要控制在5个参数以内,超过5个参数可以使用数组传递。
类
- 类的名称 :首先必须是一个有意义的英文单词或者词组。类名称首字母大写,每个单词的首字母也需要大写。
- 类的成员变量 : 成员变量的命名和变量的命名规范保持一致。
- 类的成员方法 :方法的名称和函数命名保持一致。 需要注意的是 :对于私有方法,我们要求方法名称必须以下划线开始。
总结
这里的基本哲学是不要为了偷懒而伤害了代码的清晰。但是,必须由一些常识来掌握这种平衡;例 如,printLoginStatusForAGivenUser() 做得就过火了――这个函数命名为 printUserLoginStatus() 更好些, 或只是 printLoginStatus()。
代码布局
文件头部
除了模板文件以及第三方的 PHP 程序以外,所有的 PHP 文件头部必须包含一个标准的文件头部来说明这个文件的用途和其他的一些信息。如:
<?php /** * 这里是该文件的描述,说明这个文件的作用 * * $Id$ * * @copyright Xingchangxinda Inc., all rights reserved. * @package Framework * @todo system entrance * @author Weber Liu */ ?>?
其中的copyright等标签请参考 PHP Documention 中的说明。
注释的写法
根据流行的注释写法我们要求对于代码段的注释采用以下的方式来书写:
块级注释:
这种注释用于描述下面多行的用途,一般用空行来区分一个代码块,写法如下
/* 这里是注释的内容 */ /** * 如果注释的内容比较多 * 请用这种方式来写 */?
行内注释:
这种注释用于描述改行的代码,一般来说注释和代码都保持在同一行,如:
$userInfo = $user->getInfo(); // 获得用户的详细资料?
大括号!!!
对于大括号的位置,大家的争议很多,其实对于各种说法来说都有各自的道理,但是有一点基本上大家都是一致的,这就是: 始终使用大括号 ,无论这个语句有多么的短,请始终使用大括号。例如:
/* 这些是对的 */ if (condition) { doStuff(); } while (condition) { doStuff(); } for ($i = 0; $i < size; $i++) { doStuff(); }?
对于大括号的位置,即: 类、函数以及控制语句的大括号始终都在同一行 。例如:
class MyClass { public function foo() { if (cond) { doSomething(); } } }?
符号前后使用空格
这是不用太费事就可以保持代码可读性的另一个简单,容易的步骤。 无论何时你写一个赋值,表达式,等等,始终在符号之间保留一个空格。基本上,把代码当作英语来写。在变量名和运算符之间插入空格。不要在起始括弧后或者终 止括弧前加空格。不要在逗号或者分号之前加空格。一些例子很好地展示了这一点。例如:
/* 每一对给出了错误方式,紧跟正确方式。 */ $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;?
运算符优先级
你知道 PHP 中所有运算符的详细的优先级吗?我不知道。不要猜。始终用括号强制一个表达式的优先级可以使优先级明显,这样你知道它会做些什么。例如:
/* 结果是什么?谁知道? */ $bool = ($i < 7 && $j > 8 || $k == 4); /* 现在你确定这里我在做什么了。 */ $bool = (($i < 7) && (($j < 8) || ($k == 4)))?
数据库命名规范
- 数据库以及数据表的命名与类的命名相同,采用首字母大写的驼峰方式命名。需要注意的是: 所有数据表的名字必须是复数的写法。
- 所有字段的名称应该是由描述性的单词组成,命名的规则和变量命名规范 保持一致。
- 为了配合 ORM 模型,我们要求 所有的主键统一命名为 id
其他规范
if 以及else if的写法
当条件语句中的条件存在多个,并且有变量值的判断的时候,需要把变量的判断语句放在其他的条件语句之前。
/* 正确的写法 */ if (1 === $val && function_exists(‘ob_gzhandler’)) { ... ... } /* 错误的写法 */ if (function_exists(‘ob_gzhandler’) && 1 === $val) { }?
虽然在 PHP 中else if 和 elseif 的作用基本上是一样的。但是为了代码的统一性(也有传言 else if 会出现不稳定的情况),我们要求将 elseif 之间不保留空格:
if (2 == $n) { ... ... } elseif (1 == $n) { ... ... }
上面的代码中,我用到了 1 === $n
这样的写法,而没有采用常见的 $n === 1
写法的,这么做目的是为了避免我们在写双等号时错误的写成了一个等号,而 PHP 并不会报错,这样会造成在调试过程中浪费更多的时间。
在这里我们不强行要求这种写法,但是还是强烈建议: 在写等于的逻辑判断时将常量放在等号的左侧 。
if 语句的简写方式
为了使代码看起来简短一点,对于下面的这种简单的if语句允许采用一种简写的方式:
// 通常的写法 if ($a == $b) { $c = 'foo'; } // 简写的方式 $a == $b && $c = 'foo';