Функции str_starts_with и str_ends_with в PHP: как проверить начало и конец строки?
Проблема и её решение
Вы абсолютно правы: код с substr() работает, но выглядит громоздко. Хорошая новость в том, что вы можете написать свои собственные функции, которые будут работать точно так же, как встроенные str_starts_with() и str_ends_with() из PHP 8. Это сделает код чистым и легко поддерживаемым. Если в будущем вы перейдёте на PHP 8, достаточно будет просто удалить свои функции — имена и сигнатуры совпадают.
Самый простой и правильный способ: свои функции
Создайте две простые функции, которые используют substr() и strlen(), но скрывают всю "грязную" работу внутри:
<?php
function str_starts_with(string $haystack, string $needle): bool {
return $needle !== '' && substr($haystack, 0, strlen($needle)) === $needle;
}
function str_ends_with(string $haystack, string $needle): bool {
return $needle !== '' && substr($haystack, -strlen($needle)) === $needle;
}
?>
Почему это хорошо:
- Читаемость: теперь ваш код будет выглядеть как
if (str_starts_with($file, 'report_'))— сразу понятно, что происходит. - Безопасность: мы добавили проверку
$needle !== '', чтобы избежать ошибок при пустой строке (в PHP 8 эти функции тоже возвращаютtrueдля пустого needle, но это спорное поведение). - Совместимость: если вы обновитесь до PHP 8, просто удалите эти функции — встроенные будут работать точно так же.
Пример использования
<?php
$files = ['report_2024.pdf', 'draft.txt', 'report_summary.docx', 'image.png'];
foreach ($files as $file) {
if (str_starts_with($file, 'report_')) {
echo "Начинается с report_: $file\n";
}
if (str_ends_with($file, '.pdf')) {
echo "Заканчивается на .pdf: $file\n";
}
}
?>
Вывод:
Начинается с report_: report_2024.pdf
Заканчивается на .pdf: report_2024.pdf
Начинается с report_: report_summary.docx
Дополнительные советы
- Регулярные выражения не нужны для такой простой задачи — они избыточны и медленнее.
- Проверяйте аргументы: убедитесь, что
$needleне пустая, иначеsubstr()может вернуть неожиданный результат. - Если вы используете фреймворк (Laravel, Symfony), проверьте, нет ли там встроенных хелперов. Например, в Laravel есть
Str::startsWith().
Этот подход — золотой стандарт для PHP 7.x. Код становится чистым, а вы не зависите от версии PHP.
<<Альтернативный подход: использование strpos() и strrpos()
Можно также использовать функции strpos() и strrpos() для проверки начала и конца строки. Этот способ чуть более изящен, чем substr(), так как не требует вычисления длины подстроки вручную:
<?php
function starts_with(string $haystack, string $needle): bool {
return $needle !== '' && strpos($haystack, $needle) === 0;
}
function ends_with(string $haystack, string $needle): bool {
return $needle !== '' && strrpos($haystack, $needle) === strlen($haystack) - strlen($needle);
}
?>
Как это работает:
strpos()возвращает позицию первого вхождения подстроки. Если она равна 0 — строка начинается с needle.strrpos()возвращает позицию последнего вхождения. Если она равнадлина строки - длина needle— строка заканчивается на needle.
Плюсы:
- Не нужно вызывать
substr(), что может быть чуть быстрее на больших объёмах данных. - Код всё ещё читаемый.
Минусы:
- Для
ends_with()всё равно нужно вызыватьstrlen(). - Функции называются не как в PHP 8, поэтому при обновлении придётся менять имена.
Рекомендую всё же первый вариант с substr() и именами, совпадающими с нативными функциями — это более перспективно. Но если вам нужно максимальное быстродействие на PHP 7.4, этот способ тоже хорош.