判斷字符串長度是否超過閾值,例如「用戶名不超過 20 字符」、「內容至少 10 字符」。
$str = 'aaaaaa';
if (strlen($str) > 6) {
echo '長度大於 6';
}
原理:PHP 內部 zval 結構體直接存儲字符串長度 (len 字段),strlen 僅需讀取該字段返回,屬 O(1) 操作。但涉及函數調用開銷(棧幀、參數傳遞、返回值處理)。
$str = 'aaaaaa';
if (isset($str{6})) { // 索引 6 即第 7 個字符
echo '長度大於 6';
}
原理:isset() 是語言構造器,非函數,編譯器直接生成 opcode,無函數調用開銷。檢查指定偏移量是否存在有效字符。
$str = str_repeat('a', 100);
$iterations = 10_000_000;
// strlen
$start = hrtime(true);
for ($i = 0; $i < $iterations; $i++) {
$len = strlen($str);
}
echo "strlen: " . (hrtime(true) - $start) / 1e9 . "s\n";
// isset
$start = hrtime(true);
for ($i = 0; $i < $iterations; $i++) {
$exists = isset($str{50});
}
echo "isset: " . (hrtime(true) - $start) / 1e9 . "s\n";
典型結果:
strlen:~0.45 秒isset:~0.28 秒| 場景 | 推薦方法 | 說明 |
|---|---|---|
| 精確獲取長度 | strlen() | 唯一選擇 |
| 判斷 > N / < N / ≥ N | isset($str{N}) | 性能優、語義清晰 |
| 多字節字符串 (UTF-8 中文) | mb_strlen() / mb_strpos() | 按字符而非字節計數 |
| 字符串可能未定義 | isset($str) && isset($str{N}) | 避免 Notice |
// 簡化版 zend_string (PHP 7+)
struct _zend_string {
zend_refcounted_h gc;
zend_ulong h; // 哈希值緩存
size_t len; // 字符串長度 (字節數)
char val[1]; // 柔性數組,實際內容
};
strlen 讀取 len 字段isset($str{n}) 檢查 n < len// 1. 明確語義的封裝函數
function strLongerThan(string $str, int $len): bool {
return isset($str{$len}); // $len 為閾值索引,即長度 > $len
}
// 2. 多字節安全版本
function mbStrLongerThan(string $str, int $len, string $encoding = 'UTF-8'): bool {
return mb_strlen($str, $encoding) > $len;
}
// 3. 實際業務中
if (strLongerThan($username, 20)) {
throw new InvalidArgumentException('用戶名過長');
}
// 4. 組合判斷
$min = 2; $max = 20;
if (!isset($str{$min - 1}) || isset($str{$max})) {
// 長度 < $min 或 > $max
}
判斷長度閾值用 isset($str{n}),獲取具體長度用 strlen()。這是 PHP 內部結構特性決定的微優化,單次差異納秒級,但在高頻循環、熱點路徑中可觀。理解 zval 結構,寫出既快又清晰的代碼。