strpos() 是 PHP 中查找子字串在目標字串中首次出現的索引位置的核心函數。雖然用法簡單,但「返回 0 代表找到且位於開頭」與「返回 false 代表未找到」的特性,是無數新手 Bug 的溫床。本文徹底講透用法、陷阱與最佳實踐。
strpos(string $haystack, string $needle, int $offset = 0): int|false
<?php
$str = 'Hello world!';
$pos = strpos($str, 'wo');
var_dump($pos); // int(6)
$pos = strpos($str, 'PHP');
var_dump($pos); // bool(false)
?>
❌ 錯誤寫法:
if (strpos($str, 'Hello')) { // 位置 0 被視為 false,條件不成立!
echo '找到';
}
✅ 正確寫法:
if (strpos($str, 'Hello') !== false) {
echo '找到於索引 ' . strpos($str, 'Hello');
}
鐵律:永遠使用 !== false 或 === false 判斷,切勿直接用於 if 條件或 !strpos()。
$str = 'abcabcabc';
echo strpos($str, 'a', 3); // 3(找到第二個 a)
function strpos_all(string $haystack, string $needle): array {
$positions = [];
$offset = 0;
while (($pos = strpos($haystack, $needle, $offset)) !== false) {
$positions[] = $pos;
$offset = $pos + 1;
}
return $positions;
}
print_r(strpos_all('ababa', 'aba')); // [0, 2]
使用 stripos()(PHP 5+ 內建),行為與 strpos() 完全一致,只差不區分大小寫。
| 函數 | 用途 | 速度 | 備註 |
|---|---|---|---|
strpos() | 查找位置(區分大小寫) | 最快 | 僅返回位置,不複製字串 |
stripos() | 查找位置(不區分大小寫) | 略慢 | 內部需轉換大小寫 |
strstr() | 獲取匹配點後的子字串 | 較慢 | 需複製字串內容 |
preg_match() | 正則匹配 | 最慢 | 功能最強但開銷大 |
💡 原則:只需判斷「是否包含」或「位置」時,優先用 strpos() / stripos()。
if (stripos($content, '敏感詞') !== false)$pos = strpos($url, '?'); $query = $pos !== false ? substr($url, $pos+1) : '';strpos 找分隔符位置,再 substr 切割,比 explode 更省記憶體(大檔案流式處理)。strpos 找 {{var}} 位置並替換。!== false 導致索引 0 被誤判。strpos(位置)與 strstr(子字串)的返回值。strpos($str, $needle) 而未更新 $offset,導致無限循環。mb_strpos()。$str = '你好世界';
echo strpos($str, '世'); // 6(字節索引)
echo mb_strpos($str, '世'); // 2(字符索引,正確)
處理中文等多位元組編碼時,務必使用 mb_strpos()、mb_stripos()、mb_substr() 系列函數,並確保 mb_internal_encoding('UTF-8') 已設定。
記住「嚴格比較」與「編碼對應」兩大鐵律,strpos() 就能成為你字串處理工具箱中最鋒利的利刃。