推荐的PHP编码规范

简介: 推荐的PHP编码规范 发布时间: 2014-05-7 浏览次数:2754 分类: PHP教程 推荐的PHP编码规范   一 编辑器设置 1. 使用Tab缩进,不要使用空格鉴于很多编辑器在保存文件时会自动清除用于缩进的空格,所以我们一律使用Tab键进行缩进。

推荐的PHP编码规范

发布时间: 2014-05-7 浏览次数:2754 分类: PHP教程

推荐的PHP编码规范

 

一 编辑器设置


1. 使用Tab缩进,不要使用空格

鉴于很多编辑器在保存文件时会自动清除用于缩进的空格,所以我们一律使用Tab键进行缩进。

2. UNIX文件格式

请将编辑器设置对所有程序使用UNIX格式保存,不要使用Win32或者Mac的格式。例如,EditPlus里面Document->File Format(CR/LF)->Unix 。

对于windows格式文件,以Ctrl + M结束(vim下为^M),需要过滤掉:

$text = strtr($text, "\x0D", "");

二 命名约定

1. 公共库名称空间

TPLIB,Tencent PHP Library

2. 常量名

全局常量,用'_'分隔每个单词,使用TPLIB_前缀。如:define("TPLIB_TEST_HELLO", "Hello world!");

 

类常量,用'_'分隔每个单词,如:

  1. class TPLIB_Package
  2.  
  3. {
  4.  
  5. const EXAMPLE_CONST;
  6.  
  7. }



尽量使用类常量代替全局常量。

3. 变量名

局部变量的字母都使用小写,使用“_”作为每个词的分界。如:$php_var;

函数、方法的参数,首字母为小写。如:

  1. function test_func($paramName)
  2.  
  3. {
  4.  
  5. }


类属性,使用骆驼命名法命名,与函数、方法的参数命名方法相同;

全局变量,字母都使用大写,使用“_”作为每个词的分界,公共库中无特殊需求不使用全局变量。

命名必须具有描述性,但务求简练。不要在变量名中使用长句。通常在变量名中使用一对词语(使用下划线间隔)对变量进行简要描述这种方式更好。

4. 循环索引变量

在循环结构中,仅允许使用一个字母长度的循环索引变量。通常我们使用 $i,如果存在嵌套循环,那么子循环的索引变量应该使用 $j,其下级循环的索引变量就是 $k, 以此类推。如果循环被原已存在一些有具体含义名称的变量索引,则不受此规定约束。

例如:

  1. for ($i = 0;$i < $outer_size;$i++)
  2.  
  3. {
  4.  
  5. for ($j = 0;$j < $inner_size;$j++)
  6.  
  7. {
  8.  
  9. foo($i,$j);
  10.  
  11. }
  12.  
  13. }


5. 类的方法命名

使用骆驼命名法命名,例如 getCache()、echoName()。名字采用“动词+宾语”的形式。例如 write(动词)Cache(宾语)。

6. 函数命名

函数应该使用描述性词语命名。我们不使用C的方式,也不使用类似"stristr()"这种没有描述、令人费解的函数名。所有函数名必须全部使用英文小写字母,函数名中的单词之间使用下划线间隔。某些情况下,函数名中更适合使用动词。例如:print_login_status(),get_user_data(),等等。

一个基本的哲学观点,就是不要仅仅出于懒惰而去破坏代码的清晰。比如print_login_status_for_a_given_user() 太长,换成print_user_login_status()会更好,或者仅仅用print_login_status()。

7. 函数自变量

自变量的命名应遵守变量命名规定。我们不想使用do_stuff($a,$b,$c) 中的$a,$b,$c这种缺乏实际表述意义的名称。多数情况下,我们希望能够仅仅通过查看函数的声明就可以了解如何去使用函数。

8. 名称空间与类命名

使用帕斯卡命名方法,如HelloWorld。

由于PHP 5.3版本之前没有实现命名空间语法,这给类命名带来了一定的麻烦。

这里使用类名中附带名称空间的命名方法,名称空间与类名间使用下划线连接。

如TPLIB库中Test包的HelloWorld类:TPLIB_Test_HelloWorld

所有库中的类,都以TPLIB_ 开头,根据用途命名。将类名字中的“_”替换为目录分隔符,就是这个类的定义文件所在位置。这种命名规则和目录结构可以避免命名冲突,根据类名字就能找到文件存放位置。

如:

TPLIB_Test_HelloWorld 类在库中的位置为 TPLIB/Test/HelloWorld.php

9. 文件命名

包含文件应该以.inc.php方式命名,例如config.inc.php。单独类的文件使用Classname.php方式命名,包中的类使用 PackageName/ClassName.php命名。

三 代码层

1.使用大括号

在语言结构(if,else,while,switch,for,foreach)中请在陈述与执行的代码分行,执行的代码放到大括号中,大括号不可省略。

例如:

  1. /* These are all wrong. */
  2.  
  3. if (condition) do_stuff();
  4.  
  5. if (condition)
  6.  
  7. do_stuff();
  8.  
  9. while (condition)
  10.  
  11. do_stuff();
  12.  
  13. for ($i = 0; $i < size; $i++)
  14.  
  15. do_stuff($i);
  16.  
  17.  
  18. /* These are right. */
  19.  
  20. if (condition)
  21.  
  22. {
  23.  
  24. do_stuff ();
  25.  
  26. }
  27.  
  28. while (condition)
  29.  
  30. {
  31.  
  32. do_stuff ();
  33.  
  34. }
  35.  
  36. for ($i = 0;$i < size;$i++)
  37.  
  38. {
  39.  
  40. do_stuff ();
  41.  
  42. }



2.大括号的位置

在语言结构(if,else,while,switch,for,foreach)中和类(class)、函数(function)、方法(method)中,左、右大括号必须单独占一行,与其声明处在相同的缩进级别。

例如:

  1. /* These are all wrong. */
  2.  
  3. if (condition) {
  4.  
  5. while (condition2) {
  6.  
  7. ...
  8.  
  9. }
  10.  
  11. } else {
  12.  
  13. ...
  14.  
  15. }
  16.  
  17.  
  18. /* These are right. */
  19.  
  20. if (condition)
  21.  
  22. {
  23.  
  24. while (condition2)
  25.  
  26. {
  27.  
  28. ...
  29.  
  30. }
  31.  
  32. }
  33.  
  34. else
  35.  
  36. {
  37.  
  38. ...
  39.  
  40. }
  41.  
  42.  
  43. /* These are all wrong. */
  44.  
  45. for ($i = 0;$i < $size;$i++) {
  46.  
  47. ...
  48.  
  49. }
  50.  
  51.  
  52. /* These are right. */
  53.  
  54. for ($i = 0;$i < $size;$i++)
  55.  
  56. {
  57.  
  58. ...
  59.  
  60. }
  61.  
  62.  
  63. /* These are all wrong. */
  64.  
  65. while (condition) {
  66.  
  67. ...
  68.  
  69. }
  70.  
  71.  
  72. /* These are right. */
  73.  
  74. while (condition)
  75.  
  76. {
  77.  
  78. ...
  79.  
  80. }
  81.  
  82.  
  83. /* These are all wrong. */
  84.  
  85. switch (condition) {
  86.  
  87. case: 1
  88.  
  89. ...
  90.  
  91. default:
  92.  
  93. ...
  94.  
  95. }
  96.  
  97.  
  98. /* These are right. */
  99.  
  100. switch (condition)
  101.  
  102. {
  103.  
  104. case: 1
  105.  
  106. ...
  107.  
  108. default:
  109.  
  110. ...
  111.  
  112. }
  113.  
  114.  
  115. /* These are right. */
  116.  
  117. function do_stuff()
  118.  
  119. {
  120.  
  121. ...
  122.  
  123. }
  124.  
  125.  
  126. /* These are right. */
  127.  
  128. class some_class
  129.  
  130. {
  131.  
  132. function a_method()
  133.  
  134. {
  135.  
  136. ...
  137.  
  138. }
  139.  
  140. }


3.数组格式

对于数组的定义,可以使用分行表述每个"key => value,",每行开头使用一个Tab进行缩进。右括号和该array(的起始行保持对齐。

例如:

  1. $arr = array(
  2.  
  3. 'key1' => 'value1',
  4.  
  5. 'index1' => 'value2',
  6.  
  7. );


4.在运算符之间使用空格

在比较运算符(>、<、>=、<=、==、===、!=、<>、!==)、赋值运算符(=)、数学运算符(+、-、*、/、%)、位运算符(&、|、^、~、>>、<<)、逻辑运算符(!、&&、||)、冒号(:)、问号(?)、字符串连接运算符(.)、字符串连接赋值运算符(.=)前后,以及左括号(()前(函数调用例外)、逗号(,)后请使用空格进行间隔。

例如:

  1. /* These are all wrong. */
  2.  
  3. $i=0;
  4.  
  5. /* These are all right. */
  6.  
  7. $i = 0;
  8.  
  9.  
  10. /* These are all wrong. */
  11.  
  12. if($i<7) ...
  13.  
  14. /* These are all right. */
  15.  
  16. if ($i < 7) ...
  17.  
  18.  
  19. /* These are all wrong. */
  20.  
  21. if ( ($i < 7)&&($j > 8) ) ...
  22.  
  23. /* These are all right. */
  24.  
  25. if (($i < 7) && ($j > 8)) ...
  26.  
  27.  
  28. /* These are all wrong. */
  29.  
  30. do_stuff($i,"foo",$b);
  31.  
  32. /* These are all right. */
  33.  
  34. do_stuff($i, "foo", $b);
  35.  
  36.  
  37. /* These are all wrong. */
  38.  
  39. for($i=0; $i<$size; $i++) ...
  40.  
  41. /* These are all right. */
  42.  
  43. for ($i = 0;$i < $size;$i++) ...
  44.  
  45.  
  46. /* These are all wrong. */
  47.  
  48. $i=($j < $size)?0:1;
  49.  
  50. /* These are all rightg. */
  51.  
  52. $i = ($j < $size) ? 0 : 1;


5.运算符优先级

对于容易引起迷惑的表达式中不同运算符的优先级,请使用括号来区分优先级。

例如:

  1. /* what's the result? who knows. */
  2.  
  3. $bool = ($i < 7 && $j > 8 || $k == 4);
  4.  
  5.  
  6. /* now you can be certain what I'm doing here. */
  7.  
  8. $bool = (($i < 7) && (($j < 8) || ($k == 4)))



6.条件语句

请在条件陈述中使用&&和||,不要使用and和or。

例如:

  1. /* These are all wrong. */
  2.  
  3. if (($i < 7) and ($j > 8)) ...
  4.  
  5. /* These are all right. */
  6.  
  7. if (($i < 7) && ($j > 8)) ...


    多重if...elseif...else最好换用选择结构体(switch...case)。

7.语法结构

在PHP中echo、exit(die)、return、continue、break、include、include_once、require、require_once等都属于语法结构,大部分语法结构都有两种形式:

echo 'This is a string';

echo('This is a string');

在PHP规定的允许使用的格式下,尽可能使用前一种语法结构的格式,而不要使用函数参数/表达式的形式,仅在参数包含表达式时才需要用括号将其括起来。当返回一个变量时通常不用括号,也建议不要用,这样既可以降低 PHP 的负担,又可以避免一些错误(见下)。

注意:  exit(die)只能使用括号结构

对于return(),当用引用返回值时永远不要使用括号,只能通过引用返回变量,而不是语句的结果。如果使用 return ($a); 时其实不是返回一个变量,而是表达式 ($a) 的值(当然,此时该值也正是 $a 的值)。

  1. // won't work, evaluated as include(('vars.php') == 'OK'), i.e. include('')
  2. if (include('vars.php') == 'OK')
  3.  
  4. {
  5. echo 'OK';
  6. }
  7.  
  8. // works
  9. if ((include 'vars.php') == 'OK')
  10.  
  11. {
  12. echo 'OK';
  13. }


由于echo()是语法结构、没有返回值,所以速度比print()快。在输出多个字符串时,请使用echo的多参数方式(逗号,间隔),会比字符串连接方式 (点.间隔)有更好的性能。


8.类

    必须使用PHP5的__construct()和__destruct()方式,禁止使用PHP4的用与类同名函数的方式构造。

    避免使用魔术方法__get, __set, __autoload 。

在类里面多加函数不会影响性能。

子类的方法比基类执行得更快。

执行一个拥有一个参数和空函数体的函数相当于7-8次局部变量自增操作$localvar++ ,一个相似的方法调用当然就相当于15次局部变量自增操作$localvar++。

别在对象构造函数中做实际的工作,构造函数应该包含变量的初始化,但不会发生失败的操作。即构造不能返回错误。
例如

  1. class Device
  2. {
  3. function __construct($param)
  4.  
  5. {
  6.  
  7. //这里的代码应该不发生失败
  8.  
  9. }
  10.  
  11. function open()
  12.  
  13. {
  14.  
  15. //这里的代码返回失败和成功
  16.  
  17. }
  18. }


四 SQL 代码

1.SQL代码层

SQL关键词语大写(SELECT,INSERT,UPDATE,ALTER,DELETE,CREATE,TABLE,INDEX,COUNT,MAX,MIN,FROM,WHERE,AS,LEFT JOIN,RIGHT JOIN,ON,AND,ORDER BY,DESC,ASC,GROUP BY,LIMIT等等),按照逻辑分行,比如SELECT/INSERT/UPDATE/DELETE在一行,FROM在一行,LEFT JOIN …ON/RIGHT JOIN…ON在一行,WHERE在一行,ORDER BY在一行,GROUP BY在一行,LIMIT在一行。WHERE条件里面多个条件请使用括号来区分优先级。

数据表名称请使用名词单数形式,一律使用英文小写字母。如果需要对名称作描述/分类,请在名词前/后加描述/分类关键词语,使用下划线间隔。

例如:

SELECT field1 AS something, field2, field3

FROM table a, table b

WHERE (this=that) AND (this2=that2)

2.MySQL的查询性能优化原则

(1)请不要在SELECT中使用DISTINCT;

(2)尽可能不要SELECT *,而应该查询需要用到的指定几个字段;

(3)不要对两个大表进行联合,无论是内联或外联。对于需要对两个或多个表进行联合查询的情况,可以做两次或多次数据库查询;

(4)在WHERE条件中,尽可能对同类型的数据列进行比较;

(5)在WHERE条件中,尽量让有索引的数据列在比较表达始中单独出现;

(6)在WHERE条件中,根据数据列排除不合条件数据量由多到少的次序排列条件,在不能确定排除数据多少的前提下,一般来说表达式中使用=、!=、<>要优先于>、<、>=、<=,更优先于LIKE

(7)如果WHERE条件中的值是数字,那么不要使用单引号进行类型转换

(8)如果WHERE条件中使用LIKE模式匹配,不要在模式开头使用通配符%

(9)不要对WHERE条件中的非BINARY属性的CHAR/VARCHAR字段,进行大小写转换

(10)尽可能不要在SELECT中使用GROUP BY

(11)SQL中尽量使用短语法:INSERT INTO MYTABLE (FIELD1,FIELD2) VALUES (('x','y'),('p','q'));

3.SQL语句汇总

在编程中请将所有使用到的SQL语句列表归总,每个模块一个SQL记录表。每条语句进行EXPLAIN测试,并把10000次平均结果记录到SQL记录表中。

五 HTML代码

1.XHTML标准

(1)所有标签必须成对使用,input、img、br、hr等标签,可以使用 /> 的方式,例如:<br />,<input type="text" name="name" value="" />

(2)所有XHTML的标签、元素,必须使用英文小写字母(JavaScript和CSS例外)

(3)所有XHTML标签的所有元素的属性,都需要使用英文双引号("),不允许使用单引号,更不允许不使用引号

(4)对于selected,checked,请使用selected="selected",checked="checked"

(5)使用<strong>、<em>来代替<b>、<i>

(6)不允许XHTML标签的混合嵌套,例如:<b><i>abc</b></i>

(7)img标签必须指定alt元素的属性,即使是空值;a标签必须指定title元素的属性,即使是空值;

2.可视化元素分离

不允许在table、tr、td、th、div、span等标签中直接定义宽度、高度、边框、字体、字体大小、字体颜色、背景色、背景图等等可视化内容,一律使用CSS来定义

六 通用规范

1.引号

所有字符串都使用单引号('),除非包含需要转义的字符(比如\n之类)才允许使用双引号"。字符串中如果需要包含变量/数组/对象,请将字符串拆分,用点(.)连接变量/数组/对象。向函数传递字符串变量,不要加引号。对于在Here Doc里面使用的变量/数组/对象,请用大括号嵌套。

例如:

  1. /* wrong */
  2.  
  3. $str = "This is a really long string with no variables for the parser to find.";
  4.  
  5. do_stuff("$str");
  6.  
  7. $str = "This is a $var string";
  8.  
  9.  
  10.  
  11. /* right */
  12.  
  13. $str = 'This is a really long string with no variables for the parser to find.';
  14.  
  15. do_stuff($str);
  16.  
  17. $str = 'This is a ' . $var . 'string';


2.关联数组

    关联数组当中,请用单引号将key的字符串嵌套(例如:$row['id']比$row[id]快7倍),如果key是变量则不要使用引号嵌套:

  1. /* wrong */
  2.  
  3. $foo = $assoc_array[blah];
  4.  
  5. $foo = $assoc_array["$var"];
  6.  
  7.  
  8. /* right */
  9.  
  10. $foo = $assoc_array['blah'];
  11.  
  12. $foo = $assoc_array[$var];


3.注释

以明确简洁的语句书写注释,注释格式使用PHPDocument格式(参见 http://www.phpdoc.org/),即Zend Studio中自动提示的格式。

4.类型比较

对于提交/返回值,尽可能的使用===来检查类型是否匹配,这一点对于区分FALSE,NULL, '',0四种空值尤其有用(定义了的变量但未定义值,其值为NULL)。函数返回值请用TRUE和FALSE来代替1和0 。

对于比较字符串,必须使用strcmp()或者===,这样才进行类型检查。例如:var_dump('01' == 1),返回结果为true,但是var_dump('01' === 1)的结果就是false了

对于in_array()函数,请加入第三个参数,设置为true,例如: in_array('01', array('1')),将不判断类型,返回结果为true。但是如果使用in_array('01', array('1'), true),将判断类型,返回结果为false。

5.递增/递减运算符

不允许在表达式中使用递增运算符 (前加++$i,后加$i++)和递减运算符 (前减--$i,后减$i--),这些运算符只能独自一行使用。

递增/递减运算符不影响布尔值。递减 NULL 值也没有效果,但是递增 NULL 的结果是 1 。字符串变量只能递增(使用PERL的方式而非C的方式),不能递减。

例如:

  1. /* wrong */
  2.  
  3. $array[++$i] = $j;
  4.  
  5. $array[$i++] = $k;
  6.  
  7.  
  8. /* right */
  9.  
  10. $i++;
  11.  
  12. $array[$i] = $j;
  13.  
  14.  
  15. $array[$i] = $k;
  16.  
  17. $i++;


递增使用前加++$i比后加$i++快,递减使用前减--$i比后减$i--快,;

在方法里递增、递减局部变量是最快的,在函数里调用局部变量也是;

递增、递减一个全局变量比局部变量要慢两倍;

递增、递减一个对象的属性 (例如 $this->prop++) 比局部变量慢3倍;

递增、递减一个未定义的局部变量比一个预定义过的慢9-10倍;

6.三元条件运算符

三元条件运算符更适用于赋值,使得程序更为简洁。三元条件运算符不适合用作函数调用或者其它任何复杂的代码,这将会让代码变得晦涩难懂。

例如:

  1. /* Bad place to use them */
  2.  
  3. (($i < $size) && ($j > $size)) ? do_stuff($foo) : do_stuff($bar);
  4.  
  5.  
  6. /* OK place to use them */
  7.  
  8. $min = ($i < $j) ? $i : $j;



7.未初始化的变量

请不要使用未初始化的变量!对于用户在HTML中提交的输入值,需要使用isset()来检测是否已被初始化。

例如:

  1. /* Error way */
  2.  
  3. if ($_POST['forum'])
  4.  
  5. {
  6.  
  7. ...
  8.  
  9. }
  10.  
  11.  
  12. /* Right way */
  13.  
  14. if (isset($_POST['forum']))
  15.  
  16. {
  17.  
  18. ...
  19.  
  20. }


8.变量/数组是否为空的检测

判断变量和数组是否为空使用empty(),empty()会先检查是否已经初始化,因而无须同时使用isset()和empty()。不要使用count()来判断数组是否为空。

例如:

  1. /* Error way */
  2.  
  3. if (isset($_POST['forum']) && !empty($_POST['forum']))
  4.  
  5. {
  6.  
  7. ...
  8.  
  9. }
  10.  
  11.  
  12. /* Right way */
  13.  
  14. if (!empty($_POST['forum']))
  15.  
  16. {
  17.  
  18. ...
  19.  
  20. }


9.正则表达式

PHP支持两种风格的正则表达式:Perl-Compatible (preg) (http://www.php.net/manual/en/ref.pcre.php) 和 POSIX Extended (ereg) (http://www.php.net/manual/en/ref.regex.php)。preg风格相对于ereg风格来说更为安全,速度更快。因此,请不要使用ereg风格的正则表达式。

    在使用正则表达式的时候,首选的匹配词语定界符是斜线/,如果您的匹配词语中含有斜线,那么您可以使用#作为匹配词语定界符。

例如:

  1. /* Error way */
  2.  
  3. if (ereg('something',$myvar))
  4.  
  5. {
  6.  
  7. ...
  8.  
  9. }
  10.  
  11.  
  12. /* Right way */
  13.  
  14. if (preg_match('/something/',$myvar))
  15.  
  16. {
  17.  
  18. ...
  19.  
  20. }
  21.  
  22.  
  23. /* Alternative */
  24.  
  25. if (preg_match('#/etc/php.ini#',$myvar))
  26.  
  27. {
  28.  
  29. ...
  30.  
  31. }


正则表达式最好使用单引号, "\w"是无效转义,应该写成'\w'或 "\\w"。

尽可能使用strncasecmp()、strpbrk()、stripos() 等str系列字符串函数而不是正则表达式。另外同样是str系列函数,性能也有差异:str_replace()比preg_replace()快,但strtr()比str_replace()还要快4倍 。

如果只是需要做字符串的格式类型检查,可以直接使用ctype函数库,无需使用正则或者字符串匹配。

10.使用file_get_contents/file_put_contents

PHP4.3.0以上版本提供了file_get_contents()函数,用这个函数读取文件内容为一个字符串,其速度是使用fopen()/file()的三十倍。我们要求所有读取文件内容的程序,除非必须确保不允许被服务器cache,否则一律使用file_get_contents()函数。

通过fopen()打开、flock()锁定、fwrite()写入、fclose()关闭,这四个函数组合实现对文件的写操作,如果在Daemon/Server中的请不要使用这种方式,一旦文件被其它进程删除,则数据永远无法写入(因为每次写入前不检查文件是否存在)。PHP5.0以上版本提供了file_put_contents()函数,该函数支持FILE_APPEND和LOCK_EX等Flag,可以安全的写入文件。

11.Global/Request/Session/Server 变量

不要在函数内部中直接使用全局变量$GLOBALS['variable'],而应该先在函数开头先声明global $VAR,然后直接使用$VAR即可。只是定义一个全局变量但不使用它也会导致执行变慢,大概相当于自增一次局部变量,PHP可能做了一次全局变量是否存在的检查。

尽可能直接使用$_POST、$_GET、$_COOKIE,不要直接使用$_REQUEST,除非同时允许用户使用POST方式和GET方式提交数据。我们禁止了register_globals,所以请不要试图使用$variable_name方式获得用户提交的数据。

不要使用PHP的session功能,也不允许使用$_SESSION数组。

 

禁用$_SERVER['PHP_SELF'],这个值和用户输入URL相关,当请求路径为: /index.php/asdf/, $_SERVER['PHP_SELF']就变成/index.php/asdf/

12.输出header()

对于需要输出的header(),必须将每条header写一行,不要将多个header放在同一行内,出于安全因素考虑PHP早已不再支持这种组合header输出。

例如:

  1. header('Cache-Control: no-cache, must-revalidate, max-age=0');
  2.  
  3. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
  4.  
  5. header('Pragma: no-cache');


注意:如果print/echo输出HTML会被Apache加上缓存头,如果不希望被缓存,则需要加上上面的输出无缓存头代码来避免。

13.上传文件类型

请不要使用PHP的$_FILES中的type来判定文件的类型,此类型由浏览器提供,容易被黑客伪造。请使用getimagesize()函数来进行判定:

  1. $info = getimagesize($file);
  2. $width = $info[0];
  3. $height = $info[1];
  4. $type = $info[2];
  5. $imgstr = $info[3];
  6. $mime = $info['mime'];


其中$type,1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM

14.字符串的大小写转换

请不要使用PHP的strtolower()函数来进行字符串的大小写转换,这在安装非中文系统的服务器下会导致将汉字转换为乱码。请使用strtr($string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') 来进行大小写转换。

15.检查字符串长度

    在PHP底层zval结构体里保存了字符串长度,strlen()可以直接获取而无需计算,但仍旧有一次函数调用,速度上使用 isset() 语法结构会更快。

例如:

if (strlen($foo) < 5) { echo 'Foo is too short'; }

vs.

if (!isset($foo{5})) { echo 'Foo is too short'; }

 

使用isset($foo{5})比strlen($foo)<5更快

16.PHP标签

请不要在程序里面嵌套任何PHP标签(以免多次调用PHP解析器),不允许使用<? echo($variable);?>这种形式进行内容输出。

17.程序文件末尾

如果PHP文件在文件末尾没有使用 ?> 将导致向浏览器发送空白,进而黑客可以使用脚本来试图设置cookie或者发送http头。为防止这种情况,我们要求在每个PHP文件的末尾,使用一行注释,然后接一个新行:

// end of script

18.magic_quotes_gpc

服务器php.ini必须关闭此项设置,同时需要在代码中加入:

  1. set_magic_quotes_runtime(0);
  2.  
  3. if (get_magic_quotes_gpc())
  4.  
  5. {
  6.  
  7. exit('Please set magic_quotes_gpc off');
  8.  
  9. }


19.包含文件

对于include()/requrie()所包含的文件请尽量使用绝对路径或者./开头的相对路径。

对于include_once()/require_once()所包含的文件必须使用绝对路径(每次调用都会打开目标文件,如果用绝对路径在PHP 5.2以上不存在这个问题)。

20.遍历数组

如果需要遍历数组,请使用foreach()循环,禁止使用for()或者while()。

尽量避免在循环内部修改数组key的值(会导致写时复制)

21.避免修改for循环内的条件值

避免重新计算for循环内的条件值(比如count()/strlen()/sizeof()等),因为PHP的解析器不能够删除循环不变量。请在循环前就设定循环的条件值,而不是在循环内。

 

  1. /* Error way */
  2.  
  3. for ($i=0; $i < count($array); $i++)
  4.  
  5. {
  6.  
  7. ...
  8.  
  9. }
  10.  
  11.  
  12. /* Right way */
  13.  
  14. $total = count($array);
  15.  
  16. for ($i=0; $i < $total; $i++)
  17.  
  18. {
  19.  
  20. ...
  21.  
  22. }



22.用常量代替函数

如果存在和函数等价的常量,则不要使用函数。

php_uname('s') == PHP_OS;

php_version() == PHP_VERSION;

php_sapi_name() == PHP_SAPI;

23.不信任intval()

所有通过表单提交的值,包括$_GET、$_POST、$_REQUEST,其中的数字都是字符串类型,需要使用函数来判断提交值是否合法并进行过滤,通常使用的是intval()函数。

函数intval()会对数字开头的字符串截取开头的数字,并且不区分16进制数字,因此无法通过intval($a)来判断$a一定是整数。

正确的判断方法:

if (isset($a) && $a == intval($a))

{

       $a == intval($a);

}

24.目录权限

创建、修改目录,需要设置正确的权限,必须先使用umask(0000),然后再mkdir()或chmod(),例如:

  1. if (!is_dir($dir))
  2.  
  3. {
  4.  
  5. umask(0000);
  6.  
  7. mkdir($dir, 0777);
  8.  
  9. }
  10.  
  11.  
  12. if (!is_writeable($dir))
  13.  
  14. {
  15.  
  16. umask(0000);
  17.  
  18. chmod($dir, 0777);
  19.  
  20. }



25.临时文件

请使用tmpfile()、tempnam()来创建临时文件。

26. 静态方法和静态调用

    如果类的某个方法是静态的,那就用static显式定义成静态方法,这样可以快4倍。

如果类的成员并非静态static,则在类的外部静态调用类的成员不要使用静态方法,静态方法只能调用类的静态成员。

  1. class Foo
  2.  
  3. {
  4.  
  5. function bar()
  6.  
  7. {
  8.  
  9. echo 'foobar';
  10.  
  11. }
  12.  
  13. }
  14.  
  15.  
  16. $foo = new Foo;
  17.  
  18.  
  19. /* Right way */
  20.  
  21. $foo->far();
  22.  
  23.  
  24. /* Error way */
  25.  
  26. Foo::bar();


27.时间问题

WEB服务器下运行的业务代码如果只是取当前时间,请不要使用time(),使用$_SERVER['REQUEST_TIME'] (PHP 5.1以上版本下),这里要注意非WEB服务器中是没有$_SERVER['REQUEST_TIME']变量的。

请在程序中指定时区 date_default_timezone_set('Asia/Shanghai')。

如果需要取微秒,请使用microtime(TRUE),返回浮点数。

28、注释

   单行注释用//多行注释用/* */组合。推荐使用//注释(因为/* */不允许嵌套使用,而//可以)。

    文件修改的注释:如果文件修改了在文件的说明后面加上这些东西

       ///////////////////////////////////////////////////////////////////////

       // 修改日期:        :2011/10/1

       // 修改人:          :(by 作者)

      // 版本号:            :1.0.02

       // 修改目的            :

       /*

              说明目的(例如:添加几个新的方法)

       */

///////////////////////////////////////////////////////////////////////

       最后在修改的地方标上其实修改和结束修改的标志。格式为:

       //modify start + 版本号(by 作者)

              …(源代码)

       //modify end + 版本号(by 作者)

   关于引入语句的注释:

//数据库类操作

requireonce(“./class/Db.php”);

   要注意的几点:

a): 推荐使用requireonce

b): 所有的requireonce都放在最前面。文件信息之后。

   参考源代码范例

  1. ////////////////////////////////////////////////////
  2.  
  3. //文件名称: CPoint.php
  4.  
  5. //创建日期: 2007/02/01
  6.  
  7. //功能说明: 关于点的操作的类
  8.  
  9. //作 者: (by 作者)
  10.  
  11. //版本号: 1.0.0.1
  12.  
  13. ////////////////////////////////////////////////////
  14.  
  15.  
  16. ////////////////////////////////////////////////////
  17.  
  18. // 修改日期: :2007/03/01
  19.  
  20. // 修改人: :(by 作者)
  21.  
  22. // 版本号: :1.0.02
  23.  
  24. // 修改目的
  25.  
  26. /*
  27.  
  28. 添加了PrintPoint方法
  29.  
  30. */
  31.  
  32. ////////////////////////////////////////////////////
  33.  
  34.  
  35. // 版本号 + modify start (by 作者)
  36.  
  37.  
  38. // 版本号 + modify end(by 作者)
  39.  
  40.  
  41.  
  42. requireonce("./math.php");
  43.  
  44.  
  45. namespace Math
  46.  
  47. {
  48.  
  49. class CPoint extends CObject
  50.  
  51. {
  52.  
  53. //构造函数 (最好把构造函数和析构函数放在最前面
  54.  
  55. public function _constructor($nx, $ny)
  56.  
  57. {
  58.  
  59. $x = $nx;
  60.  
  61. $y = $ny;
  62.  
  63. }
  64.  
  65.  
  66. //析构函数
  67.  
  68. public function _destructor()
  69.  
  70. {
  71.  
  72. }
  73.  
  74.  
  75. //1.0.0.2 modefy start(by andylin)
  76.  
  77. ///////////////////////////////////////////////////////////////////////
  78.  
  79. // 函数名 : PrintPoint
  80.  
  81. // 功能描述 : 打印Point的x,y
  82.  
  83. // 参数 : 如果n == 1 print x 如果 n == 2 print y 否则print x, y
  84.  
  85. // 返回值 : 无
  86.  
  87. ///////////////////////////////////////////////////////////////////////
  88.  
  89.  
  90. //类似上面的声明,如果函数复杂应该要写,否者可以不写。比如下面的几个函数很简单就可以不写
  91.  
  92. public function PrintPoint($n)
  93.  
  94. {
  95.  
  96. if ($n == 1)
  97.  
  98. {
  99.  
  100. echo "x = ", x;
  101.  
  102. }
  103.  
  104. else if ($n == 2)
  105.  
  106. {
  107.  
  108. echo "y = ", y;
  109.  
  110. }
  111.  
  112. else
  113.  
  114. {
  115.  
  116. echo "x = ", x;
  117.  
  118. echo "y = ", y;
  119.  
  120. }
  121.  
  122. }
  123.  
  124. //1.0.0.2 modefy end(by andylin)
  125.  
  126.  
  127. public function SetX($nx)
  128.  
  129. {
  130.  
  131. $this->x = $nx;
  132.  
  133. }
  134.  
  135.  
  136. public function SetY($ny)
  137.  
  138. {
  139.  
  140. $this->y = $ny;
  141.  
  142. }
  143.  
  144.  
  145. public function GetX()
  146.  
  147. {
  148.  
  149. return $this->x;
  150.  
  151. }
  152.  
  153.  
  154. public function GetY()
  155.  
  156. {
  157.  
  158. return $this->y;
  159.  
  160. }
  161.  
  162.  
  163. //Data Session
  164.  
  165. private $x = 0; //特殊的如i, j, k, x, y, n之类的可以不按命名规则。
  166.  
  167. private $y = 0 //否者,应当遵循。
  168.  
  169. };
  170.  
  171. };


文档下载:PHP代码规范.doc

目录
相关文章
|
2月前
|
JSON JavaScript PHP
PHP把unicode编码的json字符串转中文
PHP把unicode编码的json字符串转中文
14 0
|
10月前
|
定位技术 PHP 数据格式
php通过地址获得百度地图经纬度(逆地理编码)
php通过地址获得百度地图经纬度(逆地理编码)
61 0
|
10月前
|
JavaScript PHP 数据安全/隐私保护
解决php中字符串输出一样但比较不相等(编码不同导致长度不一样)
解决php中字符串输出一样但比较不相等(编码不同导致长度不一样)
109 0
|
12月前
|
PHP 数据安全/隐私保护
php base64不能解码_PHP base64编码后解码乱码的解决办法
php base64不能解码_PHP base64编码后解码乱码的解决办法
353 0
|
JSON PHP 数据库
PHP:Laravel cast array json数据存数据库时unicode 编码问题和update更新不触发数据转换
PHP:Laravel cast array json数据存数据库时unicode 编码问题和update更新不触发数据转换
108 0
|
XML 存储 安全
php安全编码规范
php安全编码规范
|
网络协议 编译器 PHP
php中的进制和编码
字符串在线转2进制 工具 由于计算机是MG发明的,一开始的映射表是ASSIC码,用一个字节(8位)表示一个符号或者字母 比如小写字母a对应的是97 相应的2进制为01100001 8个位的2进制最大值是11111111 所以当它不够用之后,就出现了双字节字符集
117 0
php中的进制和编码
|
应用服务中间件 PHP nginx
php实现img转ASCII编码图片
php实现img转ASCII编码图片
90 0
php实现img转ASCII编码图片