Функции str_starts_with и str_ends_with в PHP: как проверить начало и конец строки?
Решение: встроенные функции str_starts_with() и str_ends_with()
Начиная с PHP 8.0 в языке появились долгожданные функции str_starts_with() и str_ends_with(). Они работают точно так же, как их аналоги в других языках, и делают код чистым и читаемым.
Базовый синтаксис
str_starts_with(string $haystack, string $needle): bool
str_ends_with(string $haystack, string $needle): bool
Обе функции принимают два параметра:
$haystack— исходная строка, которую проверяем$needle— подстрока, которую ищем в начале или конце
Возвращают true, если подстрока найдена, иначе false.
Примеры использования
<?php
$email = "admin_test@gmail.com";
// Проверка начала строки
if (str_starts_with($email, "admin_")) {
echo "Это админский email";
}
// Проверка конца строки
if (str_ends_with($email, "@gmail.com")) {
echo "Это Gmail";
}
// Результат: "Это админский email Это Gmail"
?>
Важные особенности
- Регистрозависимость: функции чувствительны к регистру.
str_starts_with("Hello", "hello")вернётfalse. - Пустая подстрока: если передать пустую строку в качестве
$needle, обе функции вернутtrue(пустая строка считается началом и концом любой строки). - Бинарная безопасность: функции корректно работают с любыми байтовыми последовательностями, включая UTF-8.
- Строгая типизация: если передать не строку, PHP попытается преобразовать её в строку (может вызвать предупреждение).
Что делать, если у вас PHP 7.x или ниже?
Если вы не можете обновиться до PHP 8, можно написать свою реализацию:
<?php
if (!function_exists('str_starts_with')) {
function str_starts_with(string $haystack, string $needle): bool {
return $needle === '' || strpos($haystack, $needle) === 0;
}
}
if (!function_exists('str_ends_with')) {
function str_ends_with(string $haystack, string $needle): bool {
return $needle === '' || substr($haystack, -strlen($needle)) === $needle;
}
}
// Теперь можно использовать как в PHP 8
$email = "admin_test@gmail.com";
var_dump(str_starts_with($email, "admin_")); // true
var_dump(str_ends_with($email, "@gmail.com")); // true
?>
Практический пример: валидация URL
<?php
function validateUrl(string $url): bool {
// Проверяем, что URL начинается с http:// или https://
if (!str_starts_with($url, 'http://') && !str_starts_with($url, 'https://')) {
return false;
}
// Проверяем, что URL заканчивается на .com, .org или .ru
$validEndings = ['.com', '.org', '.ru'];
$isValid = false;
foreach ($validEndings as $ending) {
if (str_ends_with($url, $ending)) {
$isValid = true;
break;
}
}
return $isValid;
}
var_dump(validateUrl('https://example.com')); // true
var_dump(validateUrl('ftp://example.org')); // false (неправильное начало)
var_dump(validateUrl('https://example.net')); // false (неправильное окончание)
?>
Используйте str_starts_with() и str_ends_with() везде, где нужно проверить начало или конец строки. Это делает код понятным, самодокументируемым и менее подверженным ошибкам, чем ручные манипуляции с substr() или strpos().
Альтернативный подход: использование регулярных выражений
Если вам нужно более гибкое решение (например, проверка с игнорированием регистра или сложные шаблоны), можно использовать preg_match() с якорями ^ (начало строки) и $ (конец строки).
<?php
$email = "Admin_Test@Gmail.com";
// Проверка начала без учёта регистра
if (preg_match('/^admin_/i', $email)) {
echo "Начинается с admin_ (регистр не важен)";
}
// Проверка конца без учёта регистра
if (preg_match('/@gmail\.com$/i', $email)) {
echo "Заканчивается на @gmail.com (регистр не важен)";
}
?>
Плюсы:
- Мощные возможности: можно использовать метасимволы, квантификаторы, классы символов.
- Модификатор
iдля регистронезависимой проверки. - Можно проверять сразу несколько условий (например, начинается с A или B).
Минусы:
- Медленнее, чем специализированные функции (регулярные выражения требуют компиляции шаблона).
- Код менее читаем для простых проверок.
- Требуется экранирование специальных символов (например, точку нужно писать как
\.).
Для простых проверок на начало/конец строки лучше использовать str_starts_with() и str_ends_with(). Регулярные выражения оставьте для сложных сценариев, где нужна гибкость поиска.