Больше никаких костылей: знакомимся с str_starts_with и str_ends_with в PHP 8
Вы когда-нибудь писали код вроде if (strpos($str, 'prefix') === 0) и чувствовали, что это выглядит как-то неуклюже? Или, может быть, вы тратили время на расшифровку substr($str, -3) === 'end', чтобы проверить окончание строки? Если да — у меня для вас отличная новость. Начиная с PHP 8.0, в языке появились две элегантные и интуитивно понятные функции: str_starts_with() и str_ends_with().
В этой статье мы разберём их вдоль и поперёк. Вы узнаете, как они работают, чем отличаются от старых подходов, и почему их стоит использовать в каждом современном PHP-проекте. Мы также рассмотрим реальные примеры из жизни разработчика — от проверки URL до валидации email и работы с файловыми путями.
Что такое str_starts_with() и str_ends_with()?
Это встроенные функции PHP 8, которые позволяют проверить, начинается ли строка с заданной подстроки, или заканчивается ли она на неё. Они возвращают булево значение (true или false), что делает их идеальными для использования в условиях.
Вот их базовый синтаксис:
str_starts_with(string $haystack, string $needle): bool
str_ends_with(string $haystack, string $needle): bool
Где $haystack — это строка, которую вы проверяете, а $needle — подстрока, которую вы ищете в начале или в конце.
Простой пример
<?php
$string = "Hello, world!";
// Проверяем, начинается ли строка с "Hello"
if (str_starts_with($string, "Hello")) {
echo "Строка начинается с 'Hello'"; // Этот код выполнится
}
// Проверяем, заканчивается ли строка на "world!"
if (str_ends_with($string, "world!")) {
echo "Строка заканчивается на 'world!'"; // И этот тоже
}
?>
Просто, правда? Никаких дополнительных вычислений, никаких === 0 или strlen(). Просто проверка и результат.
Почему это важно? Проблемы старых подходов
До PHP 8 разработчикам приходилось изворачиваться. Самый популярный способ проверить начало строки выглядел так:
if (strpos($string, 'prefix') === 0) { ... }
В чём тут проблема? strpos() ищет подстроку где угодно в строке, а не только в начале. Да, проверка === 0 отсекает неверные результаты, но сам код не говорит о намерении разработчика. Вы смотрите на него и думаете: "Ага, он проверяет, начинается ли... или просто ищет?" — это снижает читаемость.
А проверка конца строки была ещё менее интуитивной:
if (substr($string, -3) === 'end') { ... }
Здесь нужно точно знать длину подстроки (-3), что ведёт к ошибкам, если вы укажете неверное число. Плюс, если подстрока длиннее самой строки — substr() просто вернёт пустую строку, и условие никогда не сработает.
Новые функции str_starts_with() и str_ends_with() решают все эти проблемы:
- Читаемость: Код говорит сам за себя.
- Надёжность: Не нужно думать о длине подстроки или о пустых строках.
- Производительность: Функции оптимизированы на уровне ядра PHP.
Реальные примеры использования в веб-разработке
Давайте посмотрим, где эти функции могут пригодиться на практике. Я подобрал несколько сценариев, которые вы наверняка встречали в своей работе.
1. Проверка префиксов URL (роутинг, редиректы)
Допустим, вы пишете простой роутер и хотите обрабатывать URL, которые начинаются с /admin:
<?php
$uri = $_SERVER['REQUEST_URI'];
if (str_starts_with($uri, '/admin')) {
echo "Вы в админ-панели";
// Загружаем админский контроллер
} else {
echo "Это публичная часть сайта";
}
?>
2. Проверка расширения файла
Часто нужно убедиться, что загружаемый файл — изображение:
<?php
$filename = 'photo.jpg';
if (str_ends_with($filename, '.jpg') || str_ends_with($filename, '.png')) {
echo "Это изображение. Можно обрабатывать.";
} else {
echo "Неподдерживаемый формат файла.";
}
?>
Обратите внимание: str_ends_with() чувствительна к регистру. Если у вас есть файл PHOTO.JPG, проверка не сработает. Решение — привести всё к нижнему регистру:
if (str_ends_with(strtolower($filename), '.jpg')) { ... }
3. Валидация email или домена
Хотите проверить, что email заканчивается на определённый домен?
<?php
$email = 'user@gmail.com';
if (str_ends_with($email, '@gmail.com')) {
echo "Это Gmail-адрес";
} elseif (str_ends_with($email, '@yandex.ru')) {
echo "Это Яндекс-почта";
} else {
echo "Другой почтовый сервис";
}
?>
4. Проверка протокола (HTTP/HTTPS)
При работе с внешними ссылками полезно убедиться, что URL начинается с https://:
<?php
$url = 'https://pythonlib.ru';
if (!str_starts_with($url, 'https://')) {
echo "Внимание: соединение не защищено!";
} else {
echo "Ссылка безопасна.";
}
?>
Важные нюансы и подводные камни
Как и у любой функции, у str_starts_with() и str_ends_with() есть свои особенности. Давайте разберём их, чтобы вы не попали впросак.
Регистрозависимость
Обе функции чувствительны к регистру. str_starts_with("Hello", "hello") вернёт false. Если вам нужно игнорировать регистр, используйте strtolower() или mb_strtolower() для многобайтовых строк.
Пустая строка в качестве иголки
Если $needle — пустая строка