在PHP中检查字符串开头:所有方法与潜在陷阱

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

“我的字符串是否以这个词开头?”——PHP开发者的永恒问题

\n\n

想象一下这样的场景:您正在编写一个URL解析器、处理传入请求,或者只是过滤一个文件列表。这时,您需要检查字符串是否以特定字符集开头。看起来很简单,对吧?但事实并非如此。直到最近,PHP还没有针对这个简单操作的内置函数。开发者们各显神通:有人用substr()截取字符串,有人用strpos()查找位置,还有人甚至深入正则表达式的领域。

\n\n

在本文中,我们将全面梳理PHP中检查字符串开头的所有方法。您不仅会了解如何在现代版本中“优雅地”完成此操作,还会知道如何在仍使用PHP 5的遗留项目中解决这个问题。我们开始吧!

\n\n

最正确的方法:str_starts_with() (PHP 8.0+)

\n\n

如果您的项目运行在PHP 8.0或更高版本上——您很幸运。您可以使用原生函数str_starts_with(),它完全如其名所示。它接受两个参数:原始字符串和我们要在开头查找的子串。返回true或false。

\n\n
<?php\n$url = "https://pythonlib.ru/php-tutorial";\n\nif (str_starts_with($url, "https://")) {\n    echo "链接安全,使用HTTPS";\n} else {\n    echo "警告!非HTTPS连接";\n}\n// 输出:链接安全,使用HTTPS\n?>
\n\n

为什么这是最佳选择?

\n
    \n
  • 可读性——代码不言自明。您无需注释这行代码的作用。
  • \n
  • 性能——该函数在PHP的C代码层面进行了优化。它比手动检查运行得更快。
  • \n
  • 安全性——没有多字节编码的问题(除非您以特殊方式处理UTF-8,但稍后会谈到)。
  • \n
\n\n

顺便说一下,这个函数有一个“孪生姐妹”——str_ends_with(),用于检查字符串结尾。但这已经是另一篇文章的主题了。

\n\n

经典方法:strpos()

\n\n

在str_starts_with()出现之前,最流行的方法是使用strpos()函数。它在字符串中查找子串的首次出现,并返回其位置(数字)。如果未找到子串,则返回false。

\n\n

技巧在于:如果子串位于最开头,其位置将为0。而在PHP中,0是一个假值。因此,检查必须是严格的:

\n\n
<?php\n$string = "Hello, world!";\n\nif (strpos($string, "Hello") === 0) {\n    echo "字符串以Hello开头";\n} else {\n    echo "不,开头不同";\n}\n?>
\n\n

重要!始终使用严格比较运算符===,而不是==。为什么?假设您要查找一个不存在的子串。strpos()将返回false。如果写成strpos($string, "test") == 0,那么false == 0会得到true(因为PHP会进行类型转换)。然后您的代码会说字符串以"test"开头,而事实并非如此。这是新手常犯的经典陷阱!

\n\n

strpos()的优缺点

\n
    \n
  • ✅ 适用于从PHP 4开始的所有PHP版本。
  • \n
  • ✅ 无需安装扩展。
  • \n
  • ❌ 代码可读性较差——需要记住严格比较。
  • \n
  • ❌ 如果使用不当(没有===),会导致难以发现的错误。
  • \n
\n\n

老派方法:substr()

\n\n

另一种来自历史深处的方法。思路很简单:从字符串中截取与要查找的子串长度相同的片段,然后进行比较。

\n\n
<?php\n$filename = "report_2024.pdf";\n\n$prefix = "report_";\nif (substr($filename, 0, strlen($prefix)) === $prefix) {\n    echo "这是2024年的报告";\n?>

博客

书籍推荐