对于只包含有 PHP 代码的文件, 结束标志("?>")是不允许存在的, PHP自身不需要("?>"), 这样做, 可以防止它的末尾的被意外地注入相应。
缩进由四个空格组成, 禁止使用制表符 TAB 。您需要调整您的编辑器以适合这一定义
"制表符为4, max length of a tab set tabstop=4 "用空格替换tab, use space to replace a real tab set softtabstop=4 "使用 > 指令时移动的宽度, shift which used by '>' command set shiftwidth=4 "用空格代替制表符, To insert space characters whenever the tab key is pressed set expandtab
一行 80 字符以内是比较合适, 开发者应当努力在可能的情况下保持每行代码少于 80 个字符, 在有些情况下, 长点也可以, 但最多为 120 个字符。
行结束标志遵循 Unix 文本文件的约定, 行必需以单个换行符(LF)结束。换行符在文件中表示为 10, 或16进制的 0x0A。
注:不要使用 苹果操作系统的回车CR(0x0D)或 Windows 电脑的回车换行组合如CR/LF(0x0D,0x0A)。
文件名全部用小写表示, 多个单词使用下划线(_)分割。
类名只允许有字母数字字符, 在大部分情况下不鼓励使用数字。 类名使用大写开头的的驼峰样式, 如
class NameOneTwo { }
方法名使用小写开头的驼峰样式, 如
class NameOneTwo { function doWhat() {}; }
函数名采用C GNU的惯例, 所有的字母使用小写字母, 使用'_'分割单词。如
function show_message () { }
变量名应该全部小写, 必要时使用下划线分隔各个单词, 例如:$current_user 声明为 "private" 或 "protected" 的类成员变量名必须以一个单个下划线开头, 声明为 "public" 的从不以下划线开头
除非在小循环里, 不鼓励使用简洁的名字如 "$i" 和 "$n" 。如果一个循环超过 20 行代码, 索引的变量名必须有个具有描述意义的名字。
常量名全部用大写字母, 多个单词用下划线分割, 如 SITE_ROOT。
数据库表名和列名都使用小写命名。
名字中的单词应使用下划线分割 (例如 product_order)。
对于表名, 你既可以使用单数也可以使用复数。但不要同时使用两者。为简单起见, 我们推荐使用单数名字。
表名可以使用一个通用前缀, 例如 tbl_ 。这样当应用所使用的表和另一个应用说使用的表共存于同一个数据库中时就特别有用。这两个应用的表可以通过使用不同的表前缀很容易地区别开。
这是因为懒惰不愿意多敲两个字符而破坏程序可读性的另一种案例. 即使某些代码结构体只有一行, 也不要忘记括号. 例如:
// 这些是错误的. if (condition) do_stuff(); if (condition) do_stuff(); while (condition) do_stuff(); for ($i = 0; $i < size; $i++) do_stuff($i); // 这些是正确的. if (condition) { do_stuff(); } while (condition) { do_stuff(); } for ($i = 0; $i < size; $i++) { do_stuff(); }
这也是网络上争论不休的话题, 但是我们打算用一种一句话可以描述的风格: 括号总是独自一行. 闭合括号总是和起始括号对齐在同一列上. 例如:
if (condition) { while (condition2) { ... } } else { ... } for ($i = 0; $i < $size; $i++) { ... } while (condition) { ... } function do_stuff() { ... }
在PHP中用两种不同的方式来表示一个字符串 - 单引号或者双引号. 主要的区别在于语法解释器会对双引号表示的字符串进行变量替换, 而不会处理单引号表示的字符串. 因此您应该总是使用单引号, 除非您真的需要在字符串中处理变量. 这样, 我们可以减少程序运行消耗, 因为语法解释器不需要每次多处理一大堆根本没有变量的字符串.
同样, 如果您在函数调用中使用了一个字符串变量作为参数, 您不需要将这个变量包含在引号里. 这会导致语法解释器多做好多无用功. 记住, 几乎所有双引号中的转义符对于单引号都是无效的. 您需要留意以上的规则, 但是有时候为了代码的可读性, 可以适当的破例. 例如:
// 错误 $str = "This is a really long string with no variables for the parser to find."; do_stuff("$str"); // 正确 $str = 'This is a really long string with no variables for the parser to find.'; do_stuff($str);
字符串必需用 "." 操作符连接, 在它的前后加上空格以提高可读性:
$str = $stra . $strb;
在PHP中, 使用不经单引号包含的字符串作为数组键名是合法的, 但是我们不希望如此,键名应该总是由单引号包含而避免引起混淆. 注意这是使用一个字符串, 而不是使用变量做键名的情况.例如:
// 错误 $foo = $assoc_array[blah]; // 正确 $foo = $assoc_array['blah']; // 错误 $foo = $assoc_array["$var"]; // 正确 $foo = $assoc_array[$var];
我们使用了严格的运行时错误报告. 这将意味着未初始化的变量将会产生warning. 使用isset()函数检测变量是否存在能尽量避免这些warning. 但是更可能的是变量总是存在的. 检测一个变量是否有效的方法很简单, 例如:
// 错误 if ($forum) ... // 正确 if (isset($forum)) ... // 正确 if (isset($forum) && $forum == 5)
empty()函数在检查一个变量是否存在或者是否为空的时候非常有用(一个空的字符串, 值为0的数字或字符串变量,NULL, false, 一个空数组或者一个已经声明但是没有值的变量). 因此可以用于替换isset($array) && sizeof($array) > 0 - 这可以简单的写成!empty($array).
Switch/case代码段有时候会比较长. 请注意代码的推进层次, 这样能让代码更加易懂. 例如:
// 错误 switch ($mode) { case 'mode1': // I am doing something here break; case 'mode2': // I am doing something completely different here break; } // 正确 switch ($mode) { case 'mode1': // I am doing something here break; case 'mode2': // I am doing something completely different here break; default: // Always assume that the case got not catched break; } // 这样也正确, 如果您在case和break中包含了很多代码 switch ($mode) { case 'mode1': // I am doing something here break; case 'mode2': // I am doing something completely different here break; default: // Always assume that the case got not catched break; }
不要把小括号和关键词紧贴在一起, 要用空格隔开它们。 不要把小括号和函数名紧贴在一起。 除非必要, 不要在return返回语句中使用小括号。 理由 关键字不是函数。如果小括号紧贴着函数名和关键字, 二者很容易被看成是一体的。 例如
if (condition) { } while (condition) { } strcmp ($s, $s1); return 1;
在赋值运算符( = ), 逻辑运算符(>, < 等), 算术运算符, 连接符(.), 三元操作符 前后各使用一个空格分开, 提高代码可读性, 如:
if ($condition === true) { $str = 'abc' . 'def'; }
SQL 代码常常会变得很长, 如果不作一定的格式规范, 将很难读懂. SQL代码一般按照以下的格式书写, 以关键字换行:
$sql = "SELECT * " . "FROM " . SOME_TABLE . " " . "WHERE a = 1 " . "AND (b = 2 OR b = 3) " . "ORDER BY b";
当用 "." 操作符连接字符串, 代码可以分成多个行, 也是为提高可读性。在这些例子中, 每个连续的行应当由 whitespace 来填补, 例如 "." 和 "=" 对齐:
$sql = "SELECT `id`, `name` FROM `people` " . "WHERE `name` = 'Susan' " . "ORDER BY `name` ASC ";
使用 <> 操作符代替 != The "not equals operator", as defined by the SQL:2003 standard, is "<>"
// 错误的 $sql = "SELECT * " . "FROM " . SOME_TABLE . " " . "WHERE a != 2"; // 正确的 $sql = "SELECT * " . "FROM " . SOME_TABLE . " " . "WHERE a <> 2";
在比较部分如果存在运算请一定要进行优化. 因为这部分会在循环中的每一步进行操作:
// 在每次循环中sizeof函数都要被调用 (低效率) for ($i = 0; $i < sizeof($post_data); $i++) { do_something(); } // 您可以在循环起始部分对这个不变的量赋值 for ($i = 0, $size = sizeof($post_data); $i < $size; $i++) { do_something(); }
变量的声明必须在类的顶部, 在方法的上方声明。
不允许使用 var (PHP 5), 要用 private、 protected 或 public。 私有及保护类成员变量以下划杠开头, 如 private $_var
方法必须用 private、 protected 或 public 声明它们的可见性。 函数名和括参数的圆括号中间没有空格
/** * Documentation Block Here */ class Foo { /** * Documentation Block Here */ public function bar() { // 函数的所有内容 // 必需缩进四个空格 } }
所有文档块 ("docblocks") 必须和 phpDocumentor 格式兼容, phpDocumentor 格式的描述超出了本文档的范围, 关于它的详情, 参考:http://phpdoc.org/。
所有类文件必须在文件的顶部包含文件级 ("file-level")的 docblock , 在每个类的顶部放置一个 "class-level" 的 docblock。下面是一些例子:
/**
* 文件的简短描述
*
* 文件的详细描述(如果有的话)... ...
*
* @copyright Copyright © 2009 Xxx
* @license http://www.xxx.com/license/
* @version $Id$
* @package core
*/
/**
* 类的简述
*
* 类的详细描述 (如果有的话)... ...
*
* @author lostsnow <lostsnow@gmail.com>
* @version $Id$
* @package core
* @since 1.0
*/
每个函数, 包括对象方法, 必须有最少包含下列内容的文档块(docblock):
/**
* 方法/函数简述
*
* 方法/函数的详细描述 (如果有的话)... ...
*
* @code php
* 示例代码
* @endcode
*
* 示例代码说明
*
* @param (string|int|double|bool|array|object|mixed) $param1 desc
* @param (string|int|double|bool|array|object|mixed) $param2 desc
*
* @throws exceptionclass [description]
*
* @return 返回值类型 返回值说明
*
* @todo description
*/
/** * 变量说明 * * @var array(变量类型) */ private static $_ini = array();
// 测试模式 const RUN_MODE_TEST = 'test';