فحص بداية السلسلة النصية في PHP: جميع الطرق والمزالق

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

«Начинается ли моя строка с этого слова?» — извечный вопрос PHP-разработчика

Представьте ситуацию: вы пишете парсер URL, обрабатываете входящие запросы или просто фильтруете список файлов. И тут возникает задача — нужно проверить, начинается ли строка с определённого набора символов. Казалось бы, просто? Но не тут-то было. До недавнего времени в PHP не было встроенной функции для этой простой операции. Разработчики изощрялись кто во что горазд: кто-то обрезал строку через substr(), кто-то искал позицию через strpos(), а кто-то и вовсе лез в дебри регулярных выражений.

В этой статье мы подробно разберём все способы проверки начала строки в PHP. Вы узнаете не только как сделать это «по-красивому» в современных версиях, но и как решить проблему в «старых» проектах, где до сих пор используется PHP 5. Поехали!

Самый правильный способ: str_starts_with() (PHP 8.0+)

Если ваш проект работает на PHP 8.0 или новее — вам повезло. У вас есть нативная функция str_starts_with(), которая делает ровно то, что написано на коробке. Она принимает два аргумента: исходную строку и подстроку, которую мы ищем в начале. Возвращает true или false.

<?php
$url = "https://pythonlib.ru/php-tutorial";

if (str_starts_with($url, "https://")) {
    echo "Ссылка безопасная, используем HTTPS";
} else {
    echo "Внимание! Не HTTPS соединение";
}
// Выведет: Ссылка безопасная, используем HTTPS
?>

Почему это лучший вариант?

  • Читаемость — код говорит сам за себя. Не нужно поясняющих комментариев.
  • Производительность — функция оптимизирована на уровне C-кода PHP. Работает быстрее ручных проверок.
  • Безопасность — никаких проблем с многобайтовыми кодировками (если только вы не работаете с UTF-8 каким-то особенным образом, но об этом позже).

Кстати, у функции есть «близнец» — str_ends_with(), которая проверяет конец строки. Но это тема для отдельной статьи.

Классический способ: strpos()

До появления str_starts_with() самым распространённым способом было использование функции strpos(). Она ищет первое вхождение подстроки в строке и возвращает его позицию (число). Если подстрока не найдена — возвращает false.

Хитрость в том, что если подстрока находится в самом начале, то её позиция будет 0. А 0 в PHP — это falsy значение. Поэтому проверка должна быть строгой:

<?php
$string = "Hello, world!";

if (strpos($string, "Hello") === 0) {
    echo "Строка начинается с Hello";
} else {
    echo "Нет, начало другое";
}
?>

Важно! Всегда используйте оператор строгого сравнения ===, а не ==. Почему? Представьте, что вы ищете несуществующую подстроку. strpos() вернёт false. Если написать strpos($string, "test") == 0, то false == 0 даст true (потому что PHP преобразует типы). И ваш код скажет, что строка начинается с "test", хотя это не так. Классическая ловушка для новичков!

Плюсы и минусы strpos()

  • ✅ Работает на всех версиях PHP, начиная с 4.
  • ✅ Не требует установки расширений.
  • ❌ Код менее читаемый — нужно помнить про строгое сравнение.
  • ❌ При неправильном использовании (без ===) приводит к трудноуловимым ошибкам.

Дедовский способ: substr()

Ещё один способ, пришедший к нам из глубины веков. Идея проста: вырезать из строки кусок той же длины, что и искомая подстрока, и сравнить их.

<?php
$filename = "report_2024.pdf";

$prefix = "report_";
if (substr($filename, 0, strlen($prefix)) === $prefix) {
    echo "Это отчёт за 2024 год";
}
?>

Когда это может быть полезно? Если вам нужно проверить начало и заодно получить остаток строки. Например, чтобы извлечь дату из имени файла.

Недостатки substr()

  • ❌ Лишний код — нужно вручную вычислять длину подстроки.
  • ❌ Опасность ошибок — легко промахнуться с индексами.
  • ❌ Проблемы с многобайтовыми кодировками — если строка содержит кириллицу, обычный substr() может отработать некорректно. В таком случае используйте mb_substr().

Тяжёлая артиллерия: регулярные выражения (preg_match)

Когда простых способов недостаточно, на помощь приходят регулярные выражения. Они позволяют проверить начало не просто по статической подстроке, а по целому шаблону.

<?php
$phone = "+7 (123) 456-78-90";

if (preg_match("/^\\+7/", $phone)) {
    echo "Российский номер телефона";
} else {
    echo "Иностранный номер или неизвестный формат";
}
?>

Символ ^ в регулярном выражении означает «начало строки». Это то, что нам нужно.

Когда это необходимо?

  • Когда нужно проверить начало без учёта регистра (добавьте модификатор i).
  • Когда нужно проверить один из нескольких вариантов: /^(http|https|ftp):\\/\\//.
  • Когда нужно проверить с учётом границ слов.

Но помните: регулярные выражения медленнее обычных строковых функций. Не используйте их там, где можно обойтись str_starts_with() или strpos().

Проблема многобайтовых кодировок (UTF-8)

Все вышеперечисленные способы (кроме регулярных выражений с модификатором u) работают с байтами, а не с символами. Это значит, что если ваша строка содержит кириллицу или иероглифы, вы можете получить неожиданный результат.

Например, строка "Привет" в кодировке UTF-8 занимает 12 байт (каждый символ — 2 байта). Если вы попытаетесь проверить начало с помощью обычного substr(), вы обрежете строку посередине символа и получите «кракозябры».

Решение: используйте mb_* функции:

<?php
$string = "Привет, мир!";

// Неправильно (может не сработать)
if (substr($string, 0, 6) === "Привет") { ... }

// Правильно
if (mb_substr($string, 0, 6) === "Привет") { ... }

// Или просто используйте str_starts_with() — она безопасна для многобайтовых
if (str_starts_with($string, "Привет")) { ... }
?>

Функция str_starts_with() (начиная с PHP 8.0) корректно работает с многобайтовыми кодировками. А вот strpos() и substr() — нет. Помните об этом!

Сравнительная таблица всех способов

Давайте сведём всё в одну удобную таблицу:

Способ PHP 8.0+ PHP 7.x PHP 5.x Безопасен для UTF-8 Скорость Читаемость
str_starts_with() ✅ ❌ ❌ ✅ Высокая Отличная
strpos() === 0 ✅ ✅ ✅ ❌ Высокая Средняя
substr() ✅ ✅ ✅ ❌ Высокая Низкая
preg_match() ✅ ✅ ✅ ✅ (с u) Низкая Зависит от паттерна
mb_substr() ✅ ✅ ✅ ✅ Средняя Низкая

Итог: что выбрать в 2024 году?

Если вы пишете новый код сегодня — используйте str_starts_with(). Это стандартный, современный и правильный способ. Если поддерживаете старый проект — используйте strpos() со строгой проверкой === 0. Регулярные выражения оставьте для случаев, когда нужно проверить сложный шаблон.

И самое главное — всегда помните о многобайтовых кодировках. Если ваши данные содержат нелатинские символы, тестируйте код на реальных данных. Не надейтесь на «авось».

Пишите чистый код, используйте современные функции, и пусть ошибки с началом строки останутся в прошлом! 🚀

المدونات

توصيات الكتب