タイトルにあるように、生物界のあらゆるものは成長する必要があり、その成長には邪悪な成長と健全な成長の2種類があります。
私たちが大人になるとき、健全な成長を形成するために、事前に規範を知っておく必要があります。そうしないと、大きな悪い習慣が身についた後、それを後悔することになります。
ということで、今日は参考までにPHPの仕様を整理してみました。誰もがよく言うように、「ルールは死んだ、しかし人は生きている」。はい、でもルールの中で育った人は、とてもうらやましい良い習慣をたくさん持っているでしょう。
すべてのインデントにはタブではなくスペースを使用してください。 PHP ファイルでは 4 スペースのインデントが使用され、HTML ファイルと HTML ファイルに埋め込まれた Javascript コードでは 2 スペースのインデントが使用され、個々の Javascript ファイルと CSS ファイルでは 4 スペースのインデントが使用されます。
すべての PHP および HTML ファイルは、No Bom UTF-8 文字エンコーディングとして保存されます。
ファイルの下部にある「?>」を削除します。
例: 次の例は仕様に準拠していません
リーリーは次のように書く必要があります:
リーリー
プログラムの1行は80文字未満である必要があります
長いステートメントは複数行で記述する必要があり、優先度の低い演算子で新しい行に分割する必要があり、分割された新しい行はレイアウトを適切にインデントする必要があります。 、ステートメントは読み取れます。
ループや判定などに長い式やステートメントがある場合は、優先度の低い演算子で適切に改行し、演算子を改行の先頭に配置する必要があります。 :
リーリー
1 行に複数の短いステートメントを記述することはできません。つまり、1 行に 1 つのステートメントのみを記述します。例: 次の例は仕様に準拠していません
リーリーは次のように書く必要があります:
リーリー リーリーこれは、あと 2 文字を入力するのが面倒なために、コードの明瞭さに問題が生じるもう 1 つの状況です。
例: 次の例は仕様に準拠していません
リーリー次のように書く必要があります
リーリー
例: 次の例は仕様に準拠しています
リーリーブロック区切り文字 (中括弧「{」と「}」) は、それぞれ独立した行に同じ列に配置し、それらを参照するステートメントと左揃えにする必要があります。
関数本体の先頭の右中括弧、クラスの定義、if、for、do、while、switch、case ステートメントは行末に配置し、左中括弧は行末に配置する必要があります。同じ列の右中括弧がある行の先頭
例: 次の例は仕様に準拠していません
リーリー リーリー リーリー
このような緩やかな方法でコードを記述する目的は、コードをより明確にすることです。
スペースを残すことで得られる明確さは相対的なものであるため、すでに非常に明確なステートメントにスペースを残す必要はありません。ステートメントが十分に明確であれば、括弧内 (つまり、左側の後に) にスペースを追加する必要はありません。括弧と右括弧の前) の場合、複数の括弧の間にスペースを追加する必要はありません。長いステートメントで多くのスペースを追加する必要がある場合は、ステートメント全体を明確にし、部分的にスペースを追加しないでください。演算子にスペースを残す場合は、連続して 2 つ以上のスペースを残さないでください。
例: 次の例は仕様に準拠していません
リーリー
は次のように書く必要があります:
リーリー
文字列連結を使用する場合は、ピリオド (.) の両側にスペースを追加する必要があります。
例: 次の例は仕様に準拠していません
リーリー リーリー リーリー
乱れたコードの束を見たい人はいません。コードを記述するときは、コードの可読性を高めるために必ず空白行をいくつか使用します。スペースを適切に使用してコードセグメントを区別すると、コードの論理的な流れがより明確になります。強制的に提供される空白行には、次の 2 つの状況が含まれます:
コードの行末に余分なスペースを含めることはできません。
/** * ShopEx网上商店 文件中文名称 * 类或者文件的说明,此处可以使用html * * @package * @version $Id$ * @copyright 2003-2008 Shanghai ShopEx Network Tech. Co., Ltd. * @license Commercial * ================================================================= * 版权所有 (C) 2003-2009 上海商派网络科技有限公司,并保留所有权利。 * 网站地址:http://www.shopex.cn/ * ----------------------------------------------------------------- * 您只能在不用于商业目的的前提下对程序代码进行修改和使用; * 不允许对程序代码以任何形式任何目的的再发布。 * ================================================================= */
每个函数之前应当有注释,告诉一个程序员使用这个函数所需要知道的事情。一个最小化的注释应包括:每个参数的意义,期望的输入,函数的输出。注释还应当给出在错误条件下(还有具体是什么错误条件)这个函数的行为。(注释应该确保)其他人不必察看这个函数的代码,就可以自信地在自己的代码中调用这个函数。
另外,为任何技巧性的,晦涩的或者并非显而易见的代码添加注释,无疑是我们应该做的事情。对文档尤其重要的是你的代码所做的任何假设,或者它正确运转的前提。任何一个开发者应该能够查看应用程序的任意部分,并且在合理的时间内断定(代码的执行中)发生了什么。
/** * some_func * 函数的含义说明 * <div>这部分可以随意输入<b>html</b></div> * 因为这是phpdocument的约定。 * * @param mixed $arg1 参数一的说明 * @param mixed $arg2 参数二的说明 * @access public * @return bool */
废除的注释,注释的代码要及时删除
对于所有有物理含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以注释,说明其物理含义。变量、常量、宏的注释应放在其上方相邻位置或右方。
示例:
// active statistic task number Define(‘MAX_ACT_TASK_NUMBER’,1000) Define(‘MAX_ACT_TASK_NUMBER’,1000); // active statistic task number
注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
示例:如下例子不符合规范
例1:
// get replicate sub system index and net indicator $repssn_ind = $ssn_data[$index]->repssn_index; $repssn_ni = $ssn_data[$index]->ni;
<span>例2:</span>
$repssn_ind = $ssn_data[$index]->repssn_index; $repssn_ni = $ssn_data[$index]->ni; // get replicate sub system index and net indicator
<span>应如下书写</span>
// get replicate sub system index and net indicator $repssn_ind = $ssn_data[$index]->repssn_index; $repssn_ni = $ssn_data[$index]->ni;
数据结构声明(数组),必须加以注释。对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方。
示例:按如下形式说明
// 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 )
全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明。
注释与所描述内容进行同样的缩排, 可使程序排版整齐,并方便注释的阅读与理解。
示例:如下例子不符合规范
function example_fun(){ // code one comments CodeBlock One // code two comments CodeBlock Two } 应改为如下布局: function example_fun(){ //fdgfd CodeBlock One // code two comments CodeBlock Two }
示例:如下例子,显得代码过于紧凑。
// code one comments program code one // code two comments program code two
<span>应如下书写</span>
// code one comments program code one // code two comments program code two
对于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; }
代码中代表结构体的数组变量,要提前声明。
示例:
function example_fun(){ $student = array( 'name' => '小明', //名称 'addr' => '详细地址', //地址 'sex' => '男', //性别 'city' => '上海' //城市 ) }
注释格式统一,单行注释必须使用“// …… ”,多行使用一对/*…*/
示例:如下例子不符合规范。
/* if receive_flag is TRUE */ /* if receive_flag is FALSE */ if ($receive_flag)
<span>应如下书写:</span>
/* if receive_flag is TRUE if receive_flag is FALSE */ if ($receive_flag)
注释应考虑程序易读及外观排版的因素,使用的语言若是中、英兼有的,建议多使用中文,除非能用非常流利准确的英文表达。
代码中禁止用拼音命名法。
变量名应当全部小写,并且词语之间以单个下划线分隔。
例如: $current_user 是正确的, 但是 $currentuser 和 $currentUser 就不正确。
名称应当是描述性的,并且简明。我们自然不希望使用冗长的句子作为变量名,但是多输入几个字符总好于疑惑于某个变量到底是干什么用的。
使用单词间用单下划线分隔的小写名称,允许动宾词组为执行某操作的函数命名。如果是OOP方法,可以只有动词(名词是对象本身)。允许系表函数命名。
示例:
function print_record($rec_ind) function input_record() function get_current_color() function is_boy()
<span>动词表:</span>
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
<span>系词表:</span>
is has
<span>对于私有方法,以_开头。</span>
允许使用一个单字符变量名的唯一情形是当它作为一个循环计数器的时候。在这种情况下,外层循环的计数器应当始终是 $i。如果有一个循环处于这个循环的内部,它的计数器应当是 $j,进而是 $k,等等。如果循环的计数器是一个已经存在并且名字有意义的变量,本规范并不适用。
例如:
for ($i = 0; $i < $outer_size; $i++){ for ($j = 0; $j < $inner_size; $j++){ foo($i, $j); } }
参数遵循和变量名字相同的约定。我们不希望一堆这样的函数:do_stuff($a, $b, $c)。在大部分情况下,我们希望仅仅看看函数的声明,就知道怎样使用它。
注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。防止阅读程序时产生误解,防止因默认的优先级与设计思想不符而导致程序出错。
示例:下列语句中的表达式
$word = ($high << 8) | $low (1) if (($a | $b) && ($a & $c)) (2) if (($a | $b) < ($c & $d)) (3)
<span>如果书写为</span>
$high << 8 | $low $a | $b && $a & $c $a | $b < $c & $d
<span>由于</span>
$high << 8 | $low = ($high << 8) | $low, $a | $b && $a & $c = ($a | $b) && ($a & $c),
<span>(1)(2)不会出错,但语句不易理解;</span>
$a | $b < $c & $d = $a | ($b < $c) & $d,
<span>(3)造成了判断条件出错。</span>
避免使用不易理解的数字,用有意义的常量来替代。
示例:如下的程序可读性差。
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){ $trunk[$index]->trunk_state = TRUNK_BUSY; ... // program code }
便于程序阅读和查找。
示例:以下代码布局不太合理。
$rect->length = 10; $char_poi = $str; $rect->width = 5;
若按如下形式书写,可能更清晰一些。
$rect->length = 10; $rect->width = 5; // 矩形的长与宽关系较密切,放在一起。 $char_poi = $str;
函数参数的合法性检查应由函数的调用者负责,接口函数做必要性合法性检查(不强制)。
总结为:以外为主,以内为辅,内部不强制。
函数的规模限制在100行以内,不包括注释和空格行。
除调度函数外,多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难
如果多段代码重复做同一件事情,那么在函数的划分上可能存在问题。若此段代码各语句之间有实质性关联并且是完成同一件功能的,那么可考虑把此段代码构造成一个新的函数。
三元运算符,在一行代码里只允许使用一级
三元运算符只应该用来做简单的事情。它们只适合拿来做赋值用,根本不是用来做函数调用或者任何复杂的事情的。如果使用不当,它们会影响可读性,所以不要沉迷于使用它们来减少打字。
示例:不应该使用它们的地方
(($i < $size) && ($j > $size)) ? do_stuff($foo) : do_stuff($bar);
示例:使用它们的合适地方$min = ($i < $j) ? $i : $j;
变量使用前应初始化,error_reporting 将加入 E_NOTICE。意味着,变量未初始化将报错。这个问题最容易在检查 HTML 表单传递了什么变量时出现。这些错误可以通过使用内嵌的 isset() 或者empty()函数检查一个变量是否被设置来避免。
示例: 老办法
if ($forum) ...
<span>新办法:</span>
if (!empty($forum)) ... if (isset($forum)) …
在 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);
<span>当由于可读性的原因不得不使用双引号作为引用符时,注意其中所有的变量需用{}包围:</span>
$str = " This is '{$what}' with no variables for the parser to find."
在 PHP 中,使用一个不用引号括起来的字符串作为一个关联数组的键名是可以运行的。我们不想这样做——为了避免混乱,这个字符串应当用引号括起来。注意,这只是当我们使用字符串时的情况,不是当我们使用变量时的情况。示例:如下例子不符合规范
$foo = $assoc_array[blah];
应如下书写:
$foo = $assoc_array['blah'];
简化自增($i++)和自减($i--)运算符是导致可读性问题的仅有的简化运算符。这些运算符不应当被用作表达式的一部分。然而,他们可以独占一行使用。在表达式中使用它们(带来的便利)还不够调试时头痛的(代价)。
示例:如下例子不符合规范
$array[++$i] = $j; $array[$i++] = $k;
<span>应如下书写:</span>
$i++; $array[$i] = $j; $array[$i] = $k; $i++;
当条件语句中的条件存在多个,并且有变量值的判断的时候,需要把变量的判断语句放在其他的条件语句之前。
示例:如下例子不符合规范
if (function_exists(‘ob_gzhandler’) && $val == 1){ }
<span>应如下书写:</span>
if ($val == 1 && function_exists(‘ob_gzhandler’)){ }
<span>虽然在 PHP 中else if 和 elseif 的作用基本上是一样的。但是为了代码的统一性(也有传言 else if 会出现不稳定的情况),我们要求将 elseif 之间不保留空格:</span>
if ($bool == 2){ }elseif ($n = 1){ }
无论是函数的参数还是通过URL传递的变量,在调用之前均必须对其进行预处理以及设定默认值。
字符串必须进行trim及转义的处理,并且如果变量的值是在我们预计的范围之内,需要对变量的非法值做出相应的处理;对于数字型的变量则需要进行intval或者floatval的处理。
在程序中需要使用包含文件的时候我们要求使用require_once或者include_once,不允许使用require或者include。
对于程序必须包含的文件只能采用require_once,而对于某些有条件包含的文件在引用时只能使用include_once。
文件名应当全部小写,并且词语之间以单个下划线分隔。
例如: current_user.php 是正确的, 但是 currentuser.php 和 currentUser.php 就不正确。
名称应当是描述性的,并且简明。我们自然不希望使用冗长的句子作为文件名,但是多输入几个字符总好于疑惑于某个文件到底是干什么用的。
既然我们都在使用不同的编辑器设置,不要尝试去做诸如在 SQL 代码中实现列对齐此类的麻烦事。要做的是,不管用何种方法,把语句断行到它们单独的行上去。这里有一个 SQL 代码看上去应该是什么样子的示例。注意在哪里断行,大写,和括号的用法。
例如:
SELECT field1 AS something, field2, field3 FROM `table` a, `table` b WHERE (this = that) AND (this2 = that2)
SQL语句中的表名与字段名避免使用保留字;同时所有字段值的变量名,如果是数值型,需要强制类型转换。intval,floatval…
在已知需要查询的字段的前提下,不允许使用如下的代码:
SELECT * FROM `mytable`
<span>取而代之的写法是将每一个字段名写上去,请不要偷懒。</span>
SELECT col1, col2, col3 FROM `mytable`
<span>在需要获得已知记录数量情况下,请使用 LIMIT offset, count 的方式,尽量不要使用无 LIMIT 的 SELECT 语句。</span>
在需要或者满足条件的记录数量的情况下,请使用 SELECT count([*|col1]) FROM 的方式,尽量不要使用 SELECT col1 FROM 的方式。
需要进行逻辑运算的时候,尽量不要使用不等于,可以使用大于或者小于的方式。
SQL INSERT 语句可以写成两种不同方式。或者你明确指明要插入的列,或者你已经知道数据中各列的顺序,不用详细指定它们。我们希望使用前一种方法,也就是详细说明插入哪些列。这意味着应用程序代码不会依赖于数据库中字段的顺序,也不会因为我们增加另外的字段而崩溃(当然,除非它们被指定为 NOT NULL)。
例如:
# 这不是我们想要的 INSERT INTO `mytable` VALUES ('something', 1, 'else') # 这是正确的。 INSERT INTO `mytable` (column1, column2, column3) VALUES ('something', 1, 'else')
界定符为 <{ }>
为了避免dreamweaver将Smarty语句中的双引号改写为",我们要求在Smarty的花括号中不允许使用双引号,而是使用单引号。
错误的写法:
<{if $user_name eq ""}>匿名用户<{/if}> <{insert name=”query_info”}>
<span>正确的写法:</span>
<{if $user_name eq ''}>匿名用户<{/if}> <{insert name=’query_info’}>
当需要在模板中有条件的设置HTML元素属性值的时候,我们要求所有语句均包含在双引号之内。错误的代码:
<div class= <{if $promote_price>0}>"promote_goods" <{else}>”normal_goods”<{/if}> ><{$goods.goods_name}></div>
正确的写法:
<div class="<{if $promote_price gt 0}>promote_goods <{else}>nomarl_goods<{/if}>"><{$goods.goods_name}></div>
在smarty中可以用eq、neq、gt、lt等来分别表示==、!=、>、<。那我们到底该使用哪种呢?
当Smarty语句出现在HTML标签内时不允许使用==、!=这类修饰符,如果使用了这类修饰符有可能导致该符号或者其他的HTML相关符号被Dreamweaver自动转义。
总之,尽量使用eq、gt等这类条件修饰符,避免直接使用==、>。
<br /><br />