2009年7月3日 星期五

「引用」十大技巧提升你的 PHP 實力

「來源」

Smashing Magazine 的網站,Glen Stansberry 提出十個進階 PHP 技巧,可以即時提昇你的 PHP 編程實力,其中包括 SQL 注入攻擊的「作弊表」、簡化判斷句中的 else 部分、在不得已的情況下才使用正規表達式、三元運算子、Memcached 數據庫快取系統等等,以下是詳細的內容。

PHP 在 1995 年從一個不起眼的編程語言開始,多年來迅速發展,現在已經是其中一種最流行的網絡開發語言,許多熱門網站均採用 PHP 來開發,絕大多數的程式和網站項目都是由這種流行語言寫成。

由於 PHP 如此受歡迎,任何網站開發人員幾乎都不能不認識 PHP,這份教程是為那些剛剛完成了 PHP 的學習初階,捲起衣袖準備大幹一番的人,下面列出的十個優秀技巧,是 PHP 開發人員必須學習,並在每次編程時使用它們,這些提示可以加快你們對 PHP 的熟練,使程式碼跑得更快捷,更簡潔,性能上更優化。

1. 使用 SQL 注入攻擊作弊表

SQL 注入攻擊是一種非常令人厭惡的東西,它是一種安全漏洞,允許黑客利用程式碼中的漏洞潛入你的數據庫。雖然本文與 MySQL 無關,不過許多 PHP 程式使用 MySQL 數據庫,若果你要寫安全的程式碼,懂得什麼情況需要避開是很有用的。

Furruh Mavituna 寫了一篇很有趣的 SQL 注入攻擊作弊表,其中一章節有關 PHP 和 MySQL 的安全漏洞,若果你能避開其中所述的行為,你的程式將不容易受到攻擊。

2. 認識各種比較運算符的分別

比較運算符是 PHP 很重要的部份,可惜很多程序員並不熟悉它們之間的分別,事實上,據一篇在 IO Reader 網站上發表的文章,許多 PHP 開發人員不能分辨 PHP 各種比較運算符之間的差異,引用該文的幾句話:

這是極為重要的,但是很多 PHP 開發人員根本不知道 == 和 === 有什麼分別,從本質上講,== 判斷兩個值是否相等,PHP 在進行比較前會嘗試轉換數據類型以,例如:1== '1' (true);=== 則同時判斷值和數據類型,例如:1==='1'(false),開發人員必須儘快認識這些運算符對常用函式如 strpos() 的實用性,由於 PHP 把零視為「false」,沒有 === 的話我們無從知道一個被搜尋字符串是在一個較長字符串的開始位置,還是根本不存在,在很多其他應用裡,當傳回值為零未必等於 false 的時候,=== 便十分有用。

你可以到 PHP.net 網站看到各種比較運算符的清單

3. 簡化判斷句中的 else 部分

必須提示各位,第三和第四點可能會使程式碼的可讀性降低,這兩點強調速度和效能,若果你不想犧牲程式碼的可讀性,你可能要跳過它們。

凡是能使程式碼更簡單和更小的做法,通常都是好的做法,其中之一就是把 else 敘述句的內容抽出來,Christian Montoya 便有一個很好的例子,利用較短的 else 敘述句來轉換字符。

常見的 else 敘述句:

if( this condition )
{
$x = 5;
}
else
{
$x = 10;
}

如果 $x 的預設值是 10,我們便從 10 開始,無須在 else 部分指定它的值。

$x = 10;
if( this condition )
{
$x = 5;
}

雖然看起來沒有很大分別,不過若果你的程式中有很多 else 敘述句,累加的效果會很明顯。

4. 放棄那些括號

就像簡化 else 敘述句那樣,如果在控制結構後只有一句表達式,放棄表達式前後的括號可以節省一些字符。Evolt.org 便有一個靈巧的例子示範怎樣減少使用括號。

if ($gollum == 'halfling') {
$height --;
}

這是相同的:

if ($gollum == 'halfling') $height --; 

這個方法可以在程式中多次使用:

if ($gollum == 'halfling') $height --;
else $height ++;

if ($frodo != 'dead')
echo 'Gosh darnit, roll again Sauron';

foreach ($kill as $count)
echo 'Legolas strikes again, that makes' . $count . 'for me!';

5. 取 str_replace(),捨 ereg_replace() 及 preg_replace()

以效率來說,str_replace() 比正規表達式更適合用來取代字符串,據一些研究,str_replace() 的效率比 ereg_replace() 和 preg_replace() 高 61%。

6. 使用三元運算符

在使用 if / else 敘述句的場合,使用三元運算符,PHP Value 網站有一個使用三元運算符的範例

//PHP COde Example usage for: Ternary Operator
$todo = (empty($_POST[』todo'])) ? 『default' : $_POST[』todo'];

// The above is identical to this if/else statement
if (empty($_POST[』todo'])) {
$action = 『default';
} else {
$action = $_POST[』todo'];
}
?>

三元運算符可以節省程式碼的空間,使你的程式碼沒那麼混亂,也使其更容易閱讀。但要注意,不要在同一句敘述句中使用超過一個三元運算符,因為在這種情況下 PHP 未必知道該怎麼辦。

7. Memcached

雖然 PHP 有很多數據庫快取工具,但是 Memcache 始終是效能最高的一個,雖然從實作的角度看它不是最簡單方便,不過若果你要建立一個使用數據庫的網站,Memcached 肯定可以為你的系統加速,Memcached 的快取架構最初是為一個以 PHP 為基礎的網誌系統 LiveJournal 而建立的。

在 PHP.net 網站有一份安裝和使用 Memcached 的教學文件

8. 使用開發架構

你未必每一個開發項目都使用 PHP 開發架構,但開發架構如 CakePHPZendSymfonyCodeIgniter 等無疑可以大大減少你建立一個網站的時間。開發架構是一個包含很多常用功能的軟件,可以幫助加快開發工作,使用開發架構可以消除一些開發網頁應用系統和網頁服務的繁瑣工作。

如果你可以利用開發架構來處理重複性的編程工作,你的開發進度將會大幅提高,寫的程式碼越少,所需的調試和除蟲的工作便越少

9. 正確使用壓抑運算符

錯誤壓抑運算符(在 PHP 手冊中稱為「錯誤控制運算符」)是指「@」符號,當它出現在一句 PHP 表達式前面,意思就是不論表達式發生任何錯誤都不要顯示出來,這是非常方便的,尤其是當你不知道程式碼什麼時候會發生錯誤,希望有關的錯誤訊息不會在用戶面前出現。

然而,很多程序員經常錯誤地使用這個錯誤壓抑運算符,「@」運算符相當緩慢,並且銷耗頗多資源,對系統的效能有負面影響。Michel Fortin 有一些很好的例子示範如何用替代方法迴避「@」運算符,以下是他使用 isset 替代錯誤壓抑運算符的範例:

if (isset($albus))  $albert = $albus;
else $albert = NULL;

相當於:

$albert = @$albus;

第二種形式雖然比較簡單,但它的執行速度卻比第一種慢兩倍,一個更好的解決方法是透過參考來指定變量,不會引致任何錯誤訊息,像這樣:

$albert =& $albus; 

必須注意這些變化都有某些副作用,只能應用在有極高效能要求的場合中使用。

10. 使用 isset 捨棄 strlen

如果你要檢查一個字符串是否過長,應該使用 isset 而不是 strlen,因為使用 isset 比 strlen 快五倍,還有,使用 isset 的話即使變量不存在你的表達式仍然是合法的,D-talk 有一個用 isset 替代 strlen 的詳細說明,例如要檢查字符串 $str 是否超過 9 個字符,使用 isset 的方法是:

if (isset($str[9])) echo "字符串的長度是 10 或以上"
else echo "字符串的長度小於 10"

雖然速度上這只是很小的改善,但加上前面涵蓋的技巧,累加起來便可以有更快、更精簡的程式。

【下列文章您可能也有興趣】

2 則留言:

Jax Hu 提到...

關於第四點其實不是很好的示範
去除括號不如去除不必要的空白或 Tab
或著直接用 Zend 編譯 PHP

而且不當的化簡容易造成語意錯誤
同樣是 C style 的語言
最好還是使用嚴僅語法撰寫

下面例子中也提到這樣的問題
http://www.blueidea.com/tech/web/2009/6824.asp

千江有水千江月 提到...

呵~ 感謝指點...