str_starts_with在PHP 8.0+中为原生函数,返回bool值、不区分大小写、空字符串前缀恒为true、严格类型检查、字节级比较;PHP 7.x需用strncmp+类型判断模拟,避免substr或strpos陷阱。

str_starts_with 在 PHP 8.0+ 中直接可用
如果你用的是 PHP 8.0 或更高版本,str_starts_with 是原生函数,无需额外安装或兼容层。它返回 true 或 false,不修改原字符串,也不区分大小写——这点和 stripos 不同。
常见错误是传入空字符串作为前缀:str_starts_with("hello", "") 返回 true(PHP 规定空字符串是任意字符串的前缀),这在业务逻辑里可能引发意外判断。
- 只接受 string 类型参数,传 int、null 或 array 会触发
TypeError - 前缀长度超过主字符串时,自动返回
false,不用提前 strlen 判断 - 不能用于多字节字符(如中文)的“语义开头”,它按字节比较;含 UTF-8 中文时需确认是否真要字节级匹配
PHP 7.x 或更低版本怎么模拟
没有 str_starts_with 就得自己写。别用 substr($s, 0, strlen($prefix)) === $prefix——当 $prefix 为空时 substr 返回 false,导致类型不安全比较。
推荐用 strncmp:它支持长度限制、二进制安全、且对空字符串行为明确:
立即学习“PHP免费学习笔记(深入)”;
function str_starts_with($string, $prefix) {
if (!is_string($string) || !is_string($prefix)) {
return false;
}
return strncmp($string, $prefix, strlen($prefix)) === 0;
}
-
strncmp比strpos更轻量,不涉及搜索偏移计算 - 必须加
is_string判断,否则 PHP 7.x 对非字符串参数会静默转成字符串(比如null变成"") - 不要用
mb_substr+===模拟,除非你明确需要多字节感知——那其实该用mb_str_starts_with(需自行实现或引入 polyfill)
和 strpos / mb_stripos 混用时的坑
有人习惯写 strpos($s, $prefix) === 0 来替代,这在多数场景能跑通,但有三个硬伤:
-
$prefix含 NUL 字符("\0")时,strpos会在第一个 NUL 截断,结果不可靠 - 如果
$prefix是正则特殊字符(虽然不常见),容易误以为要转义——其实不用,但心理负担重 -
mb_stripos的第三个参数是 offset,不是 length,没法直接限制只查开头;想不区分大小写又支持多字节?得自己封装mb_strtolower或用mb_ereg(已废弃)
结论:纯 ASCII 场景且确定无 NUL,strpos === 0 可临时用;但只要涉及用户输入、配置项或长期维护,优先上 str_starts_with 或 strncmp。
实际业务中容易被忽略的边界情况
比如验证 API 路径是否以 /v1/ 开头,你以为写 str_starts_with($path, "/v1/") 就稳了,但这些情况仍会出错:
-
$path = "//v1/api"→ 实际匹配的是双斜杠路径,str_starts_with仍返回true,但业务上可能不该放行 -
$path = "/v1/\n"→ 换行符在 URL 中非法,但函数照常返回true,后续解析可能失败 - 前端传来的路径带空格:
" /v1/users",开头有空格,直接判false,但你没做trim就抛错,用户看到的是 404 而不是参数错误
函数本身很干净,但真实请求里的数据从来不是教科书式的。



















