JoshChen_php新手进阶高手不可或缺的规范介绍
1. 为什么要编码规范•编码规范(code conventions)对于程序员而言尤为重要,有以下几个原因:1.在一个软件的生命周期中,80%的花费用于维护。 2.几乎没有任何一个软件在其整个生命周期中均由最初的开发人员来维护。 3.编码规范可以改善软件的可读性,可以让程序员尽快而彻底地理解新的代码。 4.如果将源码作为产品发布,就需要确认它是否被很好地打包并且清晰无误,和其他已构建的任何产品一样。 2. 概要•用四个空格代替tab缩进。•去掉PHP文件底部的“?>”。 •每行程序一般少于80字符,超出部分,分成多行书写。 •每行只写一条语句,不允许把多个短语句写在一行中。 •应为文件和函数添加注释。 •应及时删除废除的注释代码。 •变量、函数的命名应规范。 3. 编辑器设定3.1. 缩进所有的缩进使用空格取代Tab制表符。PHP文件采用4个空格的缩进,HTML文件以及HTML文件中嵌入的Javascript代码采用2个空格的缩进;单独的 Javascript以及CSS文件采用4个空格的缩进。 3.2. 字符编码 4. 代码布局4.1. 文件底部 去掉文件底部 “?>”。 4.2. 相对独立的程序块之间、变量说明之后必须加空行 代码如下: if (!$valid_ni()){ ... // program code } $repssn_ind = $ssn_data['index']->repssn_index; $repssn_ni = $ssn_data['index']->ni; 应如下书写: if (!valid_ni(){ $repssn_ind = $ssn_data['index]->repssn_index; 4.3. 较长的语句要分成多行书写 一行程序需小于80字符 较长的语句要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。 循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首示例: 代码如下: $perm_count_msg->len = NO7_TO_STAT_PERM_COUNT_LEN + STAT_SIZE_PER_FRAM * strlen( $len ); $act_task_table[$frame_id * STAT_TASK_CHECK_NUMBER + $index]->occupied $act_task_table[taskno]->duration_true_or_false if (($taskno < $max_act_task_number) for ($i = 0,$j = 0; ($i < $bufferKeyword['word_index']->word_length) 4.4. 一行只写一条语句 不允许把多个短语句写在一行中,即一行只写一条语句。示例:如下例子不符合规范 $rect->length = 0; $rect->width = 0; 示例:如下例子不符合规范 代码如下: 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(); } 4.6. switch写法 示例:如下例子符合规范 代码如下: switch (){ case ‘1': ..program break; case ‘2': ..program break; } 4.7. 大括号放在哪儿 程序块的分界符(大括号‘{'和‘}')应各独占一行并且位于同一列,同时与引用它们的语句左对齐。 而在函数体的开始、类的定义、以及if、for、do、while、switch、case语句中的右大括号应放在行尾,左大括号应与右大括号所在行的行首处在同一列 示例:如下例子不符合规范 代码如下: for (...) { ... // program code } if (...) function example_fun() if (...){ function example_fun(){ 4.8. 符号之间使用空格 采用这种松散方式编写代码的目的是使代码更加清晰。 由于留空格所产生的清晰性是相对的,所以,在已经非常清晰的语句中没有必要再留空格,如果语句已足够清晰则括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间不必加空格。在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。给操作符留空格时不要连续留两个以上空格。 示例:如下例子不符合规范 代码如下: $i=0; if($i<7) ... if ( ($i < 7)&&($j > 8) ) ... for($i=0; $i<$size; $i++) ... $i=($j < $size)?0:1; do_stuff( $i,"foo",$b ); 应如下书写: 代码如下: $i = 0; if ($i < 7) ... if (($i < 7) && ($j > 8)) ... for ($i = 0; $i < $size; $i++) ... $i = ($j < $size) ? 0 : 1; do_stuff($i,$b); 4.9. 字符串连接符 当使用字符串连接符时必须在句点(.)两侧加上空格。 示例:如下例子不符合规范 代码如下: $str = ‘ $str = ‘ 应如下书写:$str = ‘ 4.10. 空行的使用 谁也不愿意看到挤在一堆的无序的代码。我们在写代码的时候总是会利用一些空行来增加代码可读性。合理的利用空格来区分代码段会使代码的逻辑思路更加明确。我们强行规定的空行有以下两种情况: ••?> 之前必须有且只有1个空行 5. 注释5.1. 文件头部模板/** * ShopEx网上商店 文件中文名称 * 类或者文件的说明,此处可以使用html * * @package * @version $Id$ * @copyright 2003-2008 Shanghai ShopEx Network Tech. Co.,Ltd. * @license Commercial * ================================================================= */ 5.2. 函数头部注释 每个函数之前应当有注释,告诉一个程序员使用这个函数所需要知道的事情。一个最小化的注释应包括:每个参数的意义,期望的输入,函数的输出。注释还应当给出在错误条件下(还有具体是什么错误条件)这个函数的行为。(注释应该确保)其他人不必察看这个函数的代码,就可以自信地在自己的代码中调用这个函数。 另外,为任何技巧性的,晦涩的或者并非显而易见的代码添加注释,无疑是我们应该做的事情。对文档尤其重要的是你的代码所做的任何假设,或者它正确运转的前提。任何一个开发者应该能够查看应用程序的任意部分,并且在合理的时间内断定(代码的执行中)发生了什么。 代码如下: /** * some_func * 函数的含义说明 * 这部分可以随意输入html * 因为这是phpdocument的约定。 * * @param mixed $arg1 参数一的说明 * @param mixed $arg2 参数二的说明 * @access public * @return bool */ 5.3. 删除废除的注释 废除的注释,注释的代码要及时删除 5.4. 常量加注释 示例: 代码如下: // active statistic task number Define(‘MAX_ACT_TASK_NUMBER',1000) Define(‘MAX_ACT_TASK_NUMBER',1000); // active statistic task number 5.5. 注释位置 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。 示例:如下例子不符合规范 例1: 代码如下: // get replicate sub system index and net indicator $repssn_ind = $ssn_data[$index]->repssn_index; $repssn_ni = $ssn_data[$index]->ni; 例2:$repssn_ind = $ssn_data[$index]->repssn_index; $repssn_ni = $ssn_data[$index]->ni; // get replicate sub system index and net indicator 应如下书写 // get replicate sub system index and net indicator $repssn_ind = $ssn_data[$index]->repssn_index; $repssn_ni = $ssn_data[$index]->ni; 5.6. 数据结构声明加注释 数据结构声明(数组),必须加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方。 示例:按如下形式说明 代码如下: // sccp interface with sccp user primitive message name $sccp_user_primitive = array( ‘N_UNITDATA_IND' => 1,// sccp notify sccp user unit data come ‘N_NOTICE_IND => 2,// sccp notify user the No.7 network can not transmission this message N_UNITDATA_REQ => 3 // sccp user's unit data transmission request ) 5.7. 全局变量注释 全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明。 5.8. 注释缩排 示例:如下例子不符合规范 代码如下: function example_fun(){ // code one comments CodeBlock One // code two comments 应改为如下布局: 代码如下: function example_fun(){ //fdgfd CodeBlock One // code two comments 5.9. 将注释与其上面的代码用空行隔开 示例:如下例子,显得代码过于紧凑。 代码如下: // code one comments program code one // code two comments program code two 应如下书写// code one comments program code one // code two comments 5.10. 连续case注释 对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。这样比较清楚程序编写者的意图,有效防止无故遗漏break语句。 示例: 代码如下: switch ($i){ case ‘CMD_INIT': echo "i equals 0"; break; case ‘CMD_START: echo "i equals 1";// now jump into case CMD_A case ‘CMB_A': echo "i equals 2"; break; } 5.11. 结构体声明 代码中代表结构体的数组变量,要提前声明。 示例: 代码如下: function example_fun(){ $student = array( 'name' => '小明',//名称 'addr' => '详细地址',//地址 'sex' => '男',//性别 'city' => '上海' //城市 ) } 5.12. 注释格式 注释格式统一,单行注释必须使用“// …… ”,多行使用一对/*…*/ 示例:如下例子不符合规范。 代码如下: /* if receive_flag is TRUE */ /* if receive_flag is FALSE */ if ($receive_flag) 应如下书写: 代码如下: /* if receive_flag is TRUE if receive_flag is FALSE */ if ($receive_flag) 5.13. 注释以中文为主 注释应考虑程序易读及外观排版的因素,使用的语言若是中、英兼有的,建议多使用中文,除非能用非常流利准确的英文表达。 6. 命名规定6.1. 禁止拼音命名法代码中禁止用拼音命名法。 6.2. 变量命名 例如: $current_user 是正确的, 但是 $currentuser 和 $currentUser 就不正确。 名称应当是描述性的,并且简明。我们自然不希望使用冗长的句子作为变量名,但是多输入几个字符总好于疑惑于某个变量到底是干什么用的。 6.3. 函数命名 示例: 代码如下: function print_record($rec_ind) 动词表:add / edit / remove begin / end create / destroy first / last get / release get / set increment / decrement put / get lock / unlock open / close min / max old / new start / stop next / previous source / target show / hide send / receive cut / paste up / down 系词表: is has 6.4. 循环计数器 例如: 代码如下: for ($i = 0; $i < $outer_size; $i++){ for ($j = 0; $j < $inner_size; $j++){ foo($i,$j); } } 6.5. 函数参数 参数遵循和变量名字相同的约定。我们不希望一堆这样的函数:do_stuff($a,$b,$c)。在大部分情况下,我们希望仅仅看看函数的声明,就知道怎样使用它。 7. 可读性7.1. 运算符的优先级注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。防止阅读程序时产生误解,防止因默认的优先级与设计思想不符而导致程序出错。 示例:下列语句中的表达式 代码如下: $word = ($high << 8) | $low (1) if (($a | $b) && ($a & $c)) (2) if (($a | $b) < ($c & $d)) (3) 如果书写为$high << 8 | $low $a | $b && $a & $c $a | $b < $c & $d 由于$high << 8 | $low = ($high << 8) | $low, $a | $b && $a & $c = ($a | $b) && ($a & $c), (1)(2)不会出错,但语句不易理解;$a | $b < $c & $d = $a | ($b < $c) & $d, (3)造成了判断条件出错。 7.2. 避免数字,使用常量 示例:如下的程序可读性差。 代码如下: if ($trunk[$index]->trunk_state == 0){ $trunk[$index]->trunk_state = 1; ... // program code } 应改为如下形式。 代码如下: define(TRUNK_IDLE,0) define(TRUNK_BUSY,1) if ($trunk[$index]->trunk_state == TRUNK_IDLE){ 7.3. 源程序中关系较为紧密的代码应尽可能相邻 便于程序阅读和查找。 示例:以下代码布局不太合理。 代码如下: $rect->length = 10; $char_poi = $str; $rect->width = 5; 若按如下形式书写,可能更清晰一些。 代码如下: $rect->length = 10;
$rect->width = 5; // 矩形的长与宽关系较密切,放在一起。 $char_poi = $str; 8. 函数8.1. 接口函数参数的合法性检查函数参数的合法性检查应由函数的调用者负责,接口函数做必要性合法性检查(不强制)。 总结为:以外为主,以内为辅,内部不强制。 8.2. 函数规模 8.3. 一个函数仅完成一件功能 8.5. 多段代码重复同一件事情 9. 质量保证9.1. 兼容性9.2. 三元运算符 三元运算符,在一行代码里只允许使用一级 三元运算符只应该用来做简单的事情。它们只适合拿来做赋值用,根本不是用来做函数调用或者任何复杂的事情的。如果使用不当,它们会影响可读性,所以不要沉迷于使用它们来减少打字。 示例:不应该使用它们的地方 示例:使用它们的合适地方$min = ($i < $j) ? $i : $j; 9.3. 初始化变量 示例: 老办法 示例:如下例子不符合规范 代码如下: $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 = " This is '{$what}' with no variables for the parser to find." 9.5. 关联数组的键名 $foo = $assoc_array[blah]; 9.6. 简化运算符 示例:如下例子不符合规范 代码如下: $array[++$i] = $j; $array[$i++] = $k; 应如下书写:$i++; $array[$i] = $j; $array[$i] = $k; $i++; 9.7. if 以及else if的写法 当条件语句中的条件存在多个,并且有变量值的判断的时候,需要把变量的判断语句放在其他的条件语句之前。 示例:如下例子不符合规范 代码如下: if (function_exists(‘ob_gzhandler') && $val == 1){ } 应如下书写:if ($val == 1 && function_exists(‘ob_gzhandler')){ } 虽然在 PHP 中else if 和 elseif 的作用基本上是一样的。但是为了代码的统一性(也有传言 else if 会出现不稳定的情况),我们要求将 elseif 之间不保留空格:if ($bool == 2){ }elseif ($n = 1){ } 9.8. 输入变量的初始化 无论是函数的参数还是通过URL传递的变量,在调用之前均必须对其进行预处理以及设定默认值。 字符串必须进行trim及转义的处理,并且如果变量的值是在我们预计的范围之内,需要对变量的非法值做出相应的处理;对于数字型的变量则需要进行intval或者floatval的处理。 9.9. require和include 对于程序必须包含的文件只能采用require_once,而对于某些有条件包含的文件在引用时只能使用include_once。 9.10. 文件命名 例如: current_user.php 是正确的, 但是 currentuser.php 和 currentUser.php 就不正确。 名称应当是描述性的,并且简明。我们自然不希望使用冗长的句子作为文件名,但是多输入几个字符总好于疑惑于某个文件到底是干什么用的。 10. SQL语法10.1. SQL 代码布局既然我们都在使用不同的编辑器设置,不要尝试去做诸如在 SQL 代码中实现列对齐此类的麻烦事。要做的是,不管用何种方法,把语句断行到它们单独的行上去。这里有一个 SQL 代码看上去应该是什么样子的示例。注意在哪里断行,大写,和括号的用法。 例如: 代码如下: SELECT field1 AS something,field2,field3 FROM `table` a,`table` b WHERE (this = that) AND (this2 = that2) 10.2. 表名和字段值 SQL语句中的表名与字段名避免使用保留字;同时所有字段值的变量名,如果是数值型,需要强制类型转换。intval,floatval… 10.3. SQL select 语句 SELECT * FROM `mytable` 在需要或者满足条件的记录数量的情况下,请使用 SELECT count([*|col1]) FROM 的方式,尽量不要使用 SELECT col1 FROM 的方式。 需要进行逻辑运算的时候,尽量不要使用不等于,可以使用大于或者小于的方式。 10.4. SQL insert 语句 例如: 代码如下: INSERT INTO `mytable` VALUES ('something',1,'else') # 这是正确的。 代码如下: INSERT INTO `mytable` (column1,column2,column3) VALUES ('something','else') 11. smarty语法11.1. 界定符界定符为 <{ }> 11.2. 双引号、单引号 错误的写法: 代码如下: <{if $promote_price>0}>"promote_goods" <{else}>”normal_goods”<{/if}> ><{$goods.goods_name}> 正确的写法: 代码如下: 11.4. 条件修饰符 在smarty中可以用eq、neq、gt、lt等来分别表示==、!=、>、<。那我们到底该使用哪种呢? 当Smarty语句出现在HTML标签内时不允许使用==、!=这类修饰符,如果使用了这类修饰符有可能导致该符号或者其他的HTML相关符号被Dreamweaver自动转义。 总之,尽量使用eq、gt等这类条件修饰符,避免直接使用==、>。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |