Avatar ·

Функции str_starts_with и str_ends_with в PHP: как проверить начало и конец строки?

Всем привет! Я только начал изучать PHP и столкнулся с проблемой. Мне нужно проверить, начинается ли строка с определённого слова или заканчивается ли она на определённый символ. Например, я получаю email от пользователя и хочу убедиться, что он заканчивается на "@gmail.com" или начинается с "admin_". Я знаю, что в PHP есть много встроенных функций для работы со строками, но не могу найти простого способа сделать это. Пробовал использовать substr() и сравнивать, но код получается громоздким: ```php $email = "admin_test@gmail.com"; if (substr($email, 0, 6) === "admin_") { echo "Это админский email"; } if (substr($email, -10) === "@gmail.com") { echo "Это Gmail"; } ``` Это работает, но мне кажется, что есть более элегантное решение. Я слышал, что в Python есть методы startswith() и endswith(), а в Java — startsWith() и endsWith(). Есть ли что-то подобное в PHP? Я использую PHP 7.4, но слышал про новые функции в PHP 8. Подскажите, как правильно и красиво решить эту задачу? Буду благодарен за примеры кода! <<>>

Решение: встроенные функции 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(). Регулярные выражения оставьте для сложных сценариев, где нужна гибкость поиска.