Работа со строками в PHP: базовые функции, примеры и лучшие практики

Что такое строки в PHP
Строки — один из фундаментальных скалярных типов во многих языках программирования, включая PHP. Они представляют текстовые данные: от отдельных символов до целых документов.
Простейшая модель строки — однобайтовый текст, где каждый байт соответствует одному символу (до 256 символов). ASCII — самый распространённый набор для таких строк. Для многобайтовых кодировок (UTF-8 и т. п.) используйте расширение mbstring — стандартные функции работают с байтами, а не с символами.
Определение: строка — последовательность байтов, представляющая текстовую информацию. Для многобайтовых кодировок «символ» и «байт» не эквивалентны.
Important: далее в статье все примеры стандартных функций ориентированы на однобайтовые строки (ASCII). Для Unicode смотрите раздел “Когда стандартные функции не подходят”.
Как показать содержимое строки
В PHP часто используются конструкты языка для вывода текста. Хотя echo выглядит как функция, это — конструкция языка. Поэтому её нельзя всегда использовать там, где ожидается функция.
Обычно используют так:
echo "Hello, world";Можно записать с круглыми скобками, внешне похоже на вызов функции:
echo("Hello, world");Но это всё ещё не функция: нельзя присвоить её возвращаемое значение:
$a = echo("Hello, world");
// Parse error: syntax error, unexpected 'echo' (T_ECHO)Другой вариант — print. Это тоже не чистая функция, но ближе к функции, и она возвращает значение (всегда 1), которое можно присвоить:
print "Hello, world";
$a = print("Hello, world");
echo $a; // 1Настоящая функция для форматированного вывода
printf — реальная функция, похожая на функцию из C: она форматирует строку и возвращает длину сформированного текста.
$username = "John";
$length = printf("Hello, %s", $username); // выводит "Hello, John"
echo $length; // 11printf полезна, когда нужно вычислить длину результата форматирования (например, для размещения в интерфейсе командной строки).
Получение длины строки
Для определения длины строки в байтах используется strlen:
$length = strlen("Hello, World");
echo $length; // 12Важно: для ASCII число байтов равно числу символов. Для UTF-8 и других многобайтовых кодировок используйте mb_strlen.
Извлечение части строки
Частая задача — взять подстроку. Функция substr извлекает часть строки по смещению и длине:
$greeting = substr("Hello, World", 0, 5);
echo $greeting; // "Hello"Отсчёт смещений в PHP начинается с 0. Второй параметр — длина результата (не индекс конца).
Поддерживаются отрицательные значения для offset и length:
$greeting = substr("Hello, World", -5, 5);
echo $greeting; // "World"
$greeting = substr("Hello, World", 0, -6);
echo $greeting; // "Hello,"Поиск в строке
Для поиска позиции подстроки используется strpos:
$pos = strpos("Hello, World", ",");
echo $pos; // 5Можно сочетать strpos и substr, чтобы извлечь часть строки до найденного разделителя:
$string = "Hello, World";
$pos = strpos($string, ",");
$first_part = substr($string, 0, $pos);
echo $first_part; // "Hello"Изменение регистра
Для ASCII-строк есть strtoupper и strtolower:
$original = "hello, WORLD";
$upper = strtoupper($original);
$lower = strtolower($original);
echo "$lower $upper"; // "hello, world HELLO, WORLD"Для языков с многобайтовыми символами используйте mb_strtoupper и mb_strtolower с указанием кодировки.
Удаление пробелов
trim удаляет пробелы, табы и новые строки с начала и конца строки:
$trimmed = trim(" Hello, World ");
echo $trimmed; // "Hello, World"Также есть ltrim и rtrim для удаления только слева или справа.
Разбиение строки по разделителю
explode разделяет строку на массив по заданной подстроке:
$sentence = "The quick brown fox jumps over the lazy dog";
$words = explode(" ", $sentence);Результат:
[ "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" ]Разбиение на фрагменты фиксированной длины
str_split делит строку на массив фрагментов фиксированной длины:
$parts = str_split("Hello, World", 6);Результат:
[ "Hello,", " World" ]Поиск и замена
str_replace заменяет вхождения одной строки на другую:
$result = str_replace("o", "OO", "Hello, World");
echo $result; // "HellOO, WOOrld"Есть также str_ireplace (без учёта регистра) и preg_replace (по регулярному выражению).
Когда стандартные функции не подходят
Ключевая проблема стандартных функций PHP в том, что они работают с байтами. При работе с Unicode (UTF-8) поведение будет некорректным: длина, поиск и извлечение могут давать неверные результаты. Примеры проблем:
- strlen(“Привет”) вернёт количество байтов, а не символов;
- substr может разрезать многобайтовый символ посередине, оставив некорректную строку;
- strtoupper/strtolower не поддерживают языковые особенности Unicode.
Альтернатива: расширение mbstring. Основные аналоги функций для многобайтовых строк:
mb_strlen($str, 'UTF-8');
mb_substr($str, $start, $length, 'UTF-8');
mb_strpos($str, $needle, 0, 'UTF-8');
mb_strtoupper($str, 'UTF-8');Всегда указывайте кодировку (чаще всего ‘UTF-8’).
Практические советы и эвристики
- Всегда знайте, в какой кодировке хранится строка. Если проект использует UTF-8, применяйте mb-версии функций.
- Для вывода в HTML экранируйте содержимое через htmlspecialchars.
- Для SQL-запросов используйте параметризованные запросы или экранирование в рамках используемой библиотеки.
- Для больших объёмов текстовой обработки избегайте частых конкатенаций строк в цикле — используйте буферизацию или сбор в массив, затем implode.
Ментальная модель: «байты против символов» — стандартные функции работают с байтами. Префикс mb превращает байтовую операцию в символьную с учётом кодировки.
Безопасность: обработка пользовательского ввода
- Для HTML-вывода: htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, ‘UTF-8’).
- Для JSON: json_encode корректно сериализует строки.
- Для командной строки: защищайте от инъекций при передаче в оболочку.
Security note: регулярные выражения и некоторые функции могут быть уязвимы к DoS через «catastrophic backtracking» — проверяйте сложность регулярных выражений и используйте ограничители длины.
Чек-листы по ролям
Разработчик:
- Проверить кодировку входных данных.
- Использовать mb-версии при UTF-8.
- Экранировать вывод в HTML/SQL/командной строке.
- Писать юнит-тесты для граничных случаев (многобайтовые символы, пустые строки, null).
QA:
- Тесты на корректность длины и подстрок для разных языков.
- Проверить поведение при некорректной кодировке.
- Нагрузочное тестирование парсеров и регулярных выражений.
Архитектор:
- Выбрать единую кодировку (рекомендуется UTF-8) и зафиксировать её в конфигурации.
- Убедиться, что все зависимости (база, файловая система, внешние API) работают в той же кодировке.
Шпаргалка по функциям (cheat sheet)
| Задача | Функция | Примечание |
|---|---|---|
| Вывод | echo / print | echo — конструкция, print возвращает 1 |
| Форматированный вывод | printf | Возвращает длину сформатированной строки |
| Длина строки (байты) | strlen | Для ASCII OK |
| Длина строки (символы UTF-8) | mb_strlen | Укажите кодировку |
| Подстрока | substr | Работает с байтами |
| Подстрока UTF-8 | mb_substr | Укажите кодировку |
| Поиск | strpos | Возвращает позицию в байтах |
| Поиск UTF-8 | mb_strpos | |
| Приведение регистра | strtoupper / strtolower | Для ASCII |
| Приведение регистра UTF-8 | mb_strtoupper / mb_strtolower | |
| Разбиение по разделителю | explode | |
| Разбиение по длине | str_split | |
| Замена | str_replace / str_ireplace | |
| Замена по regex | preg_replace | Используйте осторожно |
| Удаление пробелов | trim / ltrim / rtrim |
Советы по тестированию и критерии приёмки
Критерии приёмки для функций обработки строк:
- Корректная обработка ASCII-тестов (латиница, цифры, знаки).
- Корректная обработка UTF-8-тестов (кириллица, китайские иероглифы, эмодзи).
- Отсутствие некорректных символов после substr/mb_substr.
- Безопасный вывод в HTML и корректное экранирование кавычек.
- Юнит-тесты покрывают граничные случаи: пустая строка, null, очень длинные строки, символы со смешанной кодировкой.
Примеры тест-кейсов:
- strlen(‘Привет’) != mb_strlen(‘Привет’, ‘UTF-8’)
- mb_substr(‘😊abc’, 0, 2, ‘UTF-8’) возвращает первые два символа корректно
- str_replace заменяет все вхождения в ожидаемых позициях
Совместимость и миграция
- Начиная с PHP 7 поведение функций осталось совместимым, но рекомендуется мигрировать проекты на UTF-8, чтобы избежать проблем с интернационализацией.
- Для миграции: установить кодировку базы и HTTP заголовки в UTF-8, включить mbstring и проходом проверить критические функции.
Факт-бокс: часто используемые функции
- Количество встроенных строковых функций в PHP — около ста; среди наиболее часто используемых: strlen, substr, strpos, str_replace, explode, implode, trim, strtoupper, strtolower.
Примеры на практике
Пример: безопасная обработка входной строки пользователя и подсчёт символов в UTF-8:
$input = $_POST['comment'] ?? '';
$input = trim($input);
$safe = htmlspecialchars($input, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$chars = mb_strlen($input, 'UTF-8');
echo "Длина комментария: $chars символов";Пример: разбор CSV-поля в простом случае:
$line = "value1,value2,значение3";
$parts = explode(",", $line);
// Обработка каждого элемента как UTF-8 при необходимости
foreach ($parts as $p) {
$p = trim($p);
// дальнейшая обработка
}Резюме
- Для простого ASCII достаточно стандартных функций PHP.
- Для Unicode используйте mbstring-функции и явно указывайте кодировку (обычно UTF-8).
- Всегда экранируйте пользовательский ввод в зависимости от места вывода (HTML, SQL, shell).
- Пишите тесты на крайние случаи и фиксируйте единую кодировку для проекта.
Notes: если проект работает с мультиязычным контентом, миграция на UTF-8 и аудит использования обычных строковых функций — приоритетная задача.
Похожие материалы
Доступ к заблокированному контенту на Android
Резервное копирование Mac — Time Machine и iCloud
Уменьшение шума вентилятора ноутбука
Как фильтровать теги и посты в Tumblr
Как не попасться на мошенничество в Black Friday