为什么要在 PHP 中检查字符串的开头和结尾?
\n\n想象一下:你正在用 PHP 编写一个网站,需要检查文件名是否以 .jpg 结尾?或者电子邮件是否以 admin 开头?以前,你不得不使用 substr() 或正则表达式来编写临时解决方案。但从 PHP 8.0 开始,我们有了一个优雅的解决方案——str_starts_with() 和 str_ends_with() 函数。
这不仅仅是语法糖。它们是快速、可读且安全的字符串处理方式,每个 PHP 开发人员都应该掌握。在本文中,我们将通过实际示例来解析它们,与旧方法进行比较,并展示如何避免常见错误。
\n\n什么是 str_starts_with 和 str_ends_with?
\n\n这两个函数都出现在 PHP 8.0(于 2020 年 11 月发布)中。它们解决了一个简单的问题:检查一个字符串是否包含给定的前缀(开头)或后缀(结尾)。
\n\n函数签名
\n\nstr_starts_with(string $haystack, string $needle): bool\nstr_ends_with(string $haystack, string $needle): bool\n\n- \n
$haystack— 要搜索的字符串(大海捞针中的“大海”)。 \n $needle— 要搜索的子字符串(大海捞针中的“针”)。 \n - 返回
true或false。 \n
最简单的示例
\n\necho str_starts_with('Hello, world!', 'Hello'); // true\necho str_ends_with('Hello, world!', 'world!'); // true\necho str_starts_with('Hello, world!', 'world'); // false\n\n重要提示:这些函数区分大小写。str_starts_with('PHP', 'php') 将返回 false。如果你需要不区分大小写的比较,请对两个字符串都使用 strtolower() 或 strtoupper()。
实际使用示例
\n\n1. 检查文件扩展名
\n\n$filename = 'report_2024.pdf';\n\nif (str_ends_with($filename, '.pdf')) {\n echo "这是一个 PDF 文档";\n} elseif (str_ends_with($filename, '.jpg')) {\n echo "这是一张图片";\n} else {\n echo "未知格式";\n}\n\n以前,这是通过 substr($filename, -4) 完成的——很容易在后缀长度上出错。现在,代码读起来就像普通的英语:“字符串以……结尾”。
2. 验证 URL 或电子邮件
\n\n$email = 'user@gmail.com';\n$url = 'https://pythonlib.ru';\n\nif (str_ends_with($email, '@gmail.com')) {\n echo "Gmail 用户";\n}\n\nif (str_starts_with($url, 'https://')) {\n echo "安全连接";\n}\n\n3. 过滤字符串数组
\n\n$files = ['image.jpg', 'document.pdf', 'photo.png', 'notes.txt'];\n\n$images = array_filter($files, function($file) {\n return str_ends_with($file, '.jpg') || str_ends_with($file, '.png');\n});\n\nprint_r($images); // ['image.jpg', 'photo.png']\n\n以前是如何工作的(以及为什么新函数更好)
\n\n在 PHP 8.0 之前,开发人员使用了几种方法。让我们将它们与新函数进行比较。
\n\n方法 1:substr()
\n\n// 旧方法:检查开头\nif (substr($string, 0, strlen('prefix')) === 'prefix') { ... }\n\n// 新方法\nif (str_starts_with($string, 'prefix')) { ... }\n\n旧方法的缺点:
\n- \n
- 冗长:需要计算子字符串的长度。 \n
- 如果
$needle比$haystack长,存在负长度错误的风险。 \n - 代码可读性较差。 \n
方法 2:strpos()
\n\n// 旧方法:检查开头\nif (strpos($string, 'prefix') === 0) { ... }\n\n// 新方法\nif (str_starts_with($string, 'prefix')) { ... }\n\n使用 strpos 很容易出现逻辑错误:如果不使用 === 0,而只是使用 == false 或 == 0,就会出错。