str_replace 遠快於 ereg_replace/preg_replace不需要正則表達式功能時,**永遠優先用 str_replace**。
<?php
$string = '<i>italic</i> <b>bold</b>';
$iterations = 100000;
// str_replace
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
str_replace(['<i>', '</i>'], ['<em>', '</em>'], $string);
}
echo 'str_replace: ' . (microtime(true) - $start) . 's'; // ~0.08s
// preg_replace
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
preg_replace('/<\/?i>/', '<em>', $string); // 簡化示意
}
echo 'preg_replace: ' . (microtime(true) - $start) . 's'; // ~0.25s
實測差距:單純字串取代 str_replace 約 **3-5 倍** 速度。ereg_replace 已於 PHP 7 移除。
\' 和 \\$name = 'World';
// 較慢
echo "Hello $name\n";
// 較快
echo 'Hello ' . $name . "\n";
微觀效能差異極小 (納秒級),但在**百萬級迴圈**或**高流量熱點路徑**可觀測到差異。建議:預設用單引號,需插值/換行才用雙引號或 Heredoc/Nowdoc。
測試環境:foo 表 1,000 筆,big_foo 表 1,000,000 筆 (相當於 foo 自 JOIN)。
| 查詢 | 耗時 (秒) | 說明 |
|---|---|---|
SELECT * FROM foo | 0.032 | 基準 |
SELECT * FROM foo a, foo b (Cartesian Product) | 17.28 | 1,000 × 1,000 = 1,000,000 列 |
SELECT * FROM foo a, foo b WHERE a.id > b.id | 14.65 | 仍產生大量中間結果 |
SELECT * FROM foo a, foo b WHERE a.id = b.id | 0.041 | 等值 JOIN,索引命中極快 |
SELECT * FROM big_foo | 25.39 | 單表百萬筆全掃描 |
結論:
big_foo) 速度與無條件 JOIN 同數量級include vs require 差異與陷阱| 特性 | include | require |
|---|---|---|
| 失敗行為 | 發出 Warning,腳本繼續執行 | 發出 Fatal Error,腳本終止 |
| 條件包含 | 動態評估,if ($cond) include $file; 依條件決定 | **編譯期**無條件包含,if ($cond) require $file; 仍會包含 |
| 迴圈中動態檔名 | while($i++) include "file$i.php"; ✅ 正常 | while($i++) require "file$i.php"; ❌ 重複包含同一檔 |
| 回傳值 | 可接收 return 值 | 同 |
實務建議:
require_onceinclude_onceinclude**echo vs print| 特性 | echo | print |
|---|---|---|
| 回傳值 | 無 | 永遠回傳 1 (可用於複合運算式) |
| 多參數 | echo 'a', 'b', 'c'; (無逗號連接開銷) | 單一參數 print 'a'.'b'.'c'; 需先連接 |
| 速度 | 略快 (無回傳值處理) | 略慢 |
| 優先使用 | ✅ 一般輸出 | 極少見需回傳值場合 |
opcache.enable=1, opcache.memory_consumption=256)includeCache-Control、Gzip/Brotli、HTTP/2 或 HTTP/3session_write_close() 釋放鎖str_replace、單引號、echo 多參數、嚴格型別宣告 (PHP 7+)、避免全域變數