在 php 8 中,应直接使用 str_contains() 函数来替代 strpos() !== false 的判断逻辑。该函数接受 haystack(主串)和 needle(子串)两个参数,当主串包含子串时返回布尔值 true,否则返回 false。这种写法不仅消除了类型比较的歧义,还显著提升了代码的可读性。

旧版 strpos 判断存在的隐患是什么
使用 strpos() 进行包含判断的主要隐患在于其返回值类型。当子串出现在主串的起始位置(索引 0)时,strpos() 会返回整数 0。如果使用弱类型比较运算符 == 来判断是否不等于 false,即 strpos($haystack, $needle) == false,由于 0 在 PHP 中会被转换为 false,这会导致误判为“不包含”,从而引发逻辑错误。因此,旧版代码必须严格使用非弱类型比较 !== 才能正确工作。

$haystack = "hello";
$needle = "he";
// 错误写法:返回 false,因为 0 == false 为 true
if (strpos($haystack, $needle) == false) {
echo "Not found";
}
// 正确写法:返回 false,因为 0 !== false 为 true
if (strpos($haystack, $needle) !== false) {
echo "Found";
}
上述代码展示了 strpos() 在匹配成功且位于开头时的行为。预期结果是第一个条件块不执行,第二个条件块执行并输出 "Found"。这证明了 !== 是处理 strpos() 返回值的必要手段,而 str_contains() 直接解决了这一痛点。
str_contains 在不同编码下的表现如何
str_contains() 函数完全基于字节序列进行操作,它不感知字符编码。这意味着在处理 UTF-8 等多字节编码字符串时,如果子串跨越了多字节的边界,或者主串中包含非法字节序列,函数的行为可能不符合预期。与 mb_str_contains()(PHP 8.3+ 引入)不同,str_contains() 不会尝试解析字符边界,因此在涉及多语言文本时需谨慎使用。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。

$utf8_string = "你好世界";
$substring = "好世";
// str_contains 按字节查找
if (str_contains($utf8_string, $substring)) {
echo "Contains";
} else {
echo "Not Contains";
}
// mb_str_contains 按字符查找 (PHP 8.3+)
if (mb_str_contains($utf8_string, $substring, encoding: 'UTF-8')) {
echo "MB Contains";
}
在 UTF-8 编码下,"好" 和 "世" 各占 3 个字节。如果 $substring 是完整的字符序列,str_contains() 能正确找到。但如果 $substring 是半个字符(如只取 "好" 的前两个字节),str_contains() 仍可能在字节层面匹配到相同的字节序列,导致误报。而 mb_str_contains() 则确保按完整字符匹配。对于 ASCII 或单字节编码,两者行为一致。
str_contains 遇到空字符串作为 needle 时返回什么
当 str_contains() 的第二个参数 $needle 为空字符串时,函数始终返回 true。这是因为从逻辑上讲,任何字符串都包含空字符串。这一行为与 strpos($haystack, "") 返回 0 的逻辑一致(0 表示存在),但通过布尔值直接表达更为直观。开发者无需额外检查 $needle 是否为空,函数已内置处理。
$test_string = "abc"; var_dump(str_contains($test_string, "")); // bool(true) var_dump(str_contains($test_string, "a")); // bool(true) var_dump(str_contains($test_string, "d")); // bool(false)
以上代码验证了 str_contains() 对空子串的处理。无论主串内容如何,只要 $needle 为空,结果即为 true。这与旧版 strpos() 的行为在语义上是等价的,但 str_contains() 提供了更明确的布尔返回值,避免了类型转换的混淆。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










