- 本文地址: https://www.laruence.com/2011/03/24/858.html
- 转载请注明出处
以下是一些PHP Coding Tips. 当然, 这些Tips并不一定仅仅局限于PHP.
大家有什么好的心得, 欢迎直接回复本文与更多的人分享.. 谢谢
本文长期更新, 请关注PHP Coding Tips
最后更新: 2011/04/02
list( , $mid) = explode(';', $string);
is_null和 NULL === 完全是一样的效果, 但是却节省了一次函数调用.
PHP有俩组相等比较运算符===/!==和==/!=, ==/!=会有隐式类型转换,而===/!==会严格比较俩个操作时是否类型相同并且值相等.
我们应该尽量使用===而不是==, 除了因为转换规则比较难记以外, 还有一点就是如果使用===, 对于日后的维护或者阅读你代码的人也会很舒服:"在这个时刻, 这一行语句, 这个变量就是这个类型的!".
continue是回到循环的头部, 而循环结束本来就是回到循环的头部, 所以通过适当的构造, 我们完全可以避免使用这条语句, 使得效率得到改善.
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提供了第三个可选的参数, 通过这个参数可以改变默认的比较方式.
比如, 对于如下的一段代码:
if($a) { } else if ($b) { } else if ($c || $d) { }
可以简单的改写为:
switch (TRUE) { case $a: break; case $b: break; case $c: case $d: break; }
是不是看起来更清晰呢?
使用一个未定义的变量, 比使用一个定义好的变量要慢8倍以上!
可以相像, PHP引擎会首先按照正常的逻辑来获取这个变量, 然而这个变量不存在, 所以PHP引擎需要抛出一个NOTICE, 并且进入一段使用未定义变量时应该走的逻辑, 然后返回一个新的变量.
另外, 阅读代码的角度讲, 当你使用一个未定义的变量时, 会让阅读你代码的人困惑:"这个变量在那里初始化的, 和之前的代码有关系么? 和include进来的文件有关系么?"
最后, 从规范编程的角度来讲, 你也需要这样做.
list($a, $b) = array($b, $a),
但其实还是有匿名临时变量的产生, 对于整数来说, 采用互逆的运算来做, 还是比较靠谱:
$a = $a + $b; $b = $a - $b; $a = $a - $b;
不过, 还是用异或比较好, 因为+ - * /容易产生精度丢失或者溢出.
echo ~~4.9; echo floor(4.9);
用俩次非运算的速度基本上是floor的3倍, 不过有一点, 对于大数来说, 可能会发生溢出:
echo ~~99999999999999.99; //276447231 echo floor(99999999999999.99); //99999999999999
我们知道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 { }
如下代码:
@func();
就相当于(参见深入理解PHP原理之错误抑制与内嵌HTML):
$report = error_reporting(0); func(); error_reporting($report);
另外错误抑制符号, 可能会造成一些问题, 参看(PHP错误抑制符(@)导致引用传参失败的Bug);
最后,错误抑制符在发生错误调试的时候也可能会带来麻烦.
递归性能堪忧, 而大部分的递归都是尾递归, 都是可以消除的.
function f($n) { if ($n = 0) return 1; return $n * f($n - 1); } //变为: $result = 1; for ($y = 1; $y < $n + 1; $y++ ) { $result *= $y; }
time()会引来一次函数调用, 而如果对时间的精确值要求不高, 可以使用$_SERVER['REQUEST_TIME']代替, 快很多.
如下的代码:
for($i=0; $i<strlen($str); $i++) { }
会导致每次循环都调用strlen, 改为
for ($i=0, $j=strlen($str); $i<$j; $i++) { }
正则耗时, 尽量避免, 而采用直接的字符串处理函数代替, 如:
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) {}
等等.
如下的代码:
echo "$name[2]";
PHP不知道程序员的意图是$name . "[2]"还是$name[2],
所以建议, 都加上大括号:
echo "{$name}[2]"; //或者 echo "${name}[2]";
对于操作类的函数, 失败返回FALSE, 表示"操作失败了", 而对于查询类的函数, 如果找不到想要的值, 则应该返回NULL, 表示"找不到".
betflix vip BETFLIX THAILAND เว็บพนันออนไลน์ มาพร้อมโบนัสสล็อตแตกง่าย
Online football betting, single ball betting, Teng ball ball step
Thank you for making me realize this. It’s great.
You are very good at that.
I’m amazed, I must say. Rarely do I come across a blog that’s both equally educative and entertaining, and
without a doubt, you have hit the nail on the head.
The issue is something that not enough men and women are speaking intelligently about.
Now i’m very happy I came across this in my search for something regarding this.
有一些是不可取的,几乎可以忽略的细微效率提高导致代码可读性的大幅下降;
用异或交换变量当两个变量类型不一致会产生问题;
I visit each day some blogs and sites to read posts, except this blog
presents quality based articles.
[…] (http://www.laruence.com/2011/03/24/858.html) 使用一个未定义的变量, […]
[…] php正则效率:回溯 php性能 […]
[…] 加速PHP的ECHO […]
if (strpbrk(“a8f9”, “sometext”)) { }
参数写反了吧?
写代码要精益求精。
[…] 原载: 风雪之隅->一些PHP Coding Tips […]
[…] 本文地址: http://www.laruence.com/2011/03/24/858.html […]
[…] Coding Tips: http://www.laruence.com/2011/03/24/858.html 关于博主 Nia, 窝窝团, php研发工程师 […]
[…] 本文长期更新, 请关注PHP Coding Tips […]
if($a === “condition”){
return true;
} else {
return false;
}
改为:
return $a === “condition”;
我是来顶鸟哥的~~~很受用,收了~~
请教了
对于“使用一个未定义的变量, 比使用一个定义好的变量要慢8倍以上!” 很震惊,但没有明白这里的定义变量的意思。
php有定义变量的方式?
直接在代码前写上?
$var;
或者通过默认赋值来定义?
$var = ”;
学习了,好东西,多谢博主分享。
[…] 本文地址: http://www.laruence.com/2011/03/24/858.html […]
[…] 本文地址: http://www.laruence.com/2011/03/24/858.html […]
经典,学习了!
[…] http://www.laruence.com/2011/03/24/858.html 里面也有一些不错的tips,当然两者之间会有一些重复,不要介意,因为多次重复的说明很多人都觉得比较重要。 冬天的萝卜php ← 新用户的随想 /* */ […]
第一条中的规律适合只适合5.2,我在我5.3的机器上反而是普通的要更快一些,不过在5.2版本的机器上,list更快一些。
我不建议将这条作为标准~~~~
如果是一个获取数组的函数,如果获取的内容为空,最好返回空数组,这样在外层不需要做额外的判断
$ret = array();
if ($from_db) {
$ret = get_list($from_db);
}
return $ret;
要比
if ($from_db) {
$ret = get_list($from_db);
}
return $ret;
要好很多
学习了
17. 用FALSE表示错误, 用NULL表示不存在.
对于操作类的函数, 失败返回FALSE, 表示”操作失败了”, 而对于查询类的函数, 如果找不到想要的值, 则应该返回NULL, 表示”找不到”.
学习,很多不了解的。
果断收藏
@horseluke 哦? 我还真没注意, 回去看看
@pangyongtao 对于Apache2handler, 可以简单调用:getallheaders, 另外, 也不应该使用preg_match, 使用strncmp代替
php中获取全部的header(来自 chengen)
foreach( $_SERVER as $k=>$v ){
if( preg_match(“#HTTP_(.+)#”,$k,$hp) ){
array_push( $headers, “$k:$v”);
}
}
@雪候鸟 ,刚才测试了一下,发现在php 5.3中,phpinfo中的env部分和$_ENV已经完全隔离开来,具体表现有:
1、初始化的$_ENV已经成为了一个空数组
2、无论是否处在safe mode下,putenv都已经不能修改phpinfo中的env。
看来可能就是怕出现你所说的问题了~
@小蔡 多谢, 已更正
呵呵,“使用$_SERVER[‘REQUEST_TIME’]代替tiem()”,有点小误,time写错了
@horseluke @pangyongtao 如果不小心phpinfo被人看了,,,就Over了.
再@pangyongtao,测试了一下,发现仅对putenv/getenv有影响。收回刚才说的话~
@pangyongtao ,在我的印象中,有点服务器在安全模式下是会变态到不允许更改$_ENV值(受php.ini的safe_mode_protected_env_vars, safe_mode_allowed_env_vars影响)。
当然真遇到那就自认倒霉了~
[…] 本文长期更新, 请关注PHP Coding Tips […]
鸟哥v5~ 好文章收藏:)
@lazyboy 第四条不行,,,js才可以,呵呵, PHP中逻辑运算返回的是boolean值, 所以$d最后的结果只能是TRUE和FALSE
我也来贡献几条:
1. 尽量减少@来抑制错误,而是用try/catch
例如 @mysql_contect();
改成
try{
mysql_contect();
} catch(Execption $e) {
// 说不定那天你就想看看这里错误的原因
}
2. 能用[]这个的时候,就别用array_push
array_push($arr, ‘aaa’);
改成
$arr[] = ‘aaa’;
3. 能用循环实现的方式,就别用递归了
4. 运算表达式的妙用
if($a || $b) {
if($a) {
$d = $a;
} else {
$d = $b;
}
} else {
$d = $c;
}
$d = $a || $b || $c;
长期关注,希望风雪牛坚持更新
我也贡献几条吧。。
使用for循环的时候用
for ($i=count($res);$i>=0;$i–) {
do_sth($res[i]);
}
好过
for ($i=0;$i<count($res);$i++) {
do_sth($res[i]);
}
查看自己的脚本用了多少内存
memory_get_usage()
单位是字节
写脚本的时候记得unset对象或者大数组
不知道哪里用了内存,就用上面的方法跟踪
查看自己的脚本执行了多久了
time()-$_SERVER['REQUEST_TIME']
精度是秒。。
那个~~代替floor的方法不好,会带来可读性的问题。
除非追求的是片面的短,那么用9.99|0也可以实现,不过我还是觉得追求速度的用(int)9.99当floor比较靠谱。。
该死的验证码,超时了,害我白写了。再加个tips: 发帖之前先刷新验证码
do
{
if(true)
{
break;
}
if(true)
{
break;
}
//@TODO:do some thing
}while(false);
好过
if(true)
{
}
else if(true)
{
}
else
{
}
你懂的..
1、可以使用下标访问字符串 $neighbor = ‘Hilda’; print $neighbor[3];
d
2、Heredoc有用的很 print <<< HTML
There are $remaining_cards left.
$text
HTML;
3、字符串替换 $credit_card = ‘4111 1111 1111 1111’;
Print ubstr_replace($credit_card,’xxxx ‘,0,strlen($credit_card)-4);
xxxx 1111
4、遍历字符串中的每个字符 for ($i = 0, $j = strlen($string); $i here am I
6、你懂的 ltrim(’10 PRINT A$’,’ 0..9′);
7、正则切 split(‘ +’,’This sentence has some extra whitespace in it.’);
8、$newtext = wordwrap($text, 20, “\n”);
The quick brown fox
jumped over the lazy
dog.
9、判断2个浮点数是否相同 $delta = 0.00001;
$a = 1.00000001;
$b = 1.00000000;
if (abs($a – $b) array(‘Red’, ‘White’, ‘Blue’),
‘cities’ => array(‘Boston’, ‘New York’, ‘Chicago’));
array_multisort($stuff[‘colors’], $stuff[‘cities’]);
18、交换变量 list($a,$b,$c) = array($c,$b,$a);
19、共享内存 sem_get sem_acquire shm_attach shm_get_var shm_put_var
shm_detach sem_release
20、唯一id $unique_id = uniqid(microtime(),1);
21、Transforming XML with XSLT xslt_create xslt_process xslt_free
22、用环境变量存密码 mysql_connect(‘localhost’,$_ENV[‘MYSQL_USER’],$_ENV[‘MYSQL_PASSWORD’]);
23、把信息隐藏在页面上,而不是原样展示 base64_encode(serialize($personal_data));
24、PHP’s mcrypt extension
25、SSL是否使用 if (‘on’ == $_SERVER[‘HTTPS’])
有些经验,但是比较肤浅,还是等待各位前辈的经验吧。
@cyberty tips~
“不用第三变量交换俩个变量的值”
请问, 这个是有效率问题么?
好东西,收藏,期待更多好文.
学习了,表示会长期关注。
强人,希望学到更多PHP知识!
长期关注本文,只盼更新频率快