一些PHP Coding Tips(php小技巧)[2011/04/02最后更新]


Posted in PHP onMay 02, 2011

最后更新: 2011/04/02

1. 使用list来实现一次获取explode后的特定段值:
list( , $mid) = explode(';', $string);
2. 使用NULL === 来代替is_null:
is_null和 NULL === 完全是一样的效果, 但是却节省了一次函数调用.

3. 使用===尽量不用==:
PHP有俩组相等比较运算符===/!==和==/!=, ==/!=会有隐式类型转换,而===/!==会严格比较俩个操作时是否类型相同并且值相等.
我们应该尽量使用===而不是==, 除了因为转换规则比较难记以外, 还有一点就是如果使用===, 对于日后的维护或者阅读你代码的人也会很舒服:”在这个时刻, 这一行语句, 这个变量就是这个类型的!”.

4. 少用/不用 continue:
continue是回到循环的头部, 而循环结束本来就是回到循环的头部, 所以通过适当的构造, 我们完全可以避免使用这条语句, 使得效率得到改善.

5. 警惕switch/in_array等的松比较(loose comparision):
switch和in_array都是采用松比较, 所以在要比较的变量之间类型不一样的时候, 很容易出错:

switch ($name) { 
case "laruence": 
... 
break; 
case "eve": 
... 
break; 
}

对于上面的switch, 如果$name是数字0, 那么它会满足任何一条case. 同理在in_array中也是.
解决的办法就是, 在switch之前, 把变量类型转换成你所期望的类型.
switch (strval($name)) { 
case "laruence": 
... 
break; 
case "eve": 
... 
break; 
}

而, in_array提供了第三个可选的参数, 通过这个参数可以改变默认的比较方式.
6. switch不仅仅只用来判别变量:
比如, 对于如下的一段代码:
if($a) { 
} else if ($b) { 
} else if ($c || $d) { 
}

可以简单的改写为:
switch (TRUE) { 
case $a: 
break; 
case $b: 
break; 
case $c: 
case $d: 
break; 
}

是不是看起来更清晰呢?
7. 变量先定义后使用:
使用一个未定义的变量, 比使用一个定义好的变量要慢8倍以上!
可以相像, PHP引擎会首先按照正常的逻辑来获取这个变量, 然而这个变量不存在, 所以PHP引擎需要抛出一个NOTICE, 并且进入一段使用未定义变量时应该走的逻辑, 然后返回一个新的变量.
另外, 阅读代码的角度讲, 当你使用一个未定义的变量时, 会让阅读你代码的人困惑:”这个变量在那里初始化的, 和之前的代码有关系么? 和include进来的文件有关系么?”
最后, 从规范编程的角度来讲, 你也需要这样做.
8. 不用第三变量交换俩个变量的值:
list($a, $b) = array($b, $a),
但其实还是有匿名临时变量的产生, 对于整数来说, 采用互逆的运算来做, 还是比较靠谱:
$a = $a + $b; 
$b = $a - $b; 
$a = $a - $b;

不过, 还是用异或比较好, 因为+ ? * /容易产生精度丢失或者溢出.
9. floor == 俩次非运算(此条由skiyo提供)
echo ~~4.9; 
echo floor(4.9);

用俩次非运算的速度基本上是floor的3倍, 不过有一点, 对于大数来说, 可能会发生溢出:
echo ~~99999999999999.99; //276447231 
echo floor(99999999999999.99); //99999999999999

10. do{}while(0)妙用(此条由Qianfeng提供)
我们知道do{}while(0)在c/c++中, 有很多妙用, 比如消除goto, 宏定义代码块.
所以, PHP中同理, 也可以用do{}while(0)来做一些巧妙的应用
do{ 
if(true) { 
break; 
} 
if(true) { 
break; 
} 
} while(false); 
//好过 
if(true) { 
} else if(true) { 
} else { 
}

11. 尽量少用@错误抑制符
如下代码:
@func();

就相当于(参见深入理解PHP原理之错误抑制与内嵌HTML):
$report = error_reporting(0); 
func(); 
error_reporting($report);

另外错误抑制符号, 可能会造成一些问题, 参看(https://3water.com/article/27022.htm);
最后,错误抑制符在发生错误调试的时候也可能会带来麻烦.
12. 尽量避免使用递归(此条来自lazyboy)
递归性能堪忧, 而大部分的递归都是尾递归, 都是可以消除的.
function f($n) { 
if ($n = 0) return 1; 
return $n * f($n - 1); 
} 
//变为: 
$result = 1; 
for ($y = 1; $y < $n + 1; $y++ ) { 
$result *= $y; 
}

13. 使用$_SERVER['REQUEST_TIME']代替time()
time()会引来一次函数调用, 而如果对时间的精确值要求不高, 可以使用$_SERVER['REQUEST_TIME']代替, 快很多.
14. 避免在for判断条件中做运算(此条来自留言的Anonymous)
如下的代码:
for($i=0; $i<strlen($str); $i++) {
}
会导致每次循环都调用strlen, 改为
for ($i=0, $j=strlen($str); $i<$j; $i++) {
}
15. 尽量避免使用正则(此条来自pangyontao)
正则耗时, 尽量避免, 而采用直接的字符串处理函数代替, 如:
if (preg_match("!^foo_!i", "FoO_")) { } 
// 替换为: 
if (!strncasecmp("foo_", "FoO_", 4)) { } 
if (preg_match("![a8f9]!", "sometext")) { } 
// 替换为: 
if (strpbrk("a8f9", "sometext")) { } 
if (preg_match("!string!i", "text")) {} 
// 替换为: 
if (stripos("text", "string") !== false) {}

等等.
16. 用大括号括起在双引号和heredoc中的变量
如下的代码:
echo "$name[2]";
PHP不知道程序员的意图是$name . “[2]“还是$name[2],
所以建议, 都加上大括号:
echo "{$name}[2]"; 
//或者 
echo "${name}[2]";

17. 用FALSE表示错误, 用NULL表示不存在.
对于操作类的函数, 失败返回FALSE, 表示”操作失败了”, 而对于查询类的函数, 如果找不到想要的值, 则应该返回NULL, 表示”找不到”.
PHP 相关文章推荐
php5 pdo新改动加载注意事项
Sep 11 PHP
php 无限级 SelectTree 类
May 19 PHP
php 分页函数multi() discuz
Jun 21 PHP
php 用checkbox一次性删除多条记录的方法
Feb 23 PHP
phpadmin如何导入导出大数据文件及php.ini参数修改
Feb 18 PHP
php生成静态页面的简单示例
Apr 17 PHP
PHP不用递归实现无限分级的例子分享
Apr 18 PHP
PHP实现简单实用的验证码类
Jul 29 PHP
PHP封装的MSSql操作类完整实例
May 26 PHP
浅谈PHP中的数据传输CURL
Sep 06 PHP
PHP实现微信提现功能
Sep 30 PHP
解决在Laravel 中处理OPTIONS请求的问题
Oct 11 PHP
PHP中使用gettext来支持多语言的方法
May 02 #PHP
php中神奇的fastcgi_finish_request
May 02 #PHP
PHP开发不能违背的安全规则 过滤用户输入
May 01 #PHP
PHP 调试工具Debug Tools
Apr 30 #PHP
php debug 安装技巧
Apr 30 #PHP
vs中通过剪切板循环来循环粘贴不同内容
Apr 30 #PHP
php获取mysql数据库中的所有表名的代码
Apr 23 #PHP
You might like
php adodb分页实现代码
2009/03/19 PHP
php 静态化实现代码
2009/03/20 PHP
跟我学Laravel之配置Laravel
2014/10/15 PHP
如何用PHP来实现一个动态Web服务器
2015/07/29 PHP
php在数据库抽象层简单使用PDO的方法
2015/11/03 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
javascript动态添加表格数据行(ASP后台数据库保存例子)
2010/05/08 Javascript
让复选框只能选择一项的方法
2013/10/08 Javascript
JS删除字符串中重复字符方法
2014/03/09 Javascript
javascript实现label标签跳出循环操作
2016/03/06 Javascript
JavaScript:Date类型全面解析
2016/05/19 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
2016/06/23 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
JS获取字符对应的ASCII码实例
2017/09/10 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
2017/10/16 Javascript
详解如何用模块化的方式写vuejs
2017/12/16 Javascript
vue实现压缩图片预览并上传功能(promise封装)
2019/01/10 Javascript
使用Python实现下载网易云音乐的高清MV
2015/03/16 Python
python实现的用于搜索文件并进行内容替换的类实例
2015/06/28 Python
Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
2015/08/16 Python
Django中间件基础用法详解
2019/07/18 Python
检测tensorflow是否使用gpu进行计算的方式
2020/02/03 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
Python startswith()和endswith() 方法原理解析
2020/04/28 Python
css3中background新增的4个新的相关属性用法介绍
2013/09/26 HTML / CSS
HTML5 Canvas画线技巧——实现绘制一个像素宽的细线
2013/08/02 HTML / CSS
墨西哥购物网站:Elektra
2020/01/21 全球购物
精细化工应届生求职信
2013/11/17 职场文书
事业单位接收函
2014/01/10 职场文书
学校评语大全
2014/05/06 职场文书
2014年班级工作总结范文
2014/12/23 职场文书
幼儿园父亲节活动总结
2015/02/12 职场文书
勤俭节约主题班会
2015/08/13 职场文书
小学生作文之《压岁钱的烦恼》
2019/09/27 职场文书
CSS3实现三角形不断放大效果
2021/04/13 HTML / CSS