PHP 中 == / === 可判斷字符串相等,但實際開發常需大小寫不敏感比較、自然排序比較(人類直覺排序)、字典序比較返回大小關係。PHP 提供四大核心比較函數,本文系統對比其差異、參數、返回值與適用場景。
| 函數 | 大小寫敏感 | 排序規則 | 返回值 | 典型場景 |
|---|---|---|---|---|
strcmp($a, $b) | ✅ 是 | 字典序 (ASCII 碼順序) | <0 / 0 / >0 | 精確匹配、區分大小寫排序 |
strcasecmp($a, $b) | ❌ 否 | 字典序 (轉小寫後比較) | <0 / 0 / >0 | 用戶名/郵箱不區分大小寫查重 |
strnatcmp($a, $b) | ✅ 是 | 自然排序 (數字按數值大小) | <0 / 0 / >0 | 版本號、文件名、含數字字符串排序 |
strnatcasecmp($a, $b) | ❌ 否 | 自然排序 + 忽略大小寫 | <0 / 0 / >0 | 不區分大小寫的自然排序 |
$a = 'version2'; $b = 'version10';
// 字典序:逐字符比較 '2' (50) > '1' (49) → $a > $b
var_dump(strcmp($a, $b)); // int(1) 表示 $a > $b
// 自然排序:識別連續數字 2 < 10 → $a < $b
var_dump(strnatcmp($a, $b)); // int(-1) 表示 $a < $b
自然排序算法:將字符串分割為「非數字段」+「數字段」,數字段按整數值比較,非數字段按字典序比較。符合人類直覺(如文件名:img1.png, img2.png, img10.png)。
var_dump(strcmp('Hello', 'hello')); // int(-32) 'H'(72) < 'h'(104)
var_dump(strcasecmp('Hello', 'hello')); // int(0) 相等
strcasecmp 內部將雙方轉為小寫再比較,等價於 strtolower($a) === strtolower($b) 但返回大小關係。
可直接用於 usort 回調:usort($arr, 'strnatcasecmp') 實現自然排序不區分大小寫。
$versions = ['v1.2', 'v1.10', 'v1.0', 'v2.0', 'v1.2.1'];
usort($versions, 'strnatcmp');
print_r($versions);
// 結果: v1.0, v1.2, v1.2.1, v1.10, v2.0 ✅ 符合預期
// 若用 strcmp: v1.0, v1.10, v1.2, v1.2.1, v2.0 ❌
function isUsernameTaken($username, $existingUsers) {
foreach ($existingUsers as $u) {
if (strcasecmp($username, $u) === 0) return true;
}
return false;
}
// 或數組去重
$unique = array_unique($users, SORT_STRING | SORT_FLAG_CASE); // PHP 5.4+
$files = ['doc1.txt', 'doc10.txt', 'doc2.txt', 'Doc1.txt'];
usort($files, 'strnatcasecmp');
// 結果: doc1.txt, Doc1.txt, doc2.txt, doc10.txt
usort($products, function($a, $b) {
// 價格升序,價格相同則名稱自然排序不區分大小寫
if ($a['price'] != $b['price']) return $a['price'] - $b['price'];
return strnatcasecmp($a['name'], $b['name']);
});
| 項目 | 說明 |
|---|---|
| 編碼敏感 | 所有函數按字節比較,UTF-8 中文按字節序(非拼音/筆劃)。中文排序請用 Collator::compare() (intl 擴展)。 |
| 性能 | strcmp 最快(C 層直接比較),strnatcmp 需解析數字段,稍慢。大數據量排序建議預提取排序鍵。 |
| NULL/非字符串 | 參數會強制轉字符串,null => '',123 => '123'。嚴格類型請自行檢查。 |
| mbstring 影響 | 不受 mbstring.func_overload 影響,始終按字節操作。 |
str_contains/str_starts_with/str_ends_with 不是比較函數,屬於檢查函數,不返回大小關係。掌握 strcmp/strcasecmp/strnatcmp/strnatcasecmp 的核心差異——「是否區分大小寫」×「字典序/自然序」——能讓你在字符串排序、去重、匹配、版本比較等場景中精準選型。記住:含數字排序必用自然序,用戶輸入比較多半不區分大小寫。配合 usort、array_unique、SORT_FLAG_CASE 等標識,構建健壯的字符串處理邏輯。