PHP 程序编码规范:第 4章 编程规范

2015-03-17 17:43:07 |  分类:PHP

 

系统统一使用时间戳 time()作为时间标志,写入 mysql 时使用 INT(10)类型写入,读取时可以使用公共函数库中的 getdate()将时间戳转换为标准时间格式;

引号统一使用'单引号,只有当引号重叠时才使用"双引号,这样每进程可以节省几百 K 内存;

统一使用<?php ?>,禁止使用<? ?>、<?=?>格式的短标签。

 

4.1 数组定义规则

数组定义和使用时中 key 值前后必须加单引号。

//正确

array(

'name'

'gender'

);

//错误

=> 'd5s.cn',

=> 'php'

array(

name

);

=> 'd5s.cn',

gender => 'php'

 

4.2 不要采用缺省方法测试非零值

不要采用缺省值测试非零值,也就是使用:

if (FAIL != f())

比下面的方法好:

if (f())

即使 FAIL 可以含有 0 值 ,也就是 PHP 认为 false 的表示。在某人决定用-1 代替 0 作为失败返回值的时候,一个显式的测试就可以帮助你了。就算是比较值不会变化也应该使用显式的比较。

例如:

if (!($bufsize % strlen($str)))

   应该写成: if (($bufsize % strlen($str)) == 0)以表示测试的数值(不是布尔)型。

一个经常出问题的地方就是使用 strcmp 来测试一个字符等式,结果永远也不会等于缺省值。

非零测试采用基于缺省值的做法,那么其他函数或表达式就会受到以下的限制:

   只能返回 表示失败,不能为/有其他的值。

   命名以便让一个真(true)的返回值是绝对显然的,调用函数 isValid()而不是 checkvalid()。

Ps:最直接的体现就是 PHP 的 ip2long 函数,在 5.2.10 以前他返回-1 表示出错,之后他返回 false 表示出错.

 

4.3 通常避免嵌入式的赋值

有时候在某些地方我们可以看到嵌入式赋值的语句,那些结构不是一个少冗余,可读性强的好方法。

while ($a != ($c = getchar())) {

process the character

}

++和--操作符类似于赋值语句。因此,出于许多的目的,在使用函数的时候会产生副作用。使用嵌入式赋值提高运行时性能是可能的。无论怎样,程序员在使用嵌入式赋值语句时需要考虑在增长的速度和减少的可维护性两者间加以权衡。

例如:

$a $b+$c;

$d $a+$r;

不要写成:

$d = ($a = $b+$c)+$r;

虽然后者可以节省一个周期。但在长远来看,随着程序的维护费用渐渐增长,程序的编写者对代码渐渐遗忘,就会减少在成熟期的最优化所得。

 

4.4 布尔逻辑类型

大部分函数在 FALSE 的时候返回 0,但是发挥非 0 值就代表 TRUE,因而不要用 1(TRUE,YES,诸如此类)等式检测一个布尔值,应该用 0(FALSE,NO,诸如此类)的不等式来代替:

if (TRUE == func()) {

应该写成:

if (FALSE != func()) {

 

4.5 别在对象构造函数中做实际的工作

别在对象架构构造函数中做实际的工作,构造函数应该包含变量的初始化和(或)不会发生失败的操作。

理由:

构造不能返回错误 。

例如:

class Device {

public function device() /* initialize and other stuff */ }

public function open() return FAIL; }

};

$devObj new Device;

if (FAIL == $devObj ->open()){

    exit(1);

}

ps:通过例子清晰表明,问题所在就是构造函数不能 return.所以不需要 return 的错误就没问题...(出错就自动挂掉全部程序 -_-)

 

4.6 switch 格式

· 当一个 case 块处理后,直接转到下一个 case 块处理,在这个 case 块的最后应该加上注释。

· default case 总应该存在,它应该不被到达,然而如果到达了就会触发一个错误。

· 如果你要创立一个变量,那就把所有的代码放在块中。

例如

switch (...) {

case 1:

...

// FALL THROUGH

case 2:

{

$v get_week_number();

...

}

break;

default:

}

 

4.7 Continue 和 Break

Continue 和 break 其实是变相的隐蔽的 goto 方法。

Continue 和 break 像 goto 一样,它们在代码中是有魔力的,所以要节俭(尽可能少)的使用它们。

使用了这一简单的魔法,由于一些未公开的原因,读者将会被定向到只有上帝才知道的地方去。

Continue 有两个主要的问题:

它可以绕过测试条件。

它可以绕过等/不等表达式。

看看下面的例子,考虑一下问题都在哪儿发生:

while (TRUE) {

...

// A lot of code

...

if (/* some condition */) {

continue;

}

...

// A lot of code

...

if $i++ STOP_VALUE) break;

}

注意: "A lot of code"是必须的,这是为了让程序员们不能那么容易的找出错误。

通过以上的例子,我们可以得出更进一步的规则: continue 和 break 混合使用是引起灾难的正确方法。

ps:刚看还真没发现问题(悲剧),运行后发现问题所在...

 

4.8 ? :

麻烦在于人们往往试着在 和 之间塞满了许多的代码。以下的是一些清晰的连接规则:

把条件放在括号内以使它和其他的代码相分离。

如果可能的话,动作可以用简单的函数。

把所做的动作,“?”“:”放在不同的行,除非他们可以清楚的放在同一行。,

例如:

(condition) ? funct1() func2();

(condition)

long statement

another long statement;

 

4.9 其他杂项

PHP 标签统一使用<?php ?>,禁止使用<? ?>、<?= ?>格式的短标签。

使用完毕后的数组变量、对象变量、查询集合必须马上使用 unset()、free_result()释放资源。

PHP 文件中绝不能出现 html 语句,html 文件中尽可能避免出现 PHP 语句。

html 文件必须通过 w3c 的 html4 检测认证(http://validator.w3.org/)。

如果发觉您在程序中的命名只有少量能和其对应事物相匹配的话,请重新设计系统。

在为类命名前首先要知道它是什么。如果通过类名提供的线索,您还是想不起这个类是什么的话,那么您的设计是做得不够好。

超过三个单词组成的混合名是容易造成系统各个实体间的混淆,请重新设计类。

所有文件的名字均为小写,以兼容 win/unix 类系统。

 

4.9.1 类定义文件中,定义体之外不得出现诸如 echo、print 等输出语句;

理由:

出现这样的语句,应该当做出现 bug 来看。

 

4.9.2 在 HTML 网页中尽量不要穿插 PHP 代码

循环代码和纯粹变量输出(类似于)除外。

理由

需要说明的是我们工作的上游,页面设计者的工作,假如在页面中穿插代码,将破坏结构,这应当是

我们需要避免的。

在这里的 PHP 代码只负责显示,多余的代码显然是不应该的。

 

4.9.3 没有含义的数字

一个在源代码中使用了的赤裸裸的数字是不可思议的数字,因为包括作者,在三个月内,没人它的含义。

例如:

if (22 == $foo) start_thermo_nuclear_war(); }

else if (19 == $foo) refund_lotso_money(); }

else if (16 == $foo) infinite_loop(); }

else cry_cause_im_lost(); }

在上例中 22 和 19 的含义是什么呢?如果一个数字改变了,或者这些数字只是简单的错误,你会怎么想?

使用不可思议的数字是该程序员是业余运动员的重要标志.

你应该用 define()来给你想表示某样东西的数值一个真正的名字,而不是采用赤裸裸的数字,例如:

define("PRESIDENT_WENT_CRAZY", "22");

define("WE_GOOFED", "19");

define("THEY_DIDNT_PAY", "16");

if (PRESIDENT_WENT_CRAZY == $foo) start_thermo_nuclear_war(); }

else if (WE_GOOFED == $foo) refund_lotso_money(); }

else if (THEY_DIDNT_PAY == $foo) infinite_loop(); }

else happy_days_i_know_why_im_here(); }

现在不是变得更好了么?

 

4.9.4 PHP 文件扩展名

常见的 PHP 文件的扩展名有: html, .php, .php3, .php4, .phtml, .inc, .class...

这里我们约定:

· 所有浏览者可见页面使用.html

· 所有类、函数库文件使用.php

理由

· 扩展名描述的是那种数据是用户将会收到的。PHP 是解释为 HTML 的。

 

4.9.5 总是将恒量放在等号/不等号的左边

例如:

if == $errorNum ) ...

一个原因是假如你在等式中漏了一个等号,语法检查器会为你报错。第二个原因是你能立刻找到数值而不是在你的表达式的末端找到它。需要一点时间来习惯这个格式,但是它确实很有用。

 

4.10 SQL 规则

在 PHP 中嵌入的 SQL 语句关键字全部采用大写;

表名和字段名要用反引号(`)引起来以防止因为字段名中包含空格而出现错误。

数据值两边用单引号”包括,并且应确保数据值中的单引号已经转义以防止 SQL 注入。

 正确 $sql ”SELECT `user`.`name` FROM `user` WHERE `id` ’$id’ LIMIT 1″;

  错误 $sql ”select name.user from name where id $id ”;

能使用多表查询一次查询的数据要一次读完,避免多次查询数据库,数据库使用完要关闭连接;

 

4.10.1 输出网页的页面不出现 SQL 语句

理由:

这是 n 层结构的编程思想所致,每层的任务不同,虽然可以越权行使,可能这样很快捷,但我们不赞成这么干。

 

4.10.2 进行 SQL 执行的数据必须进行有效性检测

特殊符号:

对于 MS SQL Server,’%_[ ] 这些符号都是在书写 SQL 语句中的特殊含义字符,在 SQL 执行前需要对这些字符进行处理。

脚本符号:

对于 PHP/javascript 脚本标记,如在进入数据库前需要检测处理。

理由

这是数据库编程的一个约定,很多参考书上也是这么说,这里需要强调一下。

 

 

 

 

2015-03-17 17:43:07 |  阅读( 0 ) |  评论( 0)
分享到: