要檢查一個字串 $str1
是否包含另一個字串 $str2
,我們可以使用 PHP 內建的 strpos()
函數。然而,strpos()
存在一個常見的「陷阱」:如果子字串 $str2
在 $str1
的開頭(也就是索引 0)被找到,strpos()
會返回 0
。在布林上下文中,0
會被評估為 false
,這可能導致判斷錯誤。
strpos()
的潛在陷阱與修正
讓我們看看這個潛在的陷阱:
PHP
<?php
$str1 = 'yabadabadoo';
$str2 = 'yaba';
// 錯誤的檢查方式:
if (strpos($str1, $str2) == FALSE) { // 或者 !strpos($str1, $str2)
echo "'$str1' 不包含 '$str2' (錯誤判斷)\n";
} else {
echo "'$str1' 包含 '$str2'\n";
}
// 修正後的檢查方式:
if (strpos($str1, $str2) !== FALSE) {
echo "'$str1' 包含 '$str2' (正確判斷)\n";
} else {
echo "'$str1' 不包含 '$str2'\n";
}
?>
在上面的例子中,strpos($str1, $str2)
會返回 0
,因為 'yaba'
就在 'yabadabadoo'
的開頭。
- 當我們使用
== FALSE
進行比較時,0 == FALSE
為true
,導致程式誤判為不包含。 - 正確的修正方法是使用嚴格比較運算符
!== FALSE
(或=== 0
進行精確匹配,但!== FALSE
更通用於任何位置的查找),這樣就能區分子字串不存在(返回false
)和子字串在開頭(返回0
)。
完整的程式碼範例
以下是如何正確檢查 $str1
是否包含 $str2
的程式碼:
PHP
<?php
function containsString(string $haystack, string $needle): bool
{
/**
* 檢查一個字串是否包含另一個字串。
*
* @param string $haystack 搜尋的原始字串。
* @param string $needle 要搜尋的子字串。
* @return bool 如果包含則返回 true,否則返回 false。
*/
// 使用 !== FALSE 進行嚴格比較,避免 strpos 返回 0 時的誤判
return strpos($haystack, $needle) !== FALSE;
}
// 範例 1: 子字串在開頭
$str1_a = 'yabadabadoo';
$str2_a = 'yaba';
if (containsString($str1_a, $str2_a)) {
echo "案例 1: '$str1_a' 包含 '$str2_a'\n"; // 預期輸出:包含
} else {
echo "案例 1: '$str1_a' 不包含 '$str2_a'\n";
}
// 範例 2: 子字串在中間
$str1_b = 'hello world';
$str2_b = 'world';
if (containsString($str1_b, $str2_b)) {
echo "案例 2: '$str1_b' 包含 '$str2_b'\n"; // 預期輸出:包含
} else {
echo "案例 2: '$str1_b' 不包含 '$str2_b'\n";
}
// 範例 3: 子字串不存在
$str1_c = 'programming';
$str2_c = 'code';
if (containsString($str1_c, $str2_c)) {
echo "案例 3: '$str1_c' 包含 '$str2_c'\n";
} else {
echo "案例 3: '$str1_c' 不包含 '$str2_c'\n"; // 預期輸出:不包含
}
// 範例 4: 空字串作為子字串
$str1_d = 'abc';
$str2_d = '';
if (containsString($str1_d, $str2_d)) {
echo "案例 4: '$str1_d' 包含 '$str2_d' (空字串通常被認為是包含的)\n"; // 預期輸出:包含
} else {
echo "案例 4: '$str1_d' 不包含 '$str2_d'\n";
}
?>
其他考慮
除了 strpos()
,PHP 還提供了其他函數來檢查字串包含性,例如:
strstr()
: 這個函數會在$haystack
中查找$needle
,如果找到,則返回$needle
及其之後的部分;如果找不到,則返回FALSE
。它的行為與strpos()
類似,也需要使用嚴格比較 (!== FALSE
)。str_contains()
(PHP 8+ 引入): 這是 PHP 8 及更高版本中引入的一個專門用於檢查字串包含性的函數。它直接返回布林值true
或false
,因此沒有strpos()
的陷阱,使用起來更直觀、安全。如果您的環境允許,強烈建議使用此函數。
使用 str_contains()
的範例:
PHP
<?php
// 僅適用於 PHP 8 及更高版本
$str1 = 'yabadabadoo';
$str2 = 'yaba';
if (str_contains($str1, $str2)) {
echo "使用 str_contains(): '$str1' 包含 '$str2'\n";
} else {
echo "使用 str_contains(): '$str1' 不包含 '$str2'\n";
}
?>
總之,當使用 strpos()
時,務必記住使用嚴格比較運算符 !== FALSE
來避免因子字串在索引 0 導致的判斷錯誤。如果您的 PHP 版本是 8 或更高,那麼 str_contains()
則是更簡潔、更安全的選擇。
沒有留言:
張貼留言