Строки в PHP: кавычки, echo, функции и работа с UTF-8

Строка PHP в одинарных и двойных кавычках Программирование и разработка

Строки в PHP записывают в одинарных или двойных кавычках, выводят через echo, склеивают точкой и обрабатывают строковыми функциями. Внутри строка хранится как набор байтов, и стандартные строковые функции считают байты, а не символы. Символ кириллицы в UTF-8 занимает 2 байта, эмодзи 😀 4 байта, поэтому для русского текста нужны варианты функций с приставкой mb_.

Код рассчитан на PHP 8.3 и новее, вывод получен запуском на PHP 8.3.12.

Создание строки: одинарные и двойные кавычки

В одинарных кавычках PHP оставляет текст как есть, особый смысл там имеют только \' и \\. В двойных интерпретатор подставляет значения переменных и превращает управляющие последовательности вроде \n в специальные символы.

<?php
$name = 'Анна';
echo 'Привет, $name!\n';
echo "\n";
echo "Привет, $name!\n";
echo 'It\'s PHP', "\n";
Привет, $name!\n
Привет, Анна!
It's PHP

Первая строка вывода показала $name и \n буквально, во второй PHP подставил значение переменной. Текст без переменных удобнее заключить в одинарные кавычки: не нужно экранировать знак доллара. На скорость выбор не влияет, строка без переменных в любых кавычках ещё при компиляции превращается в одну и ту же константу.

Переменные внутри строки

Имя переменной PHP находит по знаку доллара. В простом синтаксисе ключ элемента массива пишут без кавычек: "$user[name]". В сложном синтаксисе выражение заключают в фигурные скобки, и знак доллара идёт сразу за открывающей скобкой.

<?php
$user = ['name' => 'Анна', 'city' => 'Казань'];
$count = 3;
echo "Имя: $user[name]\n";
echo "Город: {$user['city']}\n";
echo "Заказов: {$count}шт.\n";
echo "Заказов: $countшт.\n";
Имя: Анна
Город: Казань
Заказов: 3шт.

Warning: Undefined variable $countшт in ... on line 7
Заказов: .

Последняя строка сломалась из-за русских букв. PHP разрешает в имени переменной любые байты с кодом больше 127, а символы «ш» и «т» в UTF-8 состоят как раз из таких байтов. Интерпретатор прочитал $countшт как имя другой переменной и подставил пустую строку. Фигурные скобки строкой выше отделяют имя переменной от текста.

Запись ${name} в PHP 8.2 объявлена устаревшей и выдаёт Deprecated: Using ${var} in strings is deprecated, use {$var} instead, использовать её в новом коде не стоит. Константы внутри строки не подставляются: "Версия: PHP_VERSION" так и выведет слово PHP_VERSION. Их присоединяют точкой: 'Версия: ' . PHP_VERSION.

Управляющие последовательности и перенос строки

Управляющие последовательности записывают специальные символы и работают только в двойных кавычках и heredoc.

Последовательность Что означает
\n перевод строки (LF)
\r возврат каретки (CR)
\t символ горизонтальной табуляции
\\ обратный слеш
\$ знак доллара
\" двойная кавычка
\u{1F600} символ Юникода по его коду, здесь эмодзи 😀

Символ \n переносит текст на новую строку в консоли и текстовом файле, а браузер его не показывает: в HTML для переноса используют тег <br>. Функция nl2br() преобразует каждый перевод строки в такой тег:

<?php
$text = "Первая строка\nВторая строка";
echo nl2br($text);
Первая строка<br />
Вторая строка

Константа PHP_EOL хранит перевод строки системы, где работает скрипт: \n в Linux, \r\n в Windows.

Читайте также:  Задача «Фруктовый салат» на Python: решение и разбор ошибок

Heredoc и nowdoc

Для многострочного текста используется heredoc-синтаксис: после <<< идёт идентификатор, затем текст, а закрывающий идентификатор стоит на отдельной строке. Heredoc подставляет значения переменных, как двойные кавычки. Nowdoc с идентификатором в одинарных кавычках переменные не обрабатывает.

<?php
$name = 'Анна';
$letter = <<<TEXT
    Здравствуйте, $name!
    Заказ готов.
    TEXT;
echo $letter, "\n";

$template = <<<'TEXT'
    Здравствуйте, $name!
    TEXT;
echo $template, "\n";
Здравствуйте, Анна!
Заказ готов.
Здравствуйте, $name!

В PHP 7.3 и новее закрывающий идентификатор можно сдвинуть отступом, и PHP уберёт столько же пробелов из каждой строки. Раньше он должен был стоять в первой колонке.

Вывод строки: echo, print и printf

echo и print относятся к конструкциям языка, скобки им не нужны. echo принимает несколько аргументов через запятую, print берёт один и возвращает 1. printf() выводит строку по шаблону, sprintf() возвращает результат без вывода.

<?php
$price = 1250.5;
echo 'Итого: ', $price, "\n";
print 'Итого: ' . $price . "\n";
printf("Итого: %.2f руб.\n", $price);
echo sprintf('%05d', 42), "\n";
Итого: 1250.5
Итого: 1250.5
Итого: 1250.50 руб.
00042

%.2f оставляет два знака после точки, %05d дополняет целое число нулями до пяти цифр.

Текст от пользователя перед выводом в HTML пропускают через htmlspecialchars(): теги вроде <b> превратятся в &lt;b&gt;, и браузер покажет их как текст.

Конкатенация строк

Строки склеивают с помощью оператора «точка», оператор .= дописывает текст в конец переменной.

<?php
$first = 'Иван';
$last = 'Петров';
$full = $first . ' ' . $last;
$full .= ', PHP-разработчик';
echo $full, "\n";

$a = 2;
$b = 3;
echo 'Сумма: ' . $a + $b, "\n";
Иван Петров, PHP-разработчик
Сумма: 5

В PHP 7.4 последняя строка печатала 3 с предупреждением A non-numeric value encountered, а при включённом E_DEPRECATED ещё и Deprecated о смене приоритета в PHP 8. Точка и плюс тогда имели одинаковый приоритет, и PHP прибавлял 3 к тексту 'Сумма: 2'. В PHP 8 сложение выполняется раньше, но скобки 'Сумма: ' . ($a + $b) мы бы ставили в любой версии.

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

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

<?php
$text = 'Строка';
echo strlen($text), ' ', mb_strlen($text), "\n";
echo strlen('😀'), ' ', mb_strlen('😀'), "\n";
echo mb_strlen(str_replace(' ', '', 'Строки в PHP')), "\n";
echo str_word_count('Строки в PHP'), "\n";
echo count(preg_split('/\s+/u', trim('Строки в PHP'))), "\n";
12 6
4 1
10
1
3

Строка из шести символов и двенадцати байтов

Третья строка считает символы без пробелов. Четвёртая показывает ошибку: функция str_word_count() считает словом только латинские буквы и нашла одно слово из трёх, поэтому слова в русском тексте считают через preg_split() с флагом u.

Функции mb_ входят в расширение mbstring. Если оно не подключено, скрипт упадёт с ошибкой Call to undefined function mb_strlen(), в Windows его подключают строкой extension=mbstring в php.ini.

Доступ к символам строки

К символу обращаются по индексу в квадратных скобках, первый символ имеет индекс 0. С PHP 7.1 работают отрицательные индексы: -1 означает последний символ.

<?php
$code = 'PHP8';
echo $code[0], $code[-1], "\n";
$text = 'Строка';
echo bin2hex($text[0]), "\n";
echo mb_substr($text, 0, 1), mb_substr($text, -1), "\n";
echo $code[10];
P8
d0
Са

Warning: Uninitialized string offset 10 in ... on line 7

$text[0] вернул один байт d0, половину символа «С», на странице он превратится в знак �.

Читайте также:  Полное руководство по использованию класса Event Trigger в программировании

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

strpos() возвращает позицию первого вхождения подстроки или false. Позиция в начале строки равна 0, а 0 в условии if считается ложью:

<?php
$email = 'admin@example.com';

if (strpos($email, 'admin')) {
    echo 'нашли', "\n";
} else {
    echo 'не нашли', "\n";
}

if (strpos($email, 'admin') !== false) {
    echo 'нашли', "\n";
}

echo strpos('Строка в PHP', 'PHP'), ' ', mb_strpos('Строка в PHP', 'PHP'), "\n";
не нашли
нашли
16 9

Первое условие не сработало, хотя подстрока есть, поэтому результат strpos() следует сравнивать строго: !== false. В русском тексте позицию даёт mb_strpos(): strpos() насчитала 16 байтов, а символов перед словом PHP всего 9. strrpos() ищет последнее вхождение, stripos() не учитывает регистр, substr_count() считает вхождения.

Начиная с PHP 8.0 для проверки лучше использовать три функции:

Функция Что проверяет Пример Результат
str_contains() есть ли подстрока str_contains($email, '@') true
str_starts_with() начало строки str_starts_with($email, 'admin') true
str_ends_with() конец строки str_ends_with($email, '.ru') false

С пустой подстрокой str_contains($email, '') тоже вернёт true, поскольку пустая строка содержится в любой. Поле формы проверяйте на пустоту заранее.

Извлечение подстроки

substr($string, $offset, $length) возвращает часть строки, отрицательное начало отсчитывает байты с конца. strstr() отдаёт часть от первого вхождения подстроки, а с третьим аргументом true часть до него.

<?php
$file = 'report-2026.pdf';
echo substr($file, 0, 6), ' ', substr($file, -3), "\n";
echo strstr($file, '-'), ' ', strstr($file, '.', true), "\n";
echo mb_substr('Строка в PHP', 0, 6), "\n";
var_dump(json_encode(substr('Строка', 0, 3)));
report pdf
-2026.pdf report-2026
Строка
bool(false)

substr('Строка', 0, 3) отрезал символ «С» и половину «т». Такая строка перестала быть корректным UTF-8, и json_encode() вернул false с ошибкой Malformed UTF-8 characters. Ошибка всплывает далеко от места обрезки, поэтому русский текст режьте только mb_substr().

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

str_replace() заменяет все вхождения и принимает массивы: первый элемент поиска меняется на первый элемент замены, второй на второй. Четвёртый аргумент получает количество замен.

<?php
$text = 'Цена: 100 руб., доставка: 300 руб.';
echo str_replace('руб.', '₽', $text, $count), "\n";
echo "Замен: $count", "\n";
echo str_replace(['Цена', 'доставка'], ['Товар', 'курьер'], $text), "\n";
echo substr_replace('+79991234567', '*****', 5, 5), "\n";
Цена: 100 ₽, доставка: 300 ₽
Замен: 2
Товар: 100 руб., курьер: 300 руб.
+7999*****67
Функция Что делает
substr_replace() меняет кусок по позиции и длине
str_ireplace() заменяет без учёта регистра
preg_replace() заменяет по регулярному выражению

Регистр букв

strtoupper(), strtolower() и ucfirst() меняют только латиницу: начиная с PHP 8.2 они не зависят от setlocale().

<?php
function mbUcfirst(string $text): string
{
    return mb_strtoupper(mb_substr($text, 0, 1)) . mb_substr($text, 1);
}

$title = 'строки в php';
echo strtoupper($title), "\n";
echo mb_strtoupper($title), "\n";
echo ucfirst($title), "\n";
echo mbUcfirst($title), "\n";
echo mb_convert_case('иван петров', MB_CASE_TITLE), "\n";
строки в PHP
СТРОКИ В PHP
строки в php
Строки в php
Иван Петров

Русские буквы переводят в верхний и нижний регистр mb_strtoupper() и mb_strtolower(), каждое слово с заглавной буквы делает mb_convert_case(). Функция mb_ucfirst() появилась только в PHP 8.4, до неё можно использовать mbUcfirst() из примера.

Удаление пробелов: trim, ltrim и rtrim

trim() убирает пробельные символы с обоих концов строки, ltrim() только в начале, rtrim() в конце. По умолчанию функции снимают следующие символы: пробел, \t, \n, \r, \v и нулевой байт \0. Вторым аргументом передают свой набор символов.

<?php
$input = "  user@example.com \n";
echo '[', trim($input), ']', "\n";
echo rtrim('1,2,3,', ','), ' ', ltrim('0042', '0'), "\n";

$cell = "\u{00A0}100 руб.\u{00A0}";
echo '[', trim($cell), ']', "\n";
echo '[', preg_replace('/^\s+|\s+$/u', '', $cell), ']', "\n";
[user@example.com]
1,2,3 42
[ 100 руб. ]
[100 руб.]

Неразрывный пробел U+00A0 (в HTML &nbsp;) в этот список не входит. Его снимает регулярное выражение с флагом u или mb_trim() из PHP 8.4.

Читайте также:  Что такое CORS: как работает и как исправить ошибку CORS

Строка в массив и массив в строку

explode() разбивает строку по разделителю и возвращает части в виде массива, implode() собирает элементы массива в строку. Массив, переданный в echo напрямую, превращается в слово Array с предупреждением.

<?php
$tags = ['php', 'строки', 'echo'];
echo $tags, "\n";
echo implode(', ', $tags), "\n";
echo json_encode($tags, JSON_UNESCAPED_UNICODE), "\n";
print_r(explode(';', 'яблоко;груша;;слива'));
Warning: Array to string conversion in ... on line 3
Array
php, строки, echo
["php","строки","echo"]
Array
(
    [0] => яблоко
    [1] => груша
    [2] => 
    [3] => слива
)

Строка и массив: explode и implode

Пустой элемент с индексом 2 дали две точки с запятой подряд. Третий аргумент explode() ограничивает число частей. С пустым разделителем explode() выбрасывает исключение ValueError: explode(): Argument #1 ($separator) cannot be empty. Флаг JSON_UNESCAPED_UNICODE в json_encode() оставляет кириллицу читаемой, без него получатся последовательности вида \u0441.

Преобразование строки в число и обратно

Приведение (int) берёт число из начала строки, а строка, которая начинается не с цифры, даёт 0. is_numeric() проверяет, что значение переменной целиком число.

<?php
echo (int) '42abc', ' ', (int) 'abc', ' ', intval('1A', 16), "\n";
var_dump(is_numeric('42'), is_numeric('42abc'));
echo '42abc' + 8, "\n";
var_dump(strval(1250));
42 0 26
bool(true)
bool(false)

Warning: A non-numeric value encountered in ... on line 4
50
string(4) "1250"

strval() и приведение (string) переводят число в строку. Арифметические операции со строкой без цифр в начале в PHP 8 падают: 'abc' + 8 выбрасывает TypeError: Unsupported operand types: string + int. Изменения коснулись и сравнения строки с числом:

Выражение PHP 7.4 PHP 8
'abc' == 0 true false
'' == 0 true false

Две числовые строки оператор == по-прежнему сравнивает как числа, поэтому '1e3' и '1000' для него равны. Строки мы бы сравнивали через ===, он проверяет и тип, и каждый символ. Порядок по алфавиту показывает strcmp(): 0 для равных строк, отрицательное число, если первая идёт раньше. Для кириллицы байтовый порядок не годится: strcmp('ёж', 'яма') больше нуля, и sort() поставит «ёж» после «ямы». Алфавитный порядок даёт класс Collator из расширения intl.

Байтовые функции и их mb_-пары

Задача Функция для байтов Для UTF-8 PHP
длина, часть строки, позиция, регистр strlen(), substr(), strpos(), strtolower() mb_strlen(), mb_substr(), mb_strpos(), mb_strtolower() любой с mbstring
разбить на символы str_split() mb_str_split() 7.4+
дополнить до длины str_pad() mb_str_pad() 8.3+
первая буква заглавная ucfirst() mb_ucfirst() 8.4+
пробелы по краям trim() mb_trim() 8.4+
перевернуть, посчитать слова strrev(), str_word_count() не существует

str_pad('Итог', 10, '.') вернёт «Итог..», потому что слово уже занимает 8 байтов, а mb_str_pad() даст «Итог……». Русскую строку переворачивают так: implode('', array_reverse(mb_str_split($s))).

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

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

Поставьте в начале строки // или #, несколько строк закомментируют /* и */. Однострочный комментарий действует до конца строки или до закрывающего тега ?>, поэтому HTML после ?> выведется. В PHP 8 строка, которая начинается с #[, считается атрибутом, так что надёжнее //.

Как проверить, что строка пустая?

Сравните переменную с пустой строкой: $s === ''. Функция empty() для ввода пользователя не подходит, строку '0' она тоже считает пустой. Строку из одних пробелов сначала пропустите через trim().

Оцените статью
bestprogrammer.ru
Добавить комментарий