一些PHP Coding Tips(php小技巧)[2011/04/02最后更新]
更新時(shí)間:2011年05月02日 14:00:56 作者:
以下是一些PHP Coding Tips. 當(dāng)然, 這些Tips并不一定僅僅局限于PHP.大家有什么好的心得, 歡迎直接回復(fù)本文與更多的人分享.. 謝謝
最后更新: 2011/04/02
1. 使用list來(lái)實(shí)現(xiàn)一次獲取explode后的特定段值:
list( , $mid) = explode(';', $string);
2. 使用NULL === 來(lái)代替is_null:
is_null和 NULL === 完全是一樣的效果, 但是卻節(jié)省了一次函數(shù)調(diào)用.
3. 使用===盡量不用==:
PHP有倆組相等比較運(yùn)算符===/!==和==/!=, ==/!=會(huì)有隱式類(lèi)型轉(zhuǎn)換,而===/!==會(huì)嚴(yán)格比較倆個(gè)操作時(shí)是否類(lèi)型相同并且值相等.
我們應(yīng)該盡量使用===而不是==, 除了因?yàn)檗D(zhuǎn)換規(guī)則比較難記以外, 還有一點(diǎn)就是如果使用===, 對(duì)于日后的維護(hù)或者閱讀你代碼的人也會(huì)很舒服:”在這個(gè)時(shí)刻, 這一行語(yǔ)句, 這個(gè)變量就是這個(gè)類(lèi)型的!”.
4. 少用/不用 continue:
continue是回到循環(huán)的頭部, 而循環(huán)結(jié)束本來(lái)就是回到循環(huán)的頭部, 所以通過(guò)適當(dāng)?shù)臉?gòu)造, 我們完全可以避免使用這條語(yǔ)句, 使得效率得到改善.
5. 警惕switch/in_array等的松比較(loose comparision):
switch和in_array都是采用松比較, 所以在要比較的變量之間類(lèi)型不一樣的時(shí)候, 很容易出錯(cuò):
switch ($name) {
case "laruence":
...
break;
case "eve":
...
break;
}
對(duì)于上面的switch, 如果$name是數(shù)字0, 那么它會(huì)滿(mǎn)足任何一條case. 同理在in_array中也是.
解決的辦法就是, 在switch之前, 把變量類(lèi)型轉(zhuǎn)換成你所期望的類(lèi)型.
switch (strval($name)) {
case "laruence":
...
break;
case "eve":
...
break;
}
而, in_array提供了第三個(gè)可選的參數(shù), 通過(guò)這個(gè)參數(shù)可以改變默認(rèn)的比較方式.
6. switch不僅僅只用來(lái)判別變量:
比如, 對(duì)于如下的一段代碼:
if($a) {
} else if ($b) {
} else if ($c || $d) {
}
可以簡(jiǎn)單的改寫(xiě)為:
switch (TRUE) {
case $a:
break;
case $b:
break;
case $c:
case $d:
break;
}
是不是看起來(lái)更清晰呢?
7. 變量先定義后使用:
使用一個(gè)未定義的變量, 比使用一個(gè)定義好的變量要慢8倍以上!
可以相像, PHP引擎會(huì)首先按照正常的邏輯來(lái)獲取這個(gè)變量, 然而這個(gè)變量不存在, 所以PHP引擎需要拋出一個(gè)NOTICE, 并且進(jìn)入一段使用未定義變量時(shí)應(yīng)該走的邏輯, 然后返回一個(gè)新的變量.
另外, 閱讀代碼的角度講, 當(dāng)你使用一個(gè)未定義的變量時(shí), 會(huì)讓閱讀你代碼的人困惑:”這個(gè)變量在那里初始化的, 和之前的代碼有關(guān)系么? 和include進(jìn)來(lái)的文件有關(guān)系么?”
最后, 從規(guī)范編程的角度來(lái)講, 你也需要這樣做.
8. 不用第三變量交換倆個(gè)變量的值:
list($a, $b) = array($b, $a),
但其實(shí)還是有匿名臨時(shí)變量的產(chǎn)生, 對(duì)于整數(shù)來(lái)說(shuō), 采用互逆的運(yùn)算來(lái)做, 還是比較靠譜:
$a = $a + $b;
$b = $a - $b;
$a = $a - $b;
不過(guò), 還是用異或比較好, 因?yàn)? – * /容易產(chǎn)生精度丟失或者溢出.
9. floor == 倆次非運(yùn)算(此條由skiyo提供)
echo ~~4.9;
echo floor(4.9);
用倆次非運(yùn)算的速度基本上是floor的3倍, 不過(guò)有一點(diǎn), 對(duì)于大數(shù)來(lái)說(shuō), 可能會(huì)發(fā)生溢出:
echo ~~99999999999999.99; //276447231
echo floor(99999999999999.99); //99999999999999
10. do{}while(0)妙用(此條由Qianfeng提供)
我們知道do{}while(0)在c/c++中, 有很多妙用, 比如消除goto, 宏定義代碼塊.
所以, PHP中同理, 也可以用do{}while(0)來(lái)做一些巧妙的應(yīng)用
do{
if(true) {
break;
}
if(true) {
break;
}
} while(false);
//好過(guò)
if(true) {
} else if(true) {
} else {
}
11. 盡量少用@錯(cuò)誤抑制符
如下代碼:
@func();
就相當(dāng)于(參見(jiàn)深入理解PHP原理之錯(cuò)誤抑制與內(nèi)嵌HTML):
$report = error_reporting(0);
func();
error_reporting($report);
另外錯(cuò)誤抑制符號(hào), 可能會(huì)造成一些問(wèn)題, 參看(http://chabaoo.cn/article/27022.htm);
最后,錯(cuò)誤抑制符在發(fā)生錯(cuò)誤調(diào)試的時(shí)候也可能會(huì)帶來(lái)麻煩.
12. 盡量避免使用遞歸(此條來(lái)自lazyboy)
遞歸性能堪憂(yōu), 而大部分的遞歸都是尾遞歸, 都是可以消除的.
function f($n) {
if ($n = 0) return 1;
return $n * f($n - 1);
}
//變?yōu)?
$result = 1;
for ($y = 1; $y < $n + 1; $y++ ) {
$result *= $y;
}
13. 使用$_SERVER['REQUEST_TIME']代替time()
time()會(huì)引來(lái)一次函數(shù)調(diào)用, 而如果對(duì)時(shí)間的精確值要求不高, 可以使用$_SERVER['REQUEST_TIME']代替, 快很多.
14. 避免在for判斷條件中做運(yùn)算(此條來(lái)自留言的Anonymous)
如下的代碼:
for($i=0; $i<strlen($str); $i++) {
}
會(huì)導(dǎo)致每次循環(huán)都調(diào)用strlen, 改為
for ($i=0, $j=strlen($str); $i<$j; $i++) {
}
15. 盡量避免使用正則(此條來(lái)自pangyontao)
正則耗時(shí), 盡量避免, 而采用直接的字符串處理函數(shù)代替, 如:
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. 用大括號(hào)括起在雙引號(hào)和heredoc中的變量
如下的代碼:
echo "$name[2]";
PHP不知道程序員的意圖是$name . “[2]“還是$name[2],
所以建議, 都加上大括號(hào):
echo "{$name}[2]";
//或者
echo "${name}[2]";
17. 用FALSE表示錯(cuò)誤, 用NULL表示不存在.
對(duì)于操作類(lèi)的函數(shù), 失敗返回FALSE, 表示”操作失敗了”, 而對(duì)于查詢(xún)類(lèi)的函數(shù), 如果找不到想要的值, 則應(yīng)該返回NULL, 表示”找不到”.
1. 使用list來(lái)實(shí)現(xiàn)一次獲取explode后的特定段值:
list( , $mid) = explode(';', $string);
2. 使用NULL === 來(lái)代替is_null:
is_null和 NULL === 完全是一樣的效果, 但是卻節(jié)省了一次函數(shù)調(diào)用.
3. 使用===盡量不用==:
PHP有倆組相等比較運(yùn)算符===/!==和==/!=, ==/!=會(huì)有隱式類(lèi)型轉(zhuǎn)換,而===/!==會(huì)嚴(yán)格比較倆個(gè)操作時(shí)是否類(lèi)型相同并且值相等.
我們應(yīng)該盡量使用===而不是==, 除了因?yàn)檗D(zhuǎn)換規(guī)則比較難記以外, 還有一點(diǎn)就是如果使用===, 對(duì)于日后的維護(hù)或者閱讀你代碼的人也會(huì)很舒服:”在這個(gè)時(shí)刻, 這一行語(yǔ)句, 這個(gè)變量就是這個(gè)類(lèi)型的!”.
4. 少用/不用 continue:
continue是回到循環(huán)的頭部, 而循環(huán)結(jié)束本來(lái)就是回到循環(huán)的頭部, 所以通過(guò)適當(dāng)?shù)臉?gòu)造, 我們完全可以避免使用這條語(yǔ)句, 使得效率得到改善.
5. 警惕switch/in_array等的松比較(loose comparision):
switch和in_array都是采用松比較, 所以在要比較的變量之間類(lèi)型不一樣的時(shí)候, 很容易出錯(cuò):
復(fù)制代碼 代碼如下:
switch ($name) {
case "laruence":
...
break;
case "eve":
...
break;
}
對(duì)于上面的switch, 如果$name是數(shù)字0, 那么它會(huì)滿(mǎn)足任何一條case. 同理在in_array中也是.
解決的辦法就是, 在switch之前, 把變量類(lèi)型轉(zhuǎn)換成你所期望的類(lèi)型.
復(fù)制代碼 代碼如下:
switch (strval($name)) {
case "laruence":
...
break;
case "eve":
...
break;
}
而, in_array提供了第三個(gè)可選的參數(shù), 通過(guò)這個(gè)參數(shù)可以改變默認(rèn)的比較方式.
6. switch不僅僅只用來(lái)判別變量:
比如, 對(duì)于如下的一段代碼:
復(fù)制代碼 代碼如下:
if($a) {
} else if ($b) {
} else if ($c || $d) {
}
可以簡(jiǎn)單的改寫(xiě)為:
復(fù)制代碼 代碼如下:
switch (TRUE) {
case $a:
break;
case $b:
break;
case $c:
case $d:
break;
}
是不是看起來(lái)更清晰呢?
7. 變量先定義后使用:
使用一個(gè)未定義的變量, 比使用一個(gè)定義好的變量要慢8倍以上!
可以相像, PHP引擎會(huì)首先按照正常的邏輯來(lái)獲取這個(gè)變量, 然而這個(gè)變量不存在, 所以PHP引擎需要拋出一個(gè)NOTICE, 并且進(jìn)入一段使用未定義變量時(shí)應(yīng)該走的邏輯, 然后返回一個(gè)新的變量.
另外, 閱讀代碼的角度講, 當(dāng)你使用一個(gè)未定義的變量時(shí), 會(huì)讓閱讀你代碼的人困惑:”這個(gè)變量在那里初始化的, 和之前的代碼有關(guān)系么? 和include進(jìn)來(lái)的文件有關(guān)系么?”
最后, 從規(guī)范編程的角度來(lái)講, 你也需要這樣做.
8. 不用第三變量交換倆個(gè)變量的值:
list($a, $b) = array($b, $a),
但其實(shí)還是有匿名臨時(shí)變量的產(chǎn)生, 對(duì)于整數(shù)來(lái)說(shuō), 采用互逆的運(yùn)算來(lái)做, 還是比較靠譜:
復(fù)制代碼 代碼如下:
$a = $a + $b;
$b = $a - $b;
$a = $a - $b;
不過(guò), 還是用異或比較好, 因?yàn)? – * /容易產(chǎn)生精度丟失或者溢出.
9. floor == 倆次非運(yùn)算(此條由skiyo提供)
復(fù)制代碼 代碼如下:
echo ~~4.9;
echo floor(4.9);
用倆次非運(yùn)算的速度基本上是floor的3倍, 不過(guò)有一點(diǎn), 對(duì)于大數(shù)來(lái)說(shuō), 可能會(huì)發(fā)生溢出:
復(fù)制代碼 代碼如下:
echo ~~99999999999999.99; //276447231
echo floor(99999999999999.99); //99999999999999
10. do{}while(0)妙用(此條由Qianfeng提供)
我們知道do{}while(0)在c/c++中, 有很多妙用, 比如消除goto, 宏定義代碼塊.
所以, PHP中同理, 也可以用do{}while(0)來(lái)做一些巧妙的應(yīng)用
復(fù)制代碼 代碼如下:
do{
if(true) {
break;
}
if(true) {
break;
}
} while(false);
//好過(guò)
if(true) {
} else if(true) {
} else {
}
11. 盡量少用@錯(cuò)誤抑制符
如下代碼:
復(fù)制代碼 代碼如下:
@func();
就相當(dāng)于(參見(jiàn)深入理解PHP原理之錯(cuò)誤抑制與內(nèi)嵌HTML):
復(fù)制代碼 代碼如下:
$report = error_reporting(0);
func();
error_reporting($report);
另外錯(cuò)誤抑制符號(hào), 可能會(huì)造成一些問(wèn)題, 參看(http://chabaoo.cn/article/27022.htm);
最后,錯(cuò)誤抑制符在發(fā)生錯(cuò)誤調(diào)試的時(shí)候也可能會(huì)帶來(lái)麻煩.
12. 盡量避免使用遞歸(此條來(lái)自lazyboy)
遞歸性能堪憂(yōu), 而大部分的遞歸都是尾遞歸, 都是可以消除的.
復(fù)制代碼 代碼如下:
function f($n) {
if ($n = 0) return 1;
return $n * f($n - 1);
}
//變?yōu)?
$result = 1;
for ($y = 1; $y < $n + 1; $y++ ) {
$result *= $y;
}
13. 使用$_SERVER['REQUEST_TIME']代替time()
time()會(huì)引來(lái)一次函數(shù)調(diào)用, 而如果對(duì)時(shí)間的精確值要求不高, 可以使用$_SERVER['REQUEST_TIME']代替, 快很多.
14. 避免在for判斷條件中做運(yùn)算(此條來(lái)自留言的Anonymous)
如下的代碼:
for($i=0; $i<strlen($str); $i++) {
}
會(huì)導(dǎo)致每次循環(huán)都調(diào)用strlen, 改為
for ($i=0, $j=strlen($str); $i<$j; $i++) {
}
15. 盡量避免使用正則(此條來(lái)自pangyontao)
正則耗時(shí), 盡量避免, 而采用直接的字符串處理函數(shù)代替, 如:
復(fù)制代碼 代碼如下:
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. 用大括號(hào)括起在雙引號(hào)和heredoc中的變量
如下的代碼:
echo "$name[2]";
PHP不知道程序員的意圖是$name . “[2]“還是$name[2],
所以建議, 都加上大括號(hào):
復(fù)制代碼 代碼如下:
echo "{$name}[2]";
//或者
echo "${name}[2]";
17. 用FALSE表示錯(cuò)誤, 用NULL表示不存在.
對(duì)于操作類(lèi)的函數(shù), 失敗返回FALSE, 表示”操作失敗了”, 而對(duì)于查詢(xún)類(lèi)的函數(shù), 如果找不到想要的值, 則應(yīng)該返回NULL, 表示”找不到”.
相關(guān)文章
PHP圖片處理之使用imagecopyresampled函數(shù)實(shí)現(xiàn)圖片縮放例子
這篇文章主要介紹了PHP圖片處理之使用imagecopyresampled函數(shù)實(shí)現(xiàn)圖片縮放例子,本文先是講解了imagecopyresampled函數(shù)的相關(guān)知識(shí),然后給出了實(shí)現(xiàn)代碼例子,需要的朋友可以參考下2014-11-11PHP實(shí)現(xiàn)通過(guò)strace定位故障原因的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)通過(guò)strace定位故障原因的方法,結(jié)合實(shí)例形式分析了出現(xiàn)高負(fù)載情況下使用strace定位故障原因的相關(guān)命令與操作技巧,需要的朋友可以參考下2018-04-04php 獲取頁(yè)面中指定內(nèi)容的實(shí)現(xiàn)類(lèi)
本文為大家下使用php如何獲取頁(yè)面中的指定內(nèi)容,而且以封裝成類(lèi),需要的朋友可以參考下本文2014-01-01既簡(jiǎn)單又安全的PHP驗(yàn)證碼 附調(diào)用方法
這篇文章主要為大家分享了一段實(shí)用的PHP驗(yàn)證碼類(lèi),既簡(jiǎn)單又安全的PHP驗(yàn)證碼代碼,感興趣的小伙伴們可以參考一下2016-06-06