Работа со строками в PHP: основные функции и приёмы
Строки — один из фундаментальных скалярных типов во многих языках программирования, включая PHP. Они представляют текстовые данные: от отдельных символов до целых документов.
Простейшая работа со строками связана с однобайтовым текстом. В таком случае один байт соответствует одному символу, и число байт равно числу символов. ASCII — наиболее распространённая кодировка для однобайтового текста. В core PHP есть много полезных функций для работы с такими строками.
Короткие определения
- ASCII: базовая 7/8-битная кодировка латиницы и служебных символов.
- Unicode: набор символов, охватывающий большинство письменностей мира.
- Кодировка: способ представления символов в байтах (например, UTF-8, ISO-8859-1).
- Многобайтовый символ: символ, представленный в кодировке более чем одним байтом (например, в UTF-8).
Как вывести содержимое строки
Если вы программировали на 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; // 11. Вывод с помощью реальной функции
printf — настоящая функция. Она форматирует строку, заменяя спецпоследовательности, подобно функcii из языка C.
$username = "John";
$length = printf("Hello, %s", $username); // "Hello, John"
echo $length; // 11printf возвращает длину сформированной строки. Это удобно, если нужно знать, сколько символов (байт) заняла строка в текущей кодировке.
2. Получение длины строки
Стандартный способ узнать длину строки в байтах — strlen. Для ASCII число байт равно числу символов.
$length = strlen("Hello, World");
echo $length; // 12Важно: strlen возвращает число байт. Для многобайтовых кодировок (UTF-8) используйте mb_strlen.
3. Извлечение части строки
Частая задача — получить подстроку. В PHP для этого есть substr. Параметры: исходная строка, смещение (offset), длина результата.
$greeting = substr("Hello, World", 0, 5);
echo $greeting; // "Hello"Отсчёт начинается с нуля. PHP позволяет указывать отрицательные значения для offset и length.
$greeting = substr("Hello, World", -5, 5);
echo $greeting; // "World"
$greeting = substr("Hello, World", 0, -6);
echo $greeting; // "Hello,"Для многобайтовых строк используйте mb_substr.
4. Поиск внутри строки
Для поиска позиции подстроки используют strpos. Он возвращает позицию первого вхождения или false, если не найдено.
$pos = strpos("Hello, World", ",");
echo $pos; // 5Важно учитывать тонкость: если подстрока находится в начале строки, strpos вернёт 0, что при нестрогом сравнении (==) воспринимается как false. Всегда проверяйте результат строго (===):
$pos = strpos("Hello", "H");
if ($pos === false) {
echo "Не найдено";
} else {
echo "Найдено в позиции $pos";
}Можно комбинировать strpos и substr для более гибкой выделки.
$string = "Hello, World";
$pos = strpos($string, ",");
$first_part = substr($string, 0, $pos);
echo $first_part; // "Hello"5. Изменение регистра
strtoupper и strtolower меняют регистр символов в ASCII-строках.
$original = "hello, WORLD";
$upper = strtoupper($original);
$lower = strtolower($original);
echo "$lower $upper"; // "hello, world HELLO, WORLD"Для правильно работающего преобразования регистра в Unicode используйте mb_strtoupper и mb_strtolower с указанием кодировки.
6. Удаление пробельных символов
trim убирает ведущие и конечные пробелы, табы и переводы строки.
$trimmed = trim(" Hello, World ");
echo $trimmed; // "Hello, World"Есть также ltrim и rtrim для одностороннего удаления.
7. Разбиение строки по разделителю
explode разделяет строку по разделителю и возвращает массив.
$sentence = "The quick brown fox jumps over the lazy dog";
$words = explode(" ", $sentence);Результат:
[ "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" ]Если разделитель не найден, explode вернёт массив из одного элемента — самой строки.
8. Разбиение на подстроки фиксированной длины
str_split делит строку на элементы заданной длины.
$parts = str_split("Hello, World", 6);$parts:
[ "Hello,", " World" ]Для многобайтового текста используйте mb_str_split (PHP 7.4+ в некоторых сборках или PHP 8.0+), либо реализуйте разбиение вручную с mb_substr в цикле.
9. Поиск и замена
str_replace заменяет все вхождения подстроки на другую строку.
$result = str_replace("o", "OO", "Hello, World");
echo $result; // "HellOO, WOOrld"Для регистрозависимой и регулярной замены существует str_ireplace и preg_replace.
Когда стандартные функции не подойдут
Важно понимать ограничения однобайтовых функций:
- При работе с UTF-8 strlen вернёт байты, а не символы.
- substr и strpos могут разбивать многобайтовые символы посередине.
- strtoupper/strtolower не корректно работают с многобайтовыми буквами.
Если ваш проект работает с не-ASCII (русский, китайский, арабский и т. д.), базовые функции приведут к ошибкам или искажениям.
Альтернативный подход: mbstring и Intl
Для безопасной работы с Unicode используйте расширение mbstring и функции с префиксом mb_:
$len = mb_strlen("Привет, мир", 'UTF-8');
$part = mb_substr("Привет, мир", 0, 6, 'UTF-8');
$upper = mb_strtoupper("привет", 'UTF-8');mbstring учитывает многобайтовые символы и возвращает длину в символах, а не в байтах. Также полезно использовать Normalizer из расширения intl для нормализации Unicode (NFC/NFD), особенно при сравнении пользовательских вводов.
Если mbstring не установлено, установите расширение через менеджер пакетов вашей ОС или включите его в php.ini.
Практическая методология при работе со строками
- Определите ожидаемую кодировку (рекомендуется UTF-8).
- Нормализуйте входящий текст (если нужно) с помощью Normalizer.
- Валидация: проверяйте длину и допустимые символы до сохранения/использования.
- Обработка: используйте mb_* функции для манипуляций с текстом.
- Экранирование: заранее экранируйте строки под целевой контекст (htmlspecialchars для HTML, привязанные параметры для SQL).
- Логируйте корректно: сохраняйте кодировку метаданных.
Чек-лист для разработчика, мейнтенера и ревьювера
Разработчик:
- Проверил кодировку входящих данных.
- Использует mb_* для многобайтовых операций.
- Не полагается на strlen для ограничения символов.
- Экранирует вывод в HTML/JS/SQL.
Мейнтенер:
- Убедился, что mbstring включён и настроен в окружении.
- Настроил логирование в UTF-8.
- Обновил зависимости и провёл тесты с Unicode-данными.
Ревьювер:
- Проверил, используются ли строгие сравнения для strpos.
- Проверил обработку ошибок и граничных случаев.
- Проверил, нет ли функций, разрушающих многобайтовые символы.
Критерии приёмки
- Функции работают с ASCII и Unicode в тестах.
- Нет ошибок при обработке символов с диакритикой и символов эмодзи.
- Тесты покрывают случаи: пустая строка, очень длинная строка, строка только из пробелов, строка с побайт-ошибками.
- Логи и база хранят данные в UTF-8.
Безопасность и конфиденциальность
- Никогда не подставляйте необработанные строки пользователя в HTML без htmlspecialchars.
- Для SQL используйте подготовленные выражения, а не конкатенацию.
- Будьте осторожны при логировании конфиденциальных полей: телефон, email, персональные данные — маскируйте.
Важно: неправильное экранирование строк — частая причина XSS и SQL-инъекций.
Советы по отладки и тестированию
- Тестируйте функции на наборе строк: ASCII, русские символы, CJK, эмодзи.
- Проверяйте поведение функций с краевыми параметрами (offset равен длине строки, отрицательные значения, пустые строки).
- Используйте php -l для проверки синтаксиса и phpunit для функциональных тестов.
Примеры тест-кейсов:
- strlen и mb_strlen на одной и той же строке с UTF-8: ожидаемо разные значения.
- strpos для поиска в начале строки: должно возвращаться 0, и проверка должна быть === false.
- substr с отрицательной длиной: возвращает строку без указанных символов в конце.
Факты и ориентиры
- Встроенных строковых функций в PHP примерно сто. Это покрывает базовые операции, регулярки, кодировки и потоки.
- Рекомендуется хранить все текстовые данные в базе в кодировке UTF-8.
- mbstring — стандартное расширение для работы с многобайтовыми кодировками.
Когда это не работает: примеры ошибок и как их исправить
- Символы «ломаются» после substr: используйте mb_substr с ‘UTF-8’.
- strlen возвращает больше, чем ожидается: вы считали байты, а не символы — используйте mb_strlen.
- strpos возвращает 0 и вы считаете это false: замените сравнение на === false.
Короткая методичка по миграции на Unicode
- Проверьте кодовую страницу базы данных и таблиц; смените на utf8mb4/utf8mb4_unicode_ci.
- Убедитесь, что PHP и веб-сервер используют UTF-8 (заголовки Content-Type, meta charset).
- Включите mbstring и установите mb_internal_encoding(‘UTF-8’).
- Прогоните тесты: ввод/вывод, сортировка, поиск, длина.
Краткая цитата эксперта
“Всегда учитывайте кодировку при работе со строками — это сэкономит время и предотвратит ошибки.” — инженер по разработке ПО
Итог
Строки в PHP просты для базовых задач с ASCII. Но современное программирование почти всегда требует поддержки Unicode. Применяйте mbstring и нормализацию, контролируйте контекст вывода и используйте строгие проверки. Это снизит количество ошибок и упростит поддержку.
Важно: если вы работаете с текстом в вебе, всегда думайте о безопасности (XSS, SQL) и правильной кодировке данных.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone