一些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 相关文章推荐
PHP判断远程url是否有效的几种方法小结
Oct 08 PHP
php不使用copy()函数复制文件的方法
Mar 13 PHP
js代码实现微博导航栏
Jul 30 PHP
PHP计算当前坐标3公里内4个角落的最大最小经纬度实例
Feb 26 PHP
Zend Framework教程之动作的基类Zend_Controller_Action详解
Mar 07 PHP
YII Framework框架教程之日志用法详解
Mar 14 PHP
thinkPHP实现递归循环栏目并按照树形结构无限极输出的方法
May 19 PHP
PHP表单数据写入MySQL数据库的代码
May 31 PHP
浅谈PHP链表数据结构(单链表)
Jun 08 PHP
laravel dingo API返回自定义错误信息的实例
Sep 29 PHP
Laravel5.1 框架表单验证操作实例详解
Jan 07 PHP
浅谈PHP之ThinkPHP框架使用详解
Jul 21 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
一个简单计数器的源代码
2006/10/09 PHP
php中flush()、ob_flush()、ob_end_flush()的区别介绍
2013/02/17 PHP
ThinkPHP中Session用法详解
2014/11/29 PHP
JavaScript实现删除电脑的关机键
2016/07/26 PHP
php使用curl详细解析及问题汇总
2016/08/11 PHP
PHP命令行执行整合pathinfo模拟定时任务实例
2016/08/12 PHP
thinkphp框架表单数组实现图片批量上传功能示例
2020/04/04 PHP
javascript 最常用的10个自定义函数[推荐]
2009/12/26 Javascript
各浏览器中querySelector和querySelectorAll的实现差异分析
2012/05/23 Javascript
文字溢出实现溢出的部分再放入一个新生成的div中具体代码
2013/05/17 Javascript
jquery获取iframe中的dom对象(两种方法)
2013/07/02 Javascript
js兼容火狐显示上传图片预览效果的方法
2015/05/21 Javascript
jQuery获得字体颜色16位码的方法
2016/02/20 Javascript
利用jQuery的动画函数animate实现豌豆发射效果
2016/08/28 Javascript
Javascript点击按钮随机改变数字与其颜色
2016/09/01 Javascript
JavaScript重定向URL参数的两种方法小结
2016/10/19 Javascript
AngularJS打开页面隐藏显示表达式用法示例
2016/12/25 Javascript
原生js实现放大镜
2017/02/20 Javascript
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
利用node.js如何创建子进程详解
2017/12/09 Javascript
详解VSCode配置启动Vue项目
2019/05/14 Javascript
JS实现时间校验的代码
2020/05/25 Javascript
[08:53]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS 选手采访
2021/03/11 DOTA
python获取beautifulphoto随机某图片代码实例
2013/12/18 Python
在Python中测试访问同一数据的竞争条件的方法
2015/04/23 Python
python Spyder界面无法打开的解决方法
2018/04/27 Python
Python中一些不为人知的基础技巧总结
2018/05/19 Python
numpy 返回函数的上三角矩阵实例
2019/11/25 Python
PYcharm 激活方法(推荐)
2020/03/23 Python
如何在C# winform中异步调用web services
2015/09/21 面试题
linux面试题参考答案(9)
2015/01/07 面试题
2014国庆节标语口号
2014/09/19 职场文书
民主生活会汇报材料
2014/12/15 职场文书
2015年幼儿园安全工作总结
2015/05/12 职场文书
《飘》英文读后感五篇
2019/10/11 职场文书
教你修复 Win11应用商店加载空白问题
2021/12/06 数码科技