前言
優化不僅是加快執行速度,更是降低記憶體佔用、減少 I/O 等待。以下 40 條建議涵蓋語法、函式選擇、資料庫、快取、架構等面向,適合中高階 PHP 開發者作為檢核清單。
語法與基本優化
- 靜態方法優先:可用
static 宣告的方法盡量靜態化,呼叫速度提升 ~4 倍。
- echo 優於 print:
echo 無回傳值,語言結構層級更低,效能較佳。
- echo 多參數逗號分隔:
echo $a, $b; 避免字串連接產生暫時變數。
- 循環前預計算上限:
$len = count($arr); for($i=0;$i<$len;$i++) 避免每次呼叫 count()。
- 及時釋放大變數:
unset($bigArray) 釋放記憶體,特別在循環內處理大資料集時。
- 避免魔術方法:
__get、__set、__autoload(已棄用,改用 spl_autoload_register)有額外開銷。
- 慎用 require_once:含檢查機制,比
require 慢 3-4 倍;改用 if (!class_exists('X')) require 'X.php';。
- 使用絕對路徑 include:減少
include_path 解析時間。
- 取得請求起始時間:用
$_SERVER['REQUEST_TIME'] (PHP 5.1+) 替代 time()。
- 函式替代正則:同功能下
strpos、str_replace 比 preg_* 快數倍。
字串處理
- strtr > str_replace > preg_replace:
strtr 效能是 str_replace 4 倍。
- 避免無謂替換:先用
strpos 判斷是否存在再替換,無需替換時效能提升 200%。
- 單引號優於雙引號:單引號不解析變數,解析器更快。
- 字串長度檢查用 isset 技巧:
if (!isset($str[5])) 比 strlen($str) < 6 快(語言結構 vs 函式呼叫)。
控制結構
- switch 優於多重 if-else:Opcode 優化較好。
- 禁用 @ 抑制錯誤:內部處理開銷大,效能差 3 倍;改用
error_reporting 或條件判斷。
- 開啟 mod_deflate / mod_gzip:Apache 層面壓縮輸出,節省 70%+ 頻寬。
變數與記憶體
- 陣列索引加引號:
$row['id'] 比 $row[id] 快 7 倍(避免常數查找)。
- 局部變數遞增最快:方法內
++$i 約等於函式內局部變數速度。
- 全域變數遞增慢 2 倍、物件屬性遞增慢 3 倍、未定義變數遞增慢 9-10 倍。
- 僅定義未使用的區域變數也會拖慢速度(PHP 會檢查全域同名變數)。
- 前置遞增優於後置:
++$i (3 opcodes) vs $i++ (4 opcodes,產生暫時變數)。
物件導向與架構
- 方法數量不影響呼叫效能:類別擴充方法不會降低現有方法速度。
- 子類別方法執行較快:繼承鏈解析優於基類別定義。
- 空函式呼叫 ≈ 7-8 次局部遞增、類別方法呼叫 ≈ 15 次。
- 非必要勿過度 OOP:每個方法/物件呼叫消耗記憶體,陣列常足夠。
- 方法切分適度:只重構真正會重用的邏輯。
- 善用內建函式:C 層實作遠快於用戶端 PHP 代碼。
- 極端效能瓶頸考慮 C 擴充:如影像處理、加密運算。
快取與資料庫
- 啟用 OPcache:避免重複編譯,效能提升 25-100%。
- 引入 Memcached/Redis:快取資料庫查詢結果、Session、運算碼。
- 靜態化頁面:Apache 解析 PHP 比靜態 HTML 慢 2-10 倍。
- SQL 優化:關鍵字大寫、避免
SELECT *、善用索引、EXPLAIN 分析。
- 單一資料庫連線:採用 Singleton 模式,避免重複連線開銷。
其他實用技巧
- 循環外預定義變數:避免大物件在循環內重複建構。
- 多維陣列避免巢狀循環賦值:改用
array_map、array_walk。
- 能用字串函式別用正則。
- foreach 效能優於 while/for(PHP 7+ 差距縮小但仍領先)。
- 用
i+=1 替代 i=i+1:符合 C 語法,Opcode 較少。
- 用完全域變數即 unset。
- 省略 PHP 結束標籤
?>:防止輸出空白字元導致 Header 已送出錯誤。
- 檔案寫入前檢查目錄可寫:
is_writable($dir) 避免權限錯誤。
- 表單判斷用 REQUEST_METHOD + isset:勿依賴 submit 按鈕值(多語系會失效)。
- Session 鍵名加上應用前綴:
APP_ID.'.'.$key 避免同域多應用衝突。
- 工具函式封裝為靜態類別:避免命名衝突、易維護。
- 陣列批次處理用
array_map:$arr = array_map('trim', $arr);。
- 驗證資料用
filter_var / Filter 擴充:內建 Email、IP、URL 驗證,比正則可靠。
- 使用 Xdebug/Blackfire 分析瓶頸:量化優化成果,勿靠直覺。
總結
優化是系統工程,而非單點技巧。建議:
- 先開啟 OPcache、調整 realpath_cache_size
- 引入 Redis/Memcached 快取熱點資料
- 針對慢查詢 SQL 建立索引、改寫
- 使用 Profiler 定位真正瓶頸再針對性優化