Символы в PHP строках: методы доступа и практические примеры
Работа с символами строки в PHP
Наиболее эффективное решение для однобайтовых кодировок - доступ через квадратные скобки, для многобайтовых - функции mb_substr или mb_str_split.
Для строк в кодировке ASCII или Windows-1251 (однобайтовые) оператор [] работает быстро и просто. В PHP 7.1 добавлена поддержка отрицательных индексов для доступа с конца строки. Для UTF-8 и других многобайтовых кодировок необходимо использовать расширение mbstring.
$str = 'Пример UTF-8';
// Доступ к первому символу (однобайтовая строка)
echo $str[0]; // выведет 'П' (но это неверно для UTF-8!)
echo mb_substr($str, 0, 1, 'UTF-8'); // 'П' корректно
Php маленькие буквы (преобразование строки в нижний регистр в php)
П
П
Character php (символы php)
Проблема:
Использование $str[0] для UTF-8 строки может вернуть первый байт, а не полный символ. Например, для кириллицы 'П' (2 байта) $str[0] вернет только первый байт - бессмысленный символ. Также при выходе за границы строки PHP 8+ генерирует ValueError, а более ранние версии возвращали пустую строку без предупреждения.
Как получить один символ с помощью substr?
Функция substr возвращает подстроку заданной длины. Для одного символа указывается длина 1. Этот способ работает как с однобайтовыми, так и с многобайтовыми строками (через mb_substr).
$str = 'Hello';
$char = substr($str, 0, 1); // 'H'
$last = substr($str, -1, 1); // 'o'
// Для UTF-8:
$utf8 = 'Привет';
$first = mb_substr($utf8, 0, 1, 'UTF-8'); // 'П'
Php new line (символ новой строки в php)
Возможные сложности:
Если не указать кодировку в mb_substr, используется внутренняя кодировка (может отличаться). Рекомендуется всегда явно передавать параметр encoding.
Как получить массив символов строки с помощью str_split?
str_split разбивает строку на массив по заданному количеству символов. Без второго параметра - по одному байту. Для многобайтовых символов это некорректно.
$str = 'abc';
$arr = str_split($str); // ['a', 'b', 'c']
$utf8 = 'абв';
$arr2 = str_split($utf8); // 6 элементов (каждый байт)
// Корректный способ для UTF-8:
$arr3 = preg_split('//u', $utf8, -1, PREG_SPLIT_NO_EMPTY);
// или mb_str_split в PHP 7.4+
$arr4 = mb_str_split($utf8, 1, 'UTF-8');
Php проверить строку (проверить строку в php)
Проблема:
str_split без указания encoding не учитывает многобайтовость. В результате массив содержит не символы, а байты. Для правильного разбиения используйте mb_str_split или preg_split с модификатором u.
Как извлечь символ с помощью регулярного выражения?
Регулярные выражения позволяют гибко извлекать символы, особенно в многобайтовых строках. Для получения первого символа подходит шаблон /^./u (с модификатором u).
$str = 'Мир';
preg_match('/^./u', $str, $match);
echo $match[0]; // 'М'
Php пробел (удаление пробелов в php)
Недостатки:
Регулярные выражения медленнее прямых функций. Подходят для сложных выборок (например, извлечение всех букв или цифр), но для простого доступа к символу по индексу избыточны.
Как раньше получали символ строки? (устаревший синтаксис)
До PHP 7.4 допускалось использование фигурных скобок: $str{0}. Начиная с PHP 7.4 эта форма помечена как устаревшая, а в PHP 8.0 удалена.
// Пример для очень старых версий
$str = 'PHP';
echo $str{0}; // 'P'
удалить html теги php (php удалить html теги)
Проблема:
Код с фигурными скобками не будет работать в PHP 8+. Необходимо заменить на квадратные скобки.
Как получить последний символ строки?
В PHP 7.1+ для доступа к последнему символу можно использовать отрицательный индекс: $str[-1]. Также подойдёт substr($str, -1, 1) или mb_substr($str, -1, 1, 'UTF-8') для многобайтовых.
$str = 'hello';
echo $str[-1]; // 'o'
echo substr($str, -1); // 'o'
Ошибки при использовании отрицательных индексов:
Если строки начинается с многобайтового символа, $str[-1] вернет только последний байт, что может дать неверный результат. Всегда используйте mb_* функции для UTF-8.
Расширенные примеры работы с символами строк
Пример 1. Доступ к символу по положительному и отрицательному индексу
Код демонстрирует получение первого, третьего и последнего символа строки в однобайтовой кодировке.
$str = 'Пример';
// /!\ Кодировка должна быть однобайтовой (cp1251) или ASCII
echo 'Первый: ' . $str[0] . PHP_EOL;
echo 'Третий: ' . $str[2] . PHP_EOL;
echo 'Последний: ' . $str[-1] . PHP_EOL;
Первый: П
Третий: и
Последний: р
Примечание:
Если строка сохранена в UTF-8, результат будет некорректным. Для UTF-8 используйте mb_substr:
$utf = 'Пример';
echo mb_substr($utf, 0, 1, 'UTF-8'); // П
echo mb_substr($utf, 2, 1, 'UTF-8'); // и
echo mb_substr($utf, -1, 1, 'UTF-8'); // р
Пример 2. Изменение символа в строке
Строки в PHP изменяемы по символу, если новый символ занимает столько же байт, сколько старый. Для однобайтовых строк это безопасно.
$str = 'cat';
$str[0] = 'b';
echo $str; // bat
bat
Для многобайтовых строк прямое присваивание через [] недопустимо, так как символы разной длины. Нужно собрать строку заново:
$str = 'кот';
$chars = mb_str_split($str, 1, 'UTF-8');
$chars[0] = 'с';
$newStr = implode('', $chars);
echo $newStr; // сот
Пример 3. Перебор всех символов строки
Для однобайтовой строки можно использовать foreach по str_split. Для UTF-8 – mb_str_split.
$ascii = 'abc';
foreach (str_split($ascii) as $i => $ch) {
echo "$i: $ch\n";
}
$utf = 'абв';
foreach (mb_str_split($utf, 1, 'UTF-8') as $i => $ch) {
echo "$i: $ch\n";
}
0: a
1: b
2: c
0: а
1: б
2: в
Пример 4. Работа с эмодзи и суррогатными парами
Эмодзи часто занимают 4 байта (суррогатная пара в UTF-16, в UTF-8 – 4 байта). mb_substr корректно обрабатывает их.
$emoji = '?❤️';
echo mb_strlen($emoji, 'UTF-8'); // 2
echo mb_substr($emoji, 0, 1, 'UTF-8'); // ?
echo mb_substr($emoji, 1, 1, 'UTF-8'); // ❤️
2
?
❤️
Пример 5. Байтовое представление с помощью ord и chr
Функция ord возвращает ASCII код символа, chr обратно. Для многобайтовых символов ord вернет код первого байта, что не равно коду символа.
echo ord('A'); // 65
echo chr(65); // A
// Для многобайтового символа:
$char = 'Я';
echo ord($char); // 208 – первый байт
$bytes = unpack('C*', $char);
print_r($bytes); // массив из 2 байт
65
A
208
Array
(
[1] => 208
[2] => 175
)
Пример 6. Сравнение производительности методов доступа
Тест для строки длиной 100000 символов (латиница, однобайтовая) показывает, что квадратные скобки быстрее substr.
$str = str_repeat('a', 100000);
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$ch = $str[50000];
}
echo 'Квадратные скобки: ' . (microtime(true) - $start) . ' сек.' . PHP_EOL;
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$ch = substr($str, 50000, 1);
}
echo 'substr: ' . (microtime(true) - $start) . ' сек.' . PHP_EOL;
Квадратные скобки: ~0.003 сек.
substr: ~0.01 сек.
Пример 7. Извлечение первого символа из каждой строки массива
Полезная задача – получить первые буквы слов.
$words = ['Привет', 'мир', 'из', 'PHP'];
$firstChars = array_map(function($w) {
return mb_substr($w, 0, 1, 'UTF-8');
}, $words);
print_r($firstChars);
Array
(
[0] => П
[1] => м
[2] => и
[3] => P
)