PHPFlowPHP, MySQL, Laravel и JavaScript

Строки в PHP: функции для поиска, замены, обрезки и разбиения

Обновлено:

Коротко

Строки в PHP обрабатывают встроенными функциями: длину возвращает mb_strlen(), поиск подстроки - str_contains() и mb_strpos(), замену - str_replace(), обрезку - trim(), разбиение - explode(). Для русского текста в UTF-8 выбирайте функции с префиксом mb_, иначе длина и обрезка будут считаться в байтах.

Содержание
  1. Строка в PHP: создание и склейка
  2. Длина строки: strlen и mb_strlen
  3. Поиск подстроки в строке
  4. Часть строки: substr и mb_substr
  5. Замена подстроки в строке
  6. Обрезка пробелов и длинных строк
  7. Разбить строку на массив и собрать обратно
  8. Перенос строки в тексте
  9. Как преобразовать строку в число
  10. Регистр и сравнение строк
  11. Многобайтовые функции mb_ и кодировка UTF-8

Строка в PHP: создание и склейка

Строка (string) в PHP - это последовательность байтов. Сам язык не знает о кодировке: для него кириллическая буква в UTF-8 - это два байта, а эмодзи - четыре. Из-за этого у многих функций есть пара: обычная (strlen, substr) работает с байтами, многобайтовая с префиксом mb_ (mb_strlen, mb_substr) - с символами. Для русского текста почти всегда нужна вторая.

Схема: байты и символы в строке PHP
Обычные функции считают байты, функции mb_ - символы

Строку записывают в одинарных или двойных кавычках, многострочный текст - в heredoc. Чем они различаются и как вставлять переменные, подробно разобрано в статье об интерполяции строк. Склейка (конкатенация строк) делается точкой, дописывание в конец - оператором .=:

<?php
$first = 'Анна';
$last = 'Смирнова';

$full = $first . ' ' . $last;   // Анна Смирнова
$html = '<ul>';
$html .= '<li>' . $full . '</li>'; // дописываем в конец
$html .= '</ul>';

// Повторить строку N раз
echo str_repeat('-', 20);

Для проверки "это вообще строка?" есть is_string($value). Пустая ли строка, надёжнее проверять строгим сравнением $s === '': функция empty() считает пустой и строку '0'.

Длина строки: strlen и mb_strlen

PHP длина строки считается двумя функциями, и они дают разный результат на кириллице. strlen() возвращает число байтов, mb_strlen() - число символов.

<?php
$s = 'Привет';

echo strlen($s);     // 12 - байты, по 2 на букву
echo mb_strlen($s);  // 6 - символы

// Проверка длины поля формы
$login = trim($_POST['login'] ?? '');
if (mb_strlen($login) < 3 || mb_strlen($login) > 32) {
    echo 'Логин должен быть от 3 до 32 символов';
}
Сравнение strlen и mb_strlen в терминале
strlen и mb_strlen по-разному считают длину кириллической строки

strlen() пригодится, когда важен именно размер в байтах: ограничение колонки VARBINARY, размер тела HTTP-запроса, сравнение с лимитом протокола. Для валидации текста, обрезки и вывода - только mb_strlen().

Поиск подстроки в строке

С PHP 8.0 для проверки вхождения подстроки в строку есть три понятные функции. Они возвращают true или false и корректно работают с UTF-8, потому что сравнивают байты целиком.

<?php
$url = 'https://example.com/catalog/phones?page=2';

str_contains($url, '/catalog/');  // true - подстрока есть
str_starts_with($url, 'https://'); // true - начинается с
str_ends_with($url, '.pdf');       // false - заканчивается на

// Без учёта регистра: приводим обе строки к нижнему
str_contains(mb_strtolower($title), 'php');
Пример поиска подстроки в PHP 8
str_contains и str_starts_with возвращают true или false

Позиция подстроки: strpos и mb_strpos

Если нужно не только найти подстроку, но и узнать, где она стоит, используйте strpos() (байтовая позиция) или mb_strpos() (позиция в символах). Поиск с конца - strrpos(), без учёта регистра - stripos() и mb_stripos().

<?php
$text = 'Заказ оформлен. Заказ оплачен.';

$pos = mb_strpos($text, 'оплачен');   // 22
if ($pos !== false) {
    echo "Найдено на позиции $pos";
}

mb_strrpos($text, 'Заказ');          // 16 - последнее вхождение
substr_count($text, 'Заказ');        // 2 - сколько раз встречается

Проверяйте результат strpos() только строгим сравнением !== false. Если подстрока стоит в самом начале, функция вернёт 0, и условие if (strpos(...)) ошибочно сочтёт, что ничего не найдено.

Часть строки: substr и mb_substr

Чтобы вырезать часть строки, передайте начальную позицию и длину. Отрицательная позиция отсчитывается с конца. Для кириллицы снова берите mb_substr(): обычная substr() может разрезать букву пополам, и на странице появится "�".

<?php
$s = 'Программирование';

mb_substr($s, 0, 9);   // Программи - первые 9 символов
mb_substr($s, -4);     // ание - последние 4
mb_substr($s, 3, 5);   // грамм - с 4-го символа 5 штук

// Текст до и после разделителя
$email = 'ivan@example.com';
strstr($email, '@', true);  // ivan
strstr($email, '@');        // @example.com
substr(strrchr('photo.final.jpg', '.'), 1); // jpg - расширение

Как удалить последний или первый символ

Убрать последний символ в строке можно через mb_substr($s, 0, -1). Если нужно отрезать конкретный хвост, например лишнюю запятую после цикла, надёжнее rtrim($s, ','): она не тронет строку, если запятой нет. Первый символ удаляет mb_substr($s, 1).

<?php
$list = 'яблоки, груши, сливы, ';
echo rtrim($list, ', ');        // яблоки, груши, сливы
echo mb_substr('#тег', 1);       // тег

Замена подстроки в строке

Основная функция замены - str_replace(что, на_что, где). Она заменяет все вхождения, принимает массивы и через четвёртый аргумент сообщает, сколько замен сделано. Без учёта регистра работает str_ireplace().

<?php
$phone = '+7 (912) 345-67-89';

// Удалить из строки скобки, пробелы и дефисы
$clean = str_replace(['(', ')', ' ', '-'], '', $phone); // +79123456789

// Несколько замен сразу и подсчёт
$text = str_replace(['ё', 'Ё'], ['е', 'Е'], 'Ёлка и ёжик', $count);
echo "$text, замен: $count"; // Елка и ежик, замен: 2

Для разных задач замены подходят разные функции:

ФункцияЧто делаетКогда брать
str_replace()Заменяет все вхождения подстрокиПростые замены и удаление символов
strtr()Заменяет по словарю за один проходШаблоны {name}, транслитерация
substr_replace()Заменяет кусок по позицииМаскировка номера карты, вставка
preg_replace()Заменяет по регулярному выражениюСложные шаблоны: все цифры, лишние пробелы
<?php
// Сжать любые пробелы и переносы в один пробел
$s = preg_replace('/\s+/u', ' ', "Много   пробелов\n\nи строк");

// Оставить только цифры
$digits = preg_replace('/\D+/', '', 'Тел.: 8-800-555-35-35'); // 88005553535

// Скрыть середину номера: 4111 **** **** 1111
$card = '4111111111111111';
echo substr_replace($card, ' **** **** ', 4, 8);

Флаг u в регулярных выражениях обязателен для кириллицы: без него \s, \w и . работают с байтами, а не с буквами.

Обрезка пробелов и длинных строк

trim() убирает пробелы, табуляции и переносы с обоих краёв, ltrim() - слева, rtrim() - справа. Вторым аргументом можно передать свой набор символов. В PHP 8.4 появились mb_trim(), mb_ltrim() и mb_rtrim(): они понимают многобайтовые пробелы, например неразрывный пробел U+00A0, который часто приходит из Word и с сайтов.

<?php
$name = "  Иван Петров \n";
echo trim($name);              // Иван Петров

echo ltrim('000125', '0');     // 125
echo rtrim('/path/to/dir/', '/'); // /path/to/dir

// PHP 8.4+: уберёт и неразрывные пробелы по краям
echo mb_trim("\u{00A0}Текст\u{00A0}");

Обрезать строку до N символов с многоточием

Для анонсов и карточек товаров текст обрезают по длине. Функция mb_strimwidth() делает это одной строкой, но режет посреди слова. Если важно не рвать слова, отрежьте до последнего пробела:

<?php
$text = 'Подробная инструкция по настройке локального сервера на Windows';

echo mb_strimwidth($text, 0, 30, '...'); // Подробная инструкция по настр...

function excerpt(string $s, int $max): string
{
    if (mb_strlen($s) <= $max) {
        return $s;
    }
    $cut = mb_substr($s, 0, $max);
    $space = mb_strrpos($cut, ' ');
    return rtrim(mb_substr($cut, 0, $space ?: $max), ' ,.;:') . '...';
}

echo excerpt($text, 30); // Подробная инструкция по...

Разбить строку на массив и собрать обратно

Чтобы разбить строку по разделителю, используйте explode(). Третий аргумент ограничивает число частей: положительный - не больше N элементов, отрицательный - отбросить N с конца. Обратная операция - implode(), она склеивает элементы массива в строку.

<?php
$tags = 'php, mysql, laravel , docker';

// Разбить по запятой и убрать пробелы вокруг
$list = array_map('trim', explode(',', $tags));
// ['php', 'mysql', 'laravel', 'docker']

[$key, $value] = explode('=', 'timeout=30=sec', 2); // 'timeout', '30=sec'

echo implode(' | ', $list); // php | mysql | laravel | docker
Пример explode и implode в PHP
explode разбивает строку по разделителю, implode склеивает массив

Когда разделителей несколько или они "плавают", берите preg_split(). Разбить строку на отдельные символы - mb_str_split() (обычная str_split() порежет кириллицу по байтам).

<?php
// Разделители: запятая, точка с запятой или пробелы
$words = preg_split('/[\s,;]+/u', 'кот; пёс,  ёж', -1, PREG_SPLIT_NO_EMPTY);

print_r(mb_str_split('Ёжик'));    // ['Ё', 'ж', 'и', 'к']
print_r(mb_str_split('123456', 2)); // ['12', '34', '56']

Что делать с массивом дальше - фильтровать, сортировать, превращать обратно в строку или JSON, - описано в статье про массивы в PHP.

Перенос строки в тексте

В консоли и файлах перенос делают константой PHP_EOL или символом "\n", на веб-странице - тегом <br>. Разница подробно объяснена в статье про PHP_EOL. Для текста, который пользователь ввёл в <textarea>, есть две полезные функции:

<?php
$comment = "Первая строка\nВторая строка";
// Превратить \n в <br> для вывода в HTML
echo nl2br(htmlspecialchars($comment));

// Перенести длинный текст по 40 символов, не разрывая слова
echo wordwrap('Длинный текст письма без единого переноса', 40, PHP_EOL);

wordwrap() считает байты, поэтому на кириллице строки получаются примерно вдвое короче заданной ширины. Для точного переноса русского текста разбейте строку на слова через explode(' ', ...) и набирайте строки, проверяя mb_strlen().

Как преобразовать строку в число

PHP строку в число переводит приведением типа (int) и (float) или функциями intval() и floatval(). PHP читает число с начала строки и останавливается на первом неподходящем символе. Если строка начинается не с цифры, результат будет 0.

<?php
(int) '42';        // 42
(int) '42 шт.';    // 42 - хвост отброшен
(int) 'шт. 42';    // 0
(float) '3.75';    // 3.75
(float) '3,75';    // 3 - запятая не десятичный разделитель
intval('ff', 16);  // 255 - из шестнадцатеричной

// Цена с запятой и пробелами из формы
$price = (float) str_replace([' ', ','], ['', '.'], '1 250,50'); // 1250.5
Преобразование строки в число в PHP
Приведение строки к числу отбрасывает хвост, запятая обрывает дробь

Для данных от пользователя важно не только преобразовать, но и проверить, что пришло именно число. is_numeric() вернёт true для "12", "-3.5", "1e3", а filter_var() дополнительно проверит диапазон:

<?php
$age = filter_var($_GET['age'] ?? '', FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 1, 'max_range' => 120],
]);

if ($age === false) {
    echo 'Возраст указан неверно';
}

Обратное преобразование - число в строку - делается через (string), интерполяцию или number_format(), если нужны разделители тысяч: number_format(1250.5, 2, ',', ' ') даст "1 250,50".

Регистр и сравнение строк

Функции strtolower(), strtoupper() и ucfirst() с PHP 8.2 работают только с латиницей, независимо от локали. Для русского текста берите многобайтовые версии:

<?php
echo mb_strtoupper('привет');                    // ПРИВЕТ
echo mb_convert_case('иван петров', MB_CASE_TITLE); // Иван Петров
echo mb_ucfirst('москва');                       // Москва (PHP 8.4+)

Сравнение строк в PHP делают строгим оператором ===: он сравнивает и тип, и содержимое. Нестрогий == может сравнивать числовые строки как числа, например '1e3' == '1000' даёт true. Для сортировки и сравнения "больше-меньше" есть отдельные функции:

  • strcmp($a, $b) - возвращает отрицательное число, 0 или положительное, с учётом регистра;
  • strcasecmp($a, $b) - то же без учёта регистра (только латиница);
  • strnatcmp($a, $b) - "естественный" порядок: file2 раньше file10;
  • hash_equals($known, $user) - сравнение токенов и подписей за постоянное время, защищает от атак по времени.

Сравнить кириллические строки без учёта регистра можно так: mb_strtolower($a) === mb_strtolower($b).

Многобайтовые функции mb_ и кодировка UTF-8

Функции mb_* входят в расширение mbstring. На хостингах и в сборках XAMPP и Open Server оно включено, а на чистом Ubuntu его иногда нужно поставить пакетом php8.4-mbstring (номер замените на свою версию PHP). Проверить, подключено ли расширение, можно командой:

php -m | grep -i mbstring
# в Windows: php -m | findstr mbstring

Если команда ничего не вывела, раскомментируйте строку extension=mbstring в php.ini и перезапустите веб-сервер. Где лежит этот файл, рассказано в статье про php.ini. Кодировка по умолчанию для mb-функций - UTF-8, её задаёт директива default_charset.

ЗадачаБайтовая функцияДля UTF-8
Длинаstrlenmb_strlen
Часть строкиsubstrmb_substr
Позицияstrpos, striposmb_strpos, mb_stripos
Регистрstrtolower, ucfirstmb_strtolower, mb_ucfirst
На символыstr_splitmb_str_split
Дополнениеstr_padmb_str_pad (PHP 8.3+)
Обрезка краёвtrimmb_trim (PHP 8.4+)

Функции str_replace(), str_contains(), explode() и implode() работают с UTF-8 правильно и без префикса: они ищут подстроку целиком и не режут символы. Полный перечень строковых функций - в справочнике php.net.

Частые вопросы

Как узнать длину строки в PHP?

Для текста в UTF-8 - mb_strlen($s), она считает символы. strlen() возвращает число байтов, и для кириллицы результат будет вдвое больше.

Как проверить, есть ли подстрока в строке?

В PHP 8 - str_contains($haystack, $needle). В старых версиях - strpos($haystack, $needle) !== false.

Как преобразовать строку в число в PHP?

Приведением (int) $s или (float) $s. Для данных из формы сначала проверьте значение через is_numeric() или filter_var().

Как удалить последний символ строки?
mb_substr($s, 0, -1) удалит любой последний символ, а rtrim($s, ',') - только конкретный, например лишнюю запятую.
Как разбить строку на массив по разделителю?

Функцией explode(',', $s). Если разделителей несколько, используйте preg_split().

Как закомментировать строку в PHP?

Однострочный комментарий начинается с // или #, многострочный заключают в /* */. В VS Code и PhpStorm строку комментирует Ctrl + /.