Google 的 webmaster Eric Higgins 寫了一篇文章介紹怎樣優化 PHP,文章刊登不久,PHP 開發團隊其中一員 Gwynne Raskind 發文提出異議,指 Eric 所說的與事實不符,有些甚至完全相反,在 PHP 5 上幾乎沒有一項 Eric 的優化技巧能帶來實質的好處。我們摘錄了比較具爭議性的幾點,看看誰是誰非。
Eric Higgins: 不要沒來由的複製變量
Eric 說每次我們複製一個變量的時候,便會消耗一些記憶體,一些 PHP 初哥為了使他們的原碼「好讀」,喜歡把一些預定義變量複製到另一個名稱比較簡短、容易記憶的變量,這樣對程式的效能有負面的影響。在下面的例子中,如果用 戶輸入了一段 512KB 的文字,程式便會消耗 1MB 的記憶體:
| PHP | | copy code | | ? |
| 1 | $description = strip_tags($_POST['description']); |
| 2 | echo $description; |
我們沒有理由把文字複製到 $description,只需:
| PHP | | copy code | | ? |
| 1 | echo strip_tags($_POST['description']); |
Gwynne Raskind: 複製變量不一定增加記憶體的消耗
從 PHP 4 開始,Zend 引擎變使用一種稱為「copy-on-write」的記憶體管理技術,舉一個例子,無論我們把 $source 的內容複製多少次到 $destination,我們一天不改變 $source 的值,真正的複製都沒有進行,不論我們的程式讀取 $source 還是 $destination,都是從同一個記憶體地址提取內容。以下的例子可以測試複製變量對記憶體使用影響:
| PHP | | copy code | | ? |
| 1 | <?php |
| 2 | $data = str_repeat("*", 512 * 1024); // 模擬 512K 數據 |
| 3 | $memory_used_before = memory_get_usage(); |
| 4 | $more_data = $data; |
| 5 | $memory_used_after = memory_get_usage(); |
| 6 | print "Before: {$memory_used_before}\nAfter: {$memory_used_after}\n"; |
| 7 | ?> |
在 PHP 5.3 (在除錯編譯模式下)執行的結果是:
Before: 853968 After: 854236
可見在複製前後記憶體的消耗相差只有 268 bytes,若果用正常的編譯模式,這也是絕大部分網站使用的模式,差別只有 64 bytes。
Eric Higgins: 字符串要用單引號
PHP 容許我們使用單引號或者雙引號來指定字符串,其實兩者的效能有很大差異,雙引號告訴 PHP 引擎在字符串中找尋變量,並以變量的值取代有關的部份,若果你有一列很長的純文字字符串,雙引號會引致效能降低。
Gwynne Raskind: 大部份情況下雙引號的效能比單引號高
對於不含變量的純文字字符串,由於 PHP 引擎的實作方式,雙引號的效能肯定比單引號高。
若果字符串中的變量不算很多,使用雙引號並把變量內崁在字符串中,效能也比使用單引號和字符串連接運算子的方法高。
Eric Higgins: 使用 switch/case,不用 if/else
不論是為了效能、可讀性、還是可維護性,若果只對一個變量進行檢測,我們都應該盡量使用 switch/case 代替 if/else,例如以下使用 if/else 的原碼:
| PHP | | copy code | | ? |
| 1 | if($_POST['action'] == 'add') { |
| 2 | addUser(); |
| 3 | } elseif ($_POST['action'] == 'delete') { |
| 4 | deleteUser(); |
| 5 | } elseif ($_POST['action'] == 'edit') { |
| 6 | editUser(); |
| 7 | } else { |
| 8 | defaultAction(); |
| 9 | } |
應該改用 switch/case 重寫:
| PHP | | copy code | | ? |
| 01 | switch($_POST['action']) { |
| 02 | case 'add': |
| 03 | addUser(); |
| 04 | break; |
| 05 | case 'delete': |
| 06 | deleteUser(); |
| 07 | break; |
| 08 | case 'edit': |
| 09 | editUser(); |
| 10 | break; |
| 11 | default: |
| 12 | defaultAction(); |
| 13 | break; |
| 14 | } |
Gwynne Raskind: switch/case 和 if/else 效能上沒有分別
Eric 的論點根本沒有根據,使用哪一種句式純粹是編程風格的問題,除了在極少數情況外,兩者的效能幾乎毫無分別。

[...] 有人持反對意見: Google 教你優化 PHP,PHP 開發團隊指內容不確 [...]
[...] Google 教你優化 PHP,PHP 開發團隊指內容不確 [...]