Строка (string) — набор символов, в котором символ — то же, что и байт. PHP поддерживает набор только из 256 символов и поэтому внутренне не поддерживает кодировку Unicode. Подробнее об этом рассказывает раздел «Подробные сведения о строковом типе».
Замечание: В 32-битных сборках размер строки (string) ограничивается 2 ГБ — максимум 2 147 483 647 байтов.
Строковый литерал определяют четырьмя способами:
Простейший способ определить строку — заключить строку в одинарные кавычки —
символ '
.
Буквальную одинарную кавычку при записи в строке экранируют обратным
слешем — \
. Сам обратный слеш дублируют —
\\
. В остальных случаях обратный слеш в одинарных кавычках
обрабатывется как буквальный обратный слеш: PHP не рассматривает последовательности
вроде \r
или \n
в одинарных кавычках как управляющие,
а выводит как записали.
Замечание: Переменные и управляющие последовательности служебных символов в одинарных кавычках не обрабатываются, в отличие от синтаксиса двойных кавычек и heredoc.
<?php
echo 'Это — простая строка';
echo 'В строки также разрешено вставлять
символ новой строки, способом, которым записан этот текст, —
так делать нормально';
// Выводит: Однажды Арнольд сказал: "I'll be back"
echo 'Однажды Арнольд сказал: "I\'ll be back"';
// Выводит: Вы удалили C:\*.*?
echo 'Вы удалили C:\\*.*?';
// Выводит: Вы удалили C:\*.*?
echo 'Вы удалили C:\*.*?';
// Выводит: Это не будет развёрнуто: \n в новую строку
echo 'Это не будет развёрнуто: \n в новую строку';
// Выводит: Переменные $expand и $either также не разворачиваются
echo 'Переменные $expand и $either также не разворачиваются';
?>
PHP распознает следующие управляющие последовательности служебных символов,
если строку заключили в двойные кавычки — "
:
Последовательность | Значение |
---|---|
\n |
новая строка (LF или 0x0A (10) в ASCII) |
\r |
возврат каретки (CR или 0x0D (13) в ASCII) |
\t |
горизонтальная табуляция (HT или 0x09 (9) в ASCII) |
\v |
вертикальная табуляция (VT или 0x0B (11) в ASCII) |
\e |
escape-знак (ESC или 0x1B (27) в ASCII) |
\f |
подача страницы (FF или 0x0C (12) в ASCII) |
\\ |
обратная косая черта |
\$ |
знак доллара |
\" |
двойная кавычка |
\[0-7]{1,3} |
Восьмеричная запись: символ, код которого записали в восьмеричной нотации (т. е. "\101" === "A" ),
т. е. в виде последовательности символов, которая соответствует регулярному выражению [0-7]{1,3} .
В ситуации целочисленного переполнения (если символ не поместится в один байт),
старшие биты будут без предупреждения отброшены (т. е. "\400" === "\000" )
|
\x[0-9A-Fa-f]{1,2} |
Шестнадцатеричная система счисления: символ, код которого записали
в шестнадцатеричной нотации (т. е. "\x41" === "A" ),
т. е. в виде последовательности символов, которая соответствует
регулярному выражению [0-9A-Fa-f]{1,2}
|
\u{[0-9A-Fa-f]+} |
Стандарт Unicode: символ, код которого записали в нотации кодовых точек Unicode,
т. е. в виде последовательности символов, которая соответствует
регулярному выражению [0-9A-Fa-f]+ ,
которые будут отображены как строка в кодировке UTF-8.
Последовательность необходимо заключать в фигурные скобки.
Например: "\u{41}" === "A"
|
Как и в строках в одинарных кавычках, экранирование другого символа выведет также и символ обратного слеша.
Наиболее важное свойство строк в двойных кавычках состоит в том, что имена переменных в них развёрнутся и обработаются. Подробнее об этом рассказывает раздел «Интерполяция строк».
Третий способ определения строк — heredoc-синтаксис:
<<<
. Следом за этим оператором указывают идентификатор,
а затем перевод строки. Затем идёт сама строка, за которой снова идёт тот же идентификатор,
чтобы закрыть вставку.
Закрывающий идентификатор разрешается отбивать пробелами или символами табуляции, и тогда отступ удалится из каждой строки в блоке документа. До PHP 7.3.0 закрывающий идентификатор указывали в самом начале новой строки.
Кроме того, закрывающий идентификатор подчиняется тем же правилам именования, что и другие метки в PHP: содержит только буквенно-цифровые символы и подчёркивания, и не начинается с цифрового символа или символа подчёркивания.
Пример #1 Базовый пример heredoc-синтаксиса в PHP 7.3.0
<?php
// Без отступа перед маркером закрытия
echo <<<END
a
b
c
\n
END;
// Отступ в 4 пробела перед маркером закрытия
echo <<<END
a
b
c
END;
?>
Результат выполнения приведённого примера в PHP 7.3:
a b c a b c
PHP выбросит исключение ParseError, если закрывающий идентификатор сместили дальше хотя бы одной строки тела:
Пример #2 Идентификатору закрытия нельзя отступать дальше строк тела
<?php
echo <<<END
a
b
c
END;
?>
Результат выполнения приведённого примера в PHP 7.3:
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4
В теле и перед идентификатором окончания heredoc-блока разрешается делать отступы символами пробелов и табуляции, но нельзя смешивать символы табуляции и пробелы относительно отступа идентификатора закрытия и отступа тела до начала закрывающего идентификатора; heredoc-синтаксис будет работать с отступом перед маркером закрытия, только если каждая строка тела начинается, но не ограничивается, с того же отступа, что и отступ перед маркером закрытия. При несовпадении отступов в начале строк тела с отступом перед идентификатором закрытия PHP выбросит исключение ParseError. Ограничения на пробельные отступы добавили, потому что смешивание табуляций и пробелов для отступов вредно для разбора.
Пример #3 Пример несовпадения отступов в теле и перед идентификатором закрытия тела
<?php
/**
* Каждый следующий пример кода не работает
*/
// Отступ тела отличается от отступа маркера окончания:
// тело — 5 пробелов, маркер окончания — 2 символа табуляции
{
echo <<<END
a
END;
}
// Смешивание пробелов и табуляций в теле:
// тело — 4 пробела + 1 символ табуляции, маркер окончания — 5 пробелов
{
echo <<<END
a
END;
}
// Смешивание пробелов и табуляций в маркере окончания:
// тело — 10 пробелов, маркер окончания — 2 символа табуляции + 1 пробел
{
echo <<<END
a
END;
}
?>
Результат выполнения приведённого примера в PHP 7.3:
PHP Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8
За идентификатором закрытия строки тела не обязательно ставить точку с запятой или новую строку. Приведём пример кода, который разрешается с PHP 7.3.0:
Пример #4 Продолжение выражения после идентификатора закрытия
<?php
$values = [<<<END
a
b
c
END, 'd e f'];
var_dump($values);
?>
Результат выполнения приведённого примера в PHP 7.3:
array(2) { [0] => string(11) "a b c" [1] => string(5) "d e f" }
Парсер примет идентификатор за закрывающий и выбросит исключение ParseError, если найдёт закрывающий идентификатор в начале строки, даже если это часть слова.
Пример #5 Закрывающий идентификатор в теле текста провоцирует исключение ParseError
<?php
$values = [<<<END
a
b
END ING
END, 'd e f'];
?>
Результат выполнения приведённого примера в PHP 7.3:
PHP Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 6
Таких проблем помогает избегать несложное, но надёжное правило: не выбирать идентификатор закрытия, который встречается в теле текста.
До PHP 7.3.0 строке с закрывающим идентификатором нельзя было содержать
других символов, кроме точки с запятой — ;
. То есть
идентификатор нельзя вводить с отступом,
а пробелы или знаки табуляции нельзя вводить до или после точки с запятой.
Учитывают также, что первым символом перед закрывающим идентификатором идёт
символ новой строки, который определяет операционная система. Например,
в Unix-системах, включая macOS, это символ \n
. После идентификатора
закрытия должна сразу начинаться новая строка.
PHP не будет считать идентификатор закрывающим и продолжит поиск идентификатора, если это правило нарушили и идентификатор закрытия не «чистый». На последней строке возникнет ошибка синтаксического анализа, если PHP так и не найдёт правильный идентификатор закрытия до конца текущего файла.
Пример #6 Пример неправильного до PHP 7.3.0 синтаксиса
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
// Отступ перед закрывающим идентификатором недопустим
}
?>
Пример #7 Пример правильного даже до PHP 7.3.0 синтаксиса
<?php
class foo
{
public $bar = <<<EOT
bar
EOT;
}
?>
В Heredoc-синтаксисе, который содержит переменные, нельзя инициализировать свойства класса.
Heredoc-текст ведёт себя как строка в двойных кавычках, хотя и не заключается в двойные кавычки. То есть в heredoc кавычки не экранируют, но перечисленные управляющие коды по-прежнему разрешено указывать. Переменные разворачиваются, но в выражениях со сложными переменными внутри heredoc работают так же внимательно, как и при работе со строками.
Пример #8 Пример определения heredoc-строки
<?php
$str = <<<EOD
Пример строки,
которую записали heredoc-синтаксисом
в несколько строк.
EOD;
/* Более сложный пример с переменными. */
class foo
{
var $foo;
var $bar;
function __construct()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'Имярек';
echo <<<EOT
Меня зовут "$name". Я печатаю $foo->foo.
Теперь я вывожу {$foo->bar[1]}.
Это должно вывести заглавную букву 'A': \x41
EOT;
?>
Результат выполнения приведённого примера:
Меня зовут "Имярек". Я печатаю Foo. Теперь, я вывожу Bar2. Это должно вывести заглавную букву 'A': A
Heredoc-синтаксис разрешён также для передачи данных через аргументы функции:
Пример #9 Пример heredoc-синтаксиса с аргументами
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
В heredoc-синтаксисе разрешено инициализировать статические переменные и свойства или константы класса:
Пример #10 Инициализация статических переменных heredoc-синтаксисом
<?php
// Статические переменные
function foo()
{
static $bar = <<<LABEL
Здесь ничего нет...
LABEL;
}
// Константы/свойства класса
class foo
{
const BAR = <<<FOOBAR
Пример использования константы
FOOBAR;
public $baz = <<<FOOBAR
Пример использования поля
FOOBAR;
}
?>
Допустимо также окружать heredoc-идентификатор двойными кавычками:
Пример #11 Двойные кавычки в heredoc
<?php
echo <<<"FOOBAR"
Привет, мир!
FOOBAR;
?>
Nowdoc — то же для строк в одинарных кавычках, что и heredoc для строк
в двойных кавычках. Синтаксис Nowdoc похож на heredoc-синтаксис, но внутри него
не выполняются интерполяция строк. Конструкция
легко встраивает PHP-код или другие большие блоки текста без
предварительного экранирования. В этом он отчасти похож на SGML-конструкцию
<![CDATA[ ]]>
, в том, что он объявляет блок текста,
который не требует обработки.
Nowdoc задают той же последовательностью символов <<<
,
что и в heredoc, но следующий за ней идентификатор берут
в одинарные кавычки, например, <<<'EOT'
.
Условия, которые распространяются на идентификаторы heredoc-синтаксиса, действительны также
и для синтаксиса nowdoc, а больше остальных те, что относятся к закрывающему идентификатору.
Пример #12 Пример nowdoc-синтаксиса
<?php
echo <<<'EOD'
Пример текста,
занимающего несколько строк,
написанного синтаксисом nowdoc. Обратные слеши выводятся без обработки,
например, \\ и \'.
EOD;
?>
Результат выполнения приведённого примера:
Пример текста, занимающего несколько строк, написанного синтаксисом nowdoc. Обратные слеши выводятся без обработки, например, \\ и \'.
Пример #13 Nowdoc с переменными в строках с двойными кавычками
<?php
/* Усложнённый пример с переменными. */
class foo
{
public $foo;
public $bar;
function __construct()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'Имярек';
echo <<<'EOT'
Меня зовут "$name". Я печатаю $foo->foo.
Теперь я печатаю {$foo->bar[1]}.
Это не должно вывести заглавную 'A': \x41
EOT;
?>
Результат выполнения приведённого примера:
Меня зовут "$name". Я печатаю $foo->foo. Теперь я печатаю {$foo->bar[1]}. Это не должно вывести заглавную 'A': \x41
Пример #14 Пример со статичными данными
<?php
class foo
{
public $bar = <<<'EOT'
bar
EOT;
}
?>
PHP умеет подставлять внутри строк значения вместо переменных, если строку (string) указали в двойных кавычках или heredoc-синтаксисом.
В PHP предусмотрели два вида синтаксиса для указания переменных в строках: базовый и продвинутый. Базовым синтаксисом пользуются чаще, им легко встраивать переменную, значение массива (array) или свойство объекта (object) с минимумом усилий.
PHP интерпретирует как переменную и подставит вместо переменной значение этой переменной,
если встретит в строке знак доллара $
,
за которым идут символы, из которых PHP разрешает составлять название переменной.
<?php
$juice = "яблочного";
echo "Он выпил немного $juice сока." . PHP_EOL;
?>
Результат выполнения приведённого примера:
Он выпил немного яблочного сока.
Формально структура базового синтаксиса подстановки переменных выглядит вот так:
строковая переменная:: имя-переменной (смещение-или-свойство)? | ${ выражение } смещение-или-свойство:: смещение в строке | свойство-в-строке смещение-в-строке:: [ имя ] | [ имя-переменной ] | [ целочисленный-литерал ] свойство-в-строке:: -> имя имя-переменной:: $ имя имя:: [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
Синтаксис ${ выражение }
устарел
с PHP 8.2.0, поскольку интерпретируется
как переменные переменных:
<?php
const foo = 'bar';
$foo = 'foo';
$bar = 'bar';
var_dump("${foo}");
var_dump("${(foo)}");
?>
Результат выполнения приведённого примера в PHP 8.2:
Deprecated: Using ${var} in strings is deprecated, use {$var} instead in file on line 6 Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in file on line 9 string(3) "foo" string(3) "bar"
Результат выполнения приведённого примера:
string(3) "foo" string(3) "bar"
Замечание: Знак доллара остается в строке как сам знак доллара, если невозможно сформировать допустимое имя:
<?php
echo "Строка не содержит переменных $ для интерполяции\n";
echo "Строка не содержит переменных $\n для интерполяции\n";
echo "Строка не содержит переменных $2 для интерполяции\n";
?>Результат выполнения приведённого примера:
Строка не содержит переменных $ для интерполяции Строка не содержит переменных $ для интерполяции Строка не содержит переменных $2 для интерполяции
Пример #15 Пример интерполяции значений первого уровня массива или свойства объекта
<?php
$juices = array("яблочного", "апельсинового", "string_key" => "фиолетового");
echo "Он выпил немного $juices[0] сока.";
echo PHP_EOL;
echo "Он выпил немного $juices[1] сока.";
echo PHP_EOL;
echo "Он выпил немного $juices[string_key] сока.";
echo PHP_EOL;
class A
{
public $s = "string";
}
$o = new A();
echo "Значение свойства объекта: $o->s.";
?>
Результат выполнения приведённого примера:
Он выпил немного яблочного сока. Он выпил немного апельсинового сока. Он выпил немного фиолетового сока. Значение свойства объекта: string.
Замечание: Ключ массива указывают без кавычек, поэтому невозможно ссылаться на константу как на ключ в базовом синтаксисе. Вместо этого пользуются продвинутым синтаксисом.
В PHP 7.1.0 добавили поддержку отрицательных числовых индексов.
Пример #16 Отрицательные числовые индексы
<?php
$string = 'string';
echo "Символ с индексом -2 равен $string[-2].", PHP_EOL;
$string[-3] = 'o';
echo "Изменение символа на позиции -3 на 'o' даёт следующую строку: $string.", PHP_EOL;
?>
Результат выполнения приведённого примера:
Символ с индексом -2 равен n. Изменение символа на позиции -3 на «o» даёт следующую строку: strong
Для выражений, которые сложнее этих, лучше пользоваться продвинутым синтаксисом.
Продвинутый синтаксис разрешает интерполировать переменные с произвольными методами доступа.
В строках продвинутым синтаксисом указывают скалярные переменные, элементы массива,
статические и динамические свойства объекта со строковым представлением.
Выражение записывается как и вне строки, а затем оборачивается
в фигурные скобки {
и }
.
Поскольку знак {
невозможно экранировать, продвинутый синтаксис
распознаётся только тогда, когда знак $
идёт непосредственно за знаком {
.
Знак доллара экранируют синтаксисом {\$
, чтобы получить литерал {$
.
Поясняющие примеры:
<?php
const DATA_KEY = 'const-key';
$great = 'здорово';
$arr = [
'1',
'2',
'3',
[41, 42, 43],
'key' => 'Индексное значение',
'const-key' => 'Ключ со знаком минуса',
'foo' => ['foo1', 'foo2', 'foo3']
];
// Не работает, выводит: Это { здорово}
echo "Это { $great}";
// Работает, выводит: Это здорово
echo "Это {$great}";
class Square
{
public $width;
public function __construct(int $width)
{
$this->width = $width;
}
}
$square = new Square(5);
// Работает
echo "Ширина квадрата составляет {$square->width}00 сантиметров.";
// Работает, ключи, взятые в кавычки, работают только с синтаксисом фигурных скобок
echo "Это работает: {$arr['key']}";
// Работает
echo "Это работает: {$arr[3][2]}";
echo "Работает: {$arr[DATA_KEY]}";
// При работе с многомерными массивами массивы внутри строк оборачивают в фигурные скобки
echo "Это работает: {$arr['foo'][2]}";
echo "Работает: {$obj->values[3]->name}";
echo "Работает: {$obj->$staticProp}";
// Не работает, выводит: C:\directory\{fantastic}.txt
echo "C:\directory\{$great}.txt";
// Работает, выводит: C:\directory\fantastic.txt
echo "C:\\directory\\{$great}.txt";
?>
Замечание: В строках с продвинутым синтаксисом возможно записывать переменные переменных, поскольку продвинутый синтаксис разрешает произвольные выражения.
Символы внутри строк индексируются с начала строки, индексы начинаются с 0. Смещение символа, который требуется прочитать или изменить внутри строки, указывают после строки в квадратных скобках массива (array), например $str[42]. Для этого о строке думают как о массиве символов. Больше одного символа получают и заменяют функциями substr() и substr_replace().
Замечание: Начиная с PHP 7.1.0 поддерживаются отрицательные значения смещения. Они задают смещение с конца строки. Раньше отрицательные смещение вызывали ошибку уровня
E_NOTICE
при чтении (возвращая пустую строку) илиE_WARNING
при записи (оставляя строку без изменений).
Замечание: До PHP 8.0.0 доступ к символам в строках (string) получали, указывая фигурные скобки, например $str{42}. Синтаксис фигурных скобок устарел с PHP 7.4.0 и не поддерживается с PHP 8.0.0.
Попытка записи в смещение за границами строки дополнит строку
пробелами до этого смещения. Нецелочисленные типы преобразуются в целочисленные.
Неверный тип смещения выдаст ошибку уровня E_WARNING
.
При добавлении в смещение строки новых символов присвоится только первый символ (байт).
Начиная с PHP 7.1.0 присваивание пустой строки вызовет фатальную ошибку. Раньше
присваивался нулевой байт (NULL).
Внутренне PHP представляет строки массивами байтов. Поэтому доступ или изменение строки по смещению небезопасны для многобайтовых данных и выполняются только со строками в однобайтовых кодировках, например ISO-8859-1.
Замечание: Начиная с PHP 7.1.0 попытка указать оператор пустого индекса на пустой строке выдаст фатальную ошибку. Раньше пустая строка преобразовывалась в массив без предупреждения.
Пример #17 Примеры строк
<?php
// Получим первый символ строки
$str = 'This is a test.';
$first = $str[0];
// Получим третий символ строки
$third = $str[2];
// Получим последний символ строки
$str = 'This is still a test.';
$last = $str[strlen($str)-1];
// Изменим последний символ строки
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';
?>
Смещение в строке задают либо целым числом, либо целочисленной строкой, иначе PHP выдаст предупреждение.
Пример #18 Пример недопустимого смещения строки
<?php
$str = 'abc';
var_dump($str['1']);
var_dump(isset($str['1']));
var_dump($str['1.0']);
var_dump(isset($str['1.0']));
var_dump($str['x']);
var_dump(isset($str['x']));
var_dump($str['1x']);
var_dump(isset($str['1x']));
?>
Результат выполнения приведённого примера:
string(1) "b" bool(true) Warning: Illegal string offset '1.0' in /tmp/t.php on line 7 string(1) "b" bool(false) Warning: Illegal string offset 'x' in /tmp/t.php on line 9 string(1) "a" bool(false) string(1) "b" bool(false)
Замечание:
Доступ к переменным других типов, кроме массивов и объектов, которые реализуют соответствующие интерфейсы, через операторы
[]
или{}
без предупреждения возвращаетnull
.
Замечание:
Доступ к символам в строковых литералах получают через операторы
[]
или{}
.
Замечание:
Доступ к символам в строковых литералах через оператор
{}
объявили устаревшим в PHP 7.4 и удалили в PHP 8.0.
Строки объединяют оператором «.» — точки. Обратите внимание, оператор сложения «+» здесь не работает. Подробнее об этом рассказано в разделе «Строковые операторы».
В языке предусмотрели ряд полезных функций для манипулирования строками.
Общие функции описывает раздел «Функции для работы со строками», а для расширенного поиска и замены — «Функции Perl-совместимых регулярных выражений».
В PHP также предусмотрели функции для работы с URL-адресами и функции шифрования или дешифрования строк (Sodium и Hash).
Наконец, смотрите также функции символьных типов.
Значение преобразовывают в строку приведением
через оператор (string)
или функцией strval().
В выражениях, в которых требуется строка, преобразование выполняется автоматически.
Это выполняется во время вывода через языковые конструкции echo
или print, либо когда значение переменной сравнивается
со строкой. Разделы руководства
«Типы»
и «Манипуляции с типами»,
прояснят сказанное ниже. Смотрите также описание функции settype().
Значение bool true
преобразовывается в строку
«1»
, а логическое значение false
преобразовывается
в «»
(пустую строку). Такое поведение допускает преобразование значения
в обе стороны — из логического типа в строковый и наоборот.
Целое число (int) или число с плавающей точкой
(float) преобразовывается в строку, которая будет представлять число в текстовом виде
(включая экспоненциальную часть для чисел с плавающей точкой).
Большие числа с плавающей точкой преобразовываются в экспоненциальную запись (4.1E+6
).
Замечание:
Начиная с PHP 8.0.0 в качестве разделителя дробной части в числах с плавающей точкой разрешено использовать только точку («
.
»). До PHP 8.0.0 символ десятичной точки определялся в настройках языкового стандарта скрипта (категория LC_NUMERIC). Смотрите функцию setlocale().
Массивы преобразовываются в строку «Array»
.
Поэтому конструкции echo или print
не умеют без помощи функций отображать содержимое массива (array).
Чтобы просмотреть отдельный элемент, пользуются
синтаксисом echo $arr['foo']
. Ниже рассказывается
об отображении или просмотре всего содержимого.
Для преобразования объекта (object
) в строку (string)
определяют магический метод
__toString.
Ресурс (resource) преобразовывается в строку (string) вида
«Resource id #1»
, где 1
—
это номер ресурса, который PHP назначает ресурсу (resource) во время исполнения кода.
И хотя она уникальна для текущего запуска скрипта (т. е. веб-запроса или
CLI-процесса) и не будет использована повторно для этого ресурса,
не стоит полагаться на эту строку, потому что её могут изменить в будущем.
Тип ресурса можно получить вызовом функции get_resource_type().
Значение null
всегда преобразовывается в пустую строку.
Как указано выше, прямое преобразование в строку массивов, объектов или ресурсов не даёт полезной информации о значении, кроме типа. Более эффективные инструменты вывода значений для отладки этих типов — это функции print_r() и var_dump().
Бо́льшая часть значений в PHP преобразуема в строку для постоянного хранения. Этот метод преобразования называется сериализацией. Сериализуют значения функцией serialize().
Строковый тип (string) в PHP реализовали в виде массива
байтов и целочисленного значения, которое содержит длину буфера. В этой структуре
нет информации о том, как преобразовывать байты в символы,
эту задачу решает программист. Нет ограничений на значения, из которых состоит строка,
например, байт со значением 0
(NUL-байт) разрешается
где угодно в строке (однако рекомендуют учитывать, что ряд функций,
которые в этом руководстве назвали «бинарно небезопасными»,
передают строки библиотекам, которые игнорируют данные после NUL-байта).
Такая природа строкового типа объясняет, почему в PHP нет отдельного типа «byte» — строки выполняют эту роль. Функции, которые не возвращают текстовых данных, — например, произвольный поток данных, считываемый из сетевого сокета, — по-прежнему возвращают строки.
С учётом того, что PHP не диктует конкретную кодировку
для строк, может возникнуть вопрос: Как тогда кодируются строковые
литералы? Например, строка «á»
эквивалентна
«\xE1»
(ISO-8859-1), «\xC3\xA1»
(UTF-8, форма нормализации C), «\x61\xCC\x81»
(UTF-8, форма нормализации D) или другому возможному
представлению? Ответ такой: строка будет закодирована
способом, которым она закодирована в файле скрипта. Поэтому, если
скрипт записан в кодировке ISO-8859-1, то и строка будет закодирована в
ISO-8859-1 и т. д. Однако это правило не выполняется при включённом
режиме Zend Multibyte: скрипт записывают в произвольной
кодировке, объявляя её или полагаясь на автоопределение,
а затем конвертируют в конкретную внутреннюю кодировку, которая и будет
использована для строковых литералов.
Учтите, что на кодировку скрипта (или на внутреннюю кодировку, если
включён режим Zend Multibyte) накладывается ряд ограничений:
почти в каждом случае эта кодировка должна быть надмножеством кодировки ASCII,
например, UTF-8 или ISO-8859-1. Учтите также, что кодировки, зависящие
от состояния, где одни и те же значения байтов допустимы
в начальном и не начальном состоянии сдвига, создают риск проблем.
Строковые функции, чтобы быть полезными, пробуют предположить кодировку строки. Единство в этом вопросе не помешало бы, но PHP-функции работают с текстом по-разному:
u
).
В конечном счёте, программа будет работать с кодировкой Unicode правильно, если старательно избегать функций, которые не будут работать с Unicode-строками или повредят данные, и вызывать вместо них те, которые ведут себя корректно, обычно это функции из модулей intl и mbstring. Однако работа с функциями, которые умеют обрабатывать Unicode, — это только начало. Независимо от того, какие функции предлагает язык, рекомендовано знать спецификацию Unicode. Например, программа, которая предполагает существование только прописных и строчных букв, делает неверное предположение.