mirror of
https://github.com/php/doc-ru.git
synced 2026-03-26 00:32:15 +01:00
1386 lines
56 KiB
XML
1386 lines
56 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: affa37e16f562d9297e83b2e21ec416aadc8b72d Maintainer: rjhdby Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
<sect1 xml:id="language.types.string">
|
||
<title>Строки</title>
|
||
|
||
<para>
|
||
Строка (<type>string</type>) — это набор символов, в котором символ — то же,
|
||
что и байт. То есть PHP поддерживает набор только из 256 символов и, следовательно,
|
||
не обеспечивает встроенную поддержку кодировки Unicode. Подробнее об этом рассказывает раздел
|
||
«<link linkend="language.types.string.details">Подробные сведения о строковом типе</link>».
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
В 32-битных сборках размер строки (<type>string</type>) ограничен 2 ГБ (2 147 483 647 байтов максимум).
|
||
</simpara>
|
||
</note>
|
||
|
||
<sect2 xml:id="language.types.string.syntax">
|
||
<title>Синтаксис</title>
|
||
|
||
<para>
|
||
Строковый литерал определяют четырьмя способами:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
<link linkend="language.types.string.syntax.single">одинарными кавычками</link>
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<link linkend="language.types.string.syntax.double">двойными кавычками</link>
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<link linkend="language.types.string.syntax.heredoc">heredoc-синтаксисом</link>
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<link linkend="language.types.string.syntax.nowdoc">nowdoc-синтаксисом</link>
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<sect3 xml:id="language.types.string.syntax.single">
|
||
<title>Одинарные кавычки</title>
|
||
|
||
<para>
|
||
Простейший способ определить строку — заключить строку в одинарные кавычки
|
||
(символ <literal>'</literal>).
|
||
</para>
|
||
|
||
<para>
|
||
Чтобы записать внутри строки буквальную одинарную кавычку, её экранируют обратным слешем
|
||
(<literal>\</literal>). Чтобы записать сам обратный слеш, его дублируют
|
||
(<literal>\\</literal>). В остальных случаях обратный слеш будет
|
||
обработан как буквальный обратный слеш: то есть
|
||
последовательности вроде <literal>\r</literal> или
|
||
<literal>\n</literal> не будут рассматриваться как управляющие, а будут выведены как записаны.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
<link linkend="language.variables">Переменные</link> и управляющие последовательности служебных символов
|
||
в одинарных кавычках <emphasis>не</emphasis> обрабатываются,
|
||
в отличие от синтаксиса <link linkend="language.types.string.syntax.double">двойных кавычек</link>
|
||
и <link linkend="language.types.string.syntax.heredoc">heredoc</link>.
|
||
</simpara>
|
||
</note>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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 также не разворачиваются';
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.string.syntax.double">
|
||
<title>Двойные кавычки</title>
|
||
|
||
<para>
|
||
PHP распознает следующие управляющие последовательности служебных символов,
|
||
если строку заключили в двойные кавычки ("):
|
||
</para>
|
||
|
||
<table>
|
||
<title>Управляющие последовательности</title>
|
||
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>Последовательность</entry>
|
||
<entry>Значение</entry>
|
||
</row>
|
||
</thead>
|
||
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>\n</literal></entry>
|
||
<entry>новая строка (LF или 0x0A (10) в ASCII)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\r</literal></entry>
|
||
<entry>возврат каретки (CR или 0x0D (13) в ASCII)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\t</literal></entry>
|
||
<entry>горизонтальная табуляция (HT или 0x09 (9) в ASCII)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\v</literal></entry>
|
||
<entry>вертикальная табуляция (VT или 0x0B (11) в ASCII)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\e</literal></entry>
|
||
<entry>escape-знак (ESC или 0x1B (27) в ASCII)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\f</literal></entry>
|
||
<entry>подача страницы (FF или 0x0C (12) в ASCII)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\\</literal></entry>
|
||
<entry>обратная косая черта</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\$</literal></entry>
|
||
<entry>знак доллара</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\"</literal></entry>
|
||
<entry>двойная кавычка</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\[0-7]{1,3}</literal></entry>
|
||
<entry>
|
||
Восьмеричная запись: символ, код которого записали в восьмеричной нотации (т. е. <literal>"\101" === "A"</literal>),
|
||
т. е. в виде последовательности символов, которая соответствует регулярному выражению <literal>[0-7]{1,3}</literal>.
|
||
В ситуации целочисленного переполнения (если символ не поместится в один байт),
|
||
старшие биты будут без предупреждения отброшены (т. е. <literal>"\400" === "\000"</literal>)
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\x[0-9A-Fa-f]{1,2}</literal></entry>
|
||
<entry>
|
||
Шестнадцатеричная система счисления: символ, код которого записали
|
||
в шестнадцатеричной нотации (т. е. <literal>"\x41" === "A"</literal>),
|
||
т. е. в виде последовательности символов, которая соответствует
|
||
регулярному выражению <literal>[0-9A-Fa-f]{1,2}</literal>
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>\u{[0-9A-Fa-f]+}</literal></entry>
|
||
<entry>
|
||
Стандарт Unicode: символ, код которого записали в нотации кодовых точек Unicode,
|
||
т. е. в виде последовательности символов, которая соответствует
|
||
регулярному выражению <literal>[0-9A-Fa-f]+</literal>,
|
||
которые будут отображены как строка в кодировке UTF-8.
|
||
Последовательность необходимо заключать в фигурные скобки.
|
||
Например: <literal>"\u{41}" === "A"</literal>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
<para>
|
||
Как и в строках в одинарных кавычках, экранирование другого символа
|
||
выведет также и символ обратного слеша.
|
||
</para>
|
||
|
||
<para>
|
||
Наиболее важное свойство строк в двойных кавычках состоит в том,
|
||
что имена переменных в них будут развёрнуты и обработаны.
|
||
Подробнее об этом рассказывает раздел
|
||
«<link linkend="language.types.string.parsing">Синтаксический анализ переменных</link>».
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.string.syntax.heredoc">
|
||
<title>Heredoc</title>
|
||
|
||
<simpara>
|
||
Третий способ определения строк — это heredoc-синтаксис:
|
||
<literal><<<</literal>. Следом за этим оператором указывают идентификатор,
|
||
а затем перевод строки. Затем идёт сама строка, за которой снова идёт тот же идентификатор,
|
||
чтобы закрыть вставку.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Закрывающий идентификатор разрешено отбивать пробелами или символами табуляции,
|
||
и тогда отступ будет удалён из каждой строки в блоке документа.
|
||
До PHP 7.3.0 закрывающий идентификатор указывали <emphasis>в самом начале</emphasis> новой строки.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Кроме того, закрывающий идентификатор подчиняется тем же правилам именования,
|
||
что и другие метки в PHP: содержит только буквенно-цифровые символы
|
||
и подчёркивания, и не начинается с цифрового символа или символа подчёркивания.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Базовый пример использования Heredoc-синтаксиса в PHP 7.3.0</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
// без отступов
|
||
echo <<<END
|
||
a
|
||
b
|
||
c
|
||
\n
|
||
END;
|
||
|
||
// 4 отступа
|
||
echo <<<END
|
||
a
|
||
b
|
||
c
|
||
END;
|
||
]]>
|
||
|
||
</programlisting>
|
||
&example.outputs.73;
|
||
<screen>
|
||
<![CDATA[
|
||
a
|
||
b
|
||
c
|
||
|
||
a
|
||
b
|
||
c
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<simpara>
|
||
Если закрывающий идентификатор смещён дальше хотя бы одной строки тела,
|
||
будет выброшено исключение <classname>ParseError</classname>:
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Отступу закрывающего идентификатора нельзя отступать больше, чем другим строкам тела</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
echo <<<END
|
||
a
|
||
b
|
||
c
|
||
END;
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs.73;
|
||
<screen>
|
||
<![CDATA[
|
||
PHP Parse error: Invalid body indentation level (expecting an indentation level of at least 3) in example.php on line 4
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<simpara>
|
||
В теле тоже будет допустимо указывать табуляции, если закрывающий идентификатор отбить отступом.
|
||
Однако табуляциям и пробелам <emphasis>не разрешено</emphasis>
|
||
смешиваться относительно отступа закрывающего идентификатора и тела (вплоть до закрывающего идентификатора).
|
||
В каждом из этих случаев будет выброшено исключение <classname>ParseError</classname>.
|
||
|
||
Эти ограничения на пробельные отступы добавили, потому что смешивание табуляций
|
||
и пробелов для отступов вредно для разбора.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Другой отступ для закрывающего идентификатора тела (пробелов)</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
// Весь следующий код не работает.
|
||
|
||
// Другой отступ для закрывающего идентификатора (табуляций) тела (пробелов)
|
||
{
|
||
echo <<<END
|
||
a
|
||
END;
|
||
}
|
||
|
||
// Смешивание пробелов и табуляции в теле
|
||
{
|
||
echo <<<END
|
||
a
|
||
END;
|
||
}
|
||
|
||
// Смешивание пробелов и табуляции в закрывающем идентификаторе
|
||
{
|
||
echo <<<END
|
||
a
|
||
END;
|
||
}
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs.73;
|
||
<screen>
|
||
<![CDATA[
|
||
PHP Parse error: Invalid indentation - tabs and spaces cannot be mixed in example.php line 8
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<simpara>
|
||
За закрывающим идентификатором основной строки не обязательно ставить точку с запятой или новую строку.
|
||
Например, начиная с PHP 7.3.0 разрешён следующий код:
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Продолжение выражения после закрывающего идентификатора</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$values = [<<<END
|
||
a
|
||
b
|
||
c
|
||
END, 'd e f'];
|
||
var_dump($values);
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs.73;
|
||
<screen>
|
||
<![CDATA[
|
||
array(2) {
|
||
[0] =>
|
||
string(11) "a
|
||
b
|
||
c"
|
||
[1] =>
|
||
string(5) "d e f"
|
||
}
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Парсер примет идентификатор за закрывающий и выбросит
|
||
исключение <classname>ParseError</classname>, если найдёт
|
||
закрывающий идентификатор в начале строки, даже если это часть слова.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Закрывающий идентификатор в теле текста провоцирует исключение ParseError</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$values = [<<<END
|
||
a
|
||
b
|
||
END ING
|
||
END, 'd e f'];
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs.73;
|
||
<screen>
|
||
<![CDATA[
|
||
PHP Parse error: syntax error, unexpected identifier "ING", expecting "]" in example.php on line 6
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<simpara>
|
||
Чтобы не возникало таких проблем, следуют несложному, но надёжному правилу:
|
||
<emphasis>не выбирать закрывающий идентификатор, который встречается в теле текста</emphasis>.
|
||
</simpara>
|
||
|
||
</warning>
|
||
|
||
<warning>
|
||
<simpara>
|
||
До PHP 7.3.0 строке с закрывающим идентификатором нельзя было содержать
|
||
символов, кроме точки с запятой (<literal>;</literal>). То есть
|
||
идентификатор <emphasis>не разрешено вводить с отступом</emphasis>,
|
||
а пробелы или знаки табуляции нельзя вводить до или после точки с запятой.
|
||
Учитывают также, что первым символом перед закрывающим идентификатором идёт
|
||
символ новой строки, который определён в операционной системе. Например,
|
||
в Unix-системах, включая macOS, это символ <literal>\n</literal>. После закрывающего
|
||
идентификатора должна сразу начинаться новая строка.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
PHP не будет считать идентификатор закрывающим и продолжит поиск идентификатора
|
||
дальше, если это правило нарушили и закрывающий идентификатор не «чистый».
|
||
На последней строке возникнет ошибка синтаксического анализа, если PHP
|
||
так и не найдёт правильный закрывающий идентификатор до конца текущего файла.
|
||
</simpara>
|
||
|
||
<example>
|
||
<title>Пример неправильного до PHP 7.3.0 синтаксиса</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class foo {
|
||
public $bar = <<<EOT
|
||
bar
|
||
EOT;
|
||
// Отступ перед закрывающим идентификатором недопустим
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<example>
|
||
<title>Пример правильного даже до PHP 7.3.0 синтаксиса</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class foo {
|
||
public $bar = <<<EOT
|
||
bar
|
||
EOT;
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
<para>
|
||
Переменные в Heredoc-синтаксисе не инициализируют свойств класса.
|
||
</para>
|
||
|
||
</warning>
|
||
|
||
<para>
|
||
Heredoc-текст хотя и не заключён в двойные кавычки, ведёт себя как строка в двойных кавычках.
|
||
То есть в heredoc кавычки не экранируют,
|
||
но перечисленные управляющие коды по-прежнему разрешено указывать.
|
||
Переменные разворачиваются, но в выражениях со сложными переменными внутри heredoc
|
||
работают так же внимательно, как и при работе со строками.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Пример определения heredoc-строки</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Меня зовут "Имярек". Я печатаю Foo.
|
||
Теперь, я вывожу Bar2.
|
||
Это должно вывести заглавную букву 'A': A]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<para>
|
||
Heredoc-синтаксис разрешён также для передачи данных через аргументы функции:
|
||
</para>
|
||
|
||
<example>
|
||
<title>Пример heredoc-синтаксиса с аргументами</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
var_dump(array(<<<EOD
|
||
foobar!
|
||
EOD
|
||
));
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
В heredoc-синтаксисе разрешено инициализировать статические переменные и свойства или константы класса:
|
||
</para>
|
||
|
||
<example>
|
||
<title>Инициализация статических переменных heredoc-синтаксисом</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
// Статические переменные
|
||
function foo()
|
||
{
|
||
static $bar = <<<LABEL
|
||
Здесь ничего нет...
|
||
LABEL;
|
||
}
|
||
|
||
// Константы/свойства класса
|
||
class foo
|
||
{
|
||
const BAR = <<<FOOBAR
|
||
Пример использования константы
|
||
FOOBAR;
|
||
|
||
public $baz = <<<FOOBAR
|
||
Пример использования поля
|
||
FOOBAR;
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Допустимо также окружать heredoc-идентификатор двойными кавычками:
|
||
</para>
|
||
|
||
<example>
|
||
<title>Двойные кавычки в heredoc</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
echo <<<"FOOBAR"
|
||
Привет, мир!
|
||
FOOBAR;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.string.syntax.nowdoc">
|
||
<title>Nowdoc</title>
|
||
|
||
<para>
|
||
Nowdoc — это то же для строк в одинарных кавычках, что и heredoc для строк
|
||
в двойных кавычках. Синтаксис Nowdoc похож на heredoc-синтаксис, но внутри него
|
||
<emphasis>не выполняются подстановки</emphasis>. Конструкция
|
||
легко встраивает PHP-код или другие большие блоки текста без
|
||
предварительного экранирования. В этом он отчасти похож на SGML-конструкцию
|
||
<literal><![CDATA[ ]]></literal>, в том, что он объявляет блок текста,
|
||
который не требует обработки.
|
||
</para>
|
||
|
||
<para>
|
||
Nowdoc задают той же последовательностью символов <literal><<<</literal>,
|
||
что и в heredoc, но следующий за ней идентификатор берут
|
||
в одинарные кавычки, например, <literal><<<'EOT'</literal>.
|
||
Условия, которые распространяются на идентификаторы heredoc-синтаксиса, действительны также
|
||
и для синтаксиса nowdoc, а больше остальных те, что относятся к закрывающему идентификатору.
|
||
</para>
|
||
|
||
<example>
|
||
<title>Пример nowdoc-синтаксиса</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
echo <<<'EOD'
|
||
Пример текста,
|
||
занимающего несколько строк,
|
||
написанного синтаксисом nowdoc. Обратные слеши выводятся без обработки,
|
||
например, \\ и \'.
|
||
EOD;
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Пример текста,
|
||
занимающего несколько строк,
|
||
написанного синтаксисом nowdoc. Обратные слеши выводятся без обработки,
|
||
например, \\ и \'.
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<example>
|
||
<title>Nowdoc с переменными в строках с двойными кавычками</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Меня зовут "$name". Я печатаю $foo->foo.
|
||
Теперь я печатаю {$foo->bar[1]}.
|
||
Это не должно вывести заглавную 'A': \x41]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<example>
|
||
<title>Пример со статичными данными</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class foo {
|
||
public $bar = <<<'EOT'
|
||
bar
|
||
EOT;
|
||
}
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.string.parsing">
|
||
<title>Синтаксический анализ переменных</title>
|
||
|
||
<simpara>
|
||
PHP обрабатывает <link linkend="language.variables">переменные</link>
|
||
внутри строки, если строку указали в двойных кавычках или heredoc-синтаксисом.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
В PHP предусмотрели два вида синтаксиса для указания переменных в строках:
|
||
<link linkend="language.types.string.parsing.simple">простой</link> и
|
||
<link linkend="language.types.string.parsing.complex">сложный</link>.
|
||
Простым синтаксисом пользуются чаще, с ним легко
|
||
встраивать переменную, значение массива (<type>array</type>) или
|
||
свойство объекта (<type>object</type>) с минимумом усилий.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Сложный синтаксис легко определить по фигурным скобкам, которые окружают выражение.
|
||
</simpara>
|
||
|
||
<sect4 xml:id="language.types.string.parsing.simple">
|
||
<title>Простой синтаксис</title>
|
||
|
||
<simpara>
|
||
Если интерпретатор встречает знак доллара (<literal>$</literal>), он захватывает
|
||
как можно больше символов, чтобы сформировать правильное имя переменной.
|
||
Имя переменной берут в фигурные скобки, если нужно точно определить конец имени.
|
||
</simpara>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$juice = "apple";
|
||
|
||
echo "He drank some $juice juice." . PHP_EOL;
|
||
|
||
// Непредусмотрительно. Символ «s» — корректный символ для имени переменной,
|
||
// поэтому в этом примере он относится к переменной $juces, но не $juice.
|
||
echo "He drank some juice made of $juices." . PHP_EOL;
|
||
|
||
// Укажем границы переменной, взяв её в фигурные скобки.
|
||
echo "He drank some juice made of {$juice}s.";
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
He drank some apple juice.
|
||
He drank some juice made of .
|
||
He drank some juice made of apples.
|
||
]]>
|
||
</screen>
|
||
</informalexample>
|
||
|
||
<simpara>
|
||
Аналогично будет проанализирован индекс массива (<type>array</type>) или свойство
|
||
объекта (<type>object</type>). В индексах массива закрывающая квадратная скобка
|
||
(<literal>]</literal>) означает конец определения индекса. На свойства объекта
|
||
распространяются те же правила, что и на простые переменные.
|
||
</simpara>
|
||
|
||
<example><title>Пример простого синтаксиса</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$juices = array("apple", "orange", "koolaid1" => "purple");
|
||
|
||
echo "He drank some $juices[0] juice.".PHP_EOL;
|
||
echo "He drank some $juices[1] juice.".PHP_EOL;
|
||
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;
|
||
|
||
class people {
|
||
public $john = "John Smith";
|
||
public $jane = "Jane Smith";
|
||
public $robert = "Robert Paulsen";
|
||
|
||
public $smith = "Smith";
|
||
}
|
||
|
||
$people = new people();
|
||
|
||
echo "$people->john drank some $juices[0] juice.".PHP_EOL;
|
||
echo "$people->john then said hello to $people->jane.".PHP_EOL;
|
||
echo "$people->john's wife greeted $people->robert.".PHP_EOL;
|
||
echo "$people->robert greeted the two $people->smiths."; // Не сработает
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
He drank some apple juice.
|
||
He drank some orange juice.
|
||
He drank some purple juice.
|
||
John Smith drank some apple juice.
|
||
John Smith then said hello to Jane Smith.
|
||
John Smith's wife greeted Robert Paulsen.
|
||
Robert Paulsen greeted the two .
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<simpara>
|
||
В PHP 7.1.0 добавлена поддержка <emphasis>отрицательных</emphasis>
|
||
числовых индексов.
|
||
</simpara>
|
||
|
||
<example><title>Отрицательные числовые индексы</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$string = 'string';
|
||
echo "Символ с индексом -2 равен $string[-2].", PHP_EOL;
|
||
$string[-3] = 'o';
|
||
echo "Изменение символа на позиции -3 на «o» даёт следующую строку: $string.", PHP_EOL;
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
Символ с индексом -2 равен n.
|
||
Изменение символа на позиции -3 на «o» даёт следующую строку: strong
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<simpara>
|
||
Для выражений, которые сложнее этих, лучше пользоваться сложным синтаксисом.
|
||
</simpara>
|
||
</sect4>
|
||
|
||
<sect4 xml:id="language.types.string.parsing.complex">
|
||
<title>Сложный (фигурный) синтаксис</title>
|
||
|
||
<simpara>
|
||
Он называется сложным не из-за сложности синтаксиса,
|
||
а только потому, что разрешает писать сложные выражения.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Скалярная переменная, элемент массива или отображаемое в строку свойство объекта
|
||
разрешено указывать в строке этим синтаксисом. Выражение записывается
|
||
как и вне строки, а затем берётся в фигурные скобки: <literal>{</literal> и <literal>}</literal>.
|
||
Поскольку знак <literal>{</literal> невозможно экранировать, этот синтаксис будет
|
||
распознаваться только тогда, когда знак <literal>$</literal> идёт непосредственно за знаком <literal>{</literal>.
|
||
Чтобы получить литерал <literal>{$</literal>, знак доллара экранируют <literal>{\$</literal>.
|
||
Поясняющие примеры:
|
||
</simpara>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
// Показываем все ошибки
|
||
error_reporting(E_ALL);
|
||
|
||
$great = 'здорово';
|
||
|
||
// Не работает, выводит: Это { здорово}
|
||
echo "Это { $great}";
|
||
|
||
// Работает, выводит: Это здорово
|
||
echo "Это {$great}";
|
||
|
||
// Работает
|
||
echo "Этот квадрат шириной {$square->width}00 сантиметров.";
|
||
|
||
// Работает, ключи, взятые в кавычки, работают только с синтаксисом фигурных скобок
|
||
echo "Это работает: {$arr['key']}";
|
||
|
||
// Работает
|
||
echo "Это работает: {$arr[4][3]}";
|
||
|
||
// Следующая запись неверна по той же причине, по которой запись $foo[bar] неверна вне строки.
|
||
// Сначала PHP ищет константу foo и выбрасывает ошибку, если не находит.
|
||
// PHP, если найдёт константу, будет использовать как индекс массива
|
||
// значение константы, а не само «foo»
|
||
echo "Это неправильно: {$arr[foo][3]}";
|
||
|
||
// Работает. При обращении к многомерным массивам внутри
|
||
// строк указывают фигурные скобки
|
||
echo "Это работает: {$arr['foo'][3]}";
|
||
|
||
// Работает.
|
||
echo "Это работает: " . $arr['foo'][3];
|
||
|
||
echo "Это тоже работает: {$obj->values[3]->name}";
|
||
|
||
echo "Это значение переменной с именем $name: {${$name}}";
|
||
|
||
echo "Это значение переменной с именем, которое возвращает функция getName(): {${getName()}}";
|
||
|
||
echo "Это значение переменной с именем, которое возвращает \$object->getName(): {${$object->getName()}}";
|
||
|
||
// Не работает, выводит: Это то, что возвращает функция getName(): {getName()}
|
||
echo "Это то, что возвращает функция getName(): {getName()}";
|
||
|
||
// Не работает, выводит: C:\folder\{fantastic}.txt
|
||
echo "C:\folder\{$great}.txt"
|
||
|
||
// Работает, выводит: C:\folder\fantastic.txt
|
||
echo "C:\\folder\\{$great}.txt"
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Через переменные внутри строк, которые записали таким синтаксисом,
|
||
доступны свойства класса.
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
class foo {
|
||
var $bar = 'I am bar.';
|
||
}
|
||
|
||
$foo = new foo();
|
||
$bar = 'bar';
|
||
$baz = array('foo', 'bar', 'baz', 'quux');
|
||
echo "{$foo->$bar}\n";
|
||
echo "{$foo->{$baz[1]}}\n";
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
I am bar.
|
||
I am bar.
|
||
]]>
|
||
</screen>
|
||
</informalexample>
|
||
|
||
<note>
|
||
<para>
|
||
Значение внутри литерала <literal>{$}</literal>, к которому получают доступ из функций,
|
||
вызовов методов, статических переменных класса и констант класса, интерпретируется как имя
|
||
переменной в области, в которой определена строка. Синтаксис
|
||
одинарных фигурных скобок (<literal>{}</literal>) не будет работать
|
||
для доступа к значениям функций, методов,
|
||
констант классов или статических переменных класса.
|
||
</para>
|
||
</note>
|
||
|
||
<informalexample>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
// Показываем все ошибки
|
||
error_reporting(E_ALL);
|
||
|
||
class beers {
|
||
const softdrink = 'rootbeer';
|
||
public static $ale = 'ipa';
|
||
}
|
||
|
||
$rootbeer = 'A & W';
|
||
$ipa = 'Alexander Keith\'s';
|
||
|
||
// Это работает, выводит: Я бы хотел A & W
|
||
echo "Я бы хотел {${beers::softdrink}}\n";
|
||
|
||
// Это тоже работает, выводит: Я бы хотел Alexander Keith's
|
||
echo "Я бы хотел {${beers::$ale}}\n";
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
</sect4>
|
||
</sect3>
|
||
|
||
<sect3 xml:id="language.types.string.substr">
|
||
<title>Доступ и изменение символа в строке</title>
|
||
|
||
<para>
|
||
Чтобы получить доступ и изменить символ в строке,
|
||
нужно в квадратных скобках после переменной определить смещение искомого символа
|
||
относительно начала строки начиная с нуля, например, <varname>$str[42]</varname>.
|
||
Для этого о строке думают как о массиве символов.
|
||
Чтобы получить или заменить больше одного символа, вызывают
|
||
функции <function>substr</function> и <function>substr_replace</function>.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Начиная с PHP 7.1.0 поддерживаются отрицательные значения смещения.
|
||
Они задают смещение с конца строки. Раньше отрицательные смещение вызывали
|
||
ошибку уровня <constant>E_NOTICE</constant> при чтении (возвращая пустую строку)
|
||
или <constant>E_WARNING</constant> при записи (оставляя строку без изменений).
|
||
</simpara>
|
||
</note>
|
||
|
||
<note>
|
||
<simpara>
|
||
До PHP 8.0.0 доступ к символам в строках (<type>string</type>) получали,
|
||
указывая фигурные скобки, например <varname>$str{42}</varname>.
|
||
Синтаксис фигурных скобок устарел с PHP 7.4.0 и не поддерживается с PHP 8.0.0.
|
||
</simpara>
|
||
</note>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Попытка записи в смещение за границами строки дополнит строку
|
||
пробелами до этого смещения. Нецелочисленные типы преобразуются в целочисленные.
|
||
Неверный тип смещения выдаст ошибку уровня <constant>E_WARNING</constant>.
|
||
При добавлении в смещение строки новых символов присвоится только первый символ (байт).
|
||
Начиная с PHP 7.1.0 присваивание пустой строки вызовет фатальную ошибку. Раньше
|
||
присваивался нулевой байт (NULL).
|
||
</simpara>
|
||
</warning>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Внутренне строки PHP представлены массивами байтов. Поэтому
|
||
доступ или изменение строки по смещению небезопасны для многобайтовых данных
|
||
и выполняются только со строками в однобайтных кодировках,
|
||
например ISO-8859-1.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<note>
|
||
<simpara>
|
||
Начиная с PHP 7.1.0 попытка указать оператор пустого индекса
|
||
на пустой строке выдаст фатальную ошибку.
|
||
Раньше пустая строка преобразовывалась в массив без предупреждения.
|
||
</simpara>
|
||
</note>
|
||
|
||
<example>
|
||
<title>Примеры строк</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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';
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
</example>
|
||
|
||
<para>
|
||
Смещение в строке задают либо целым числом, либо целочисленной строкой,
|
||
иначе PHP выдаст предупреждение.
|
||
</para>
|
||
|
||
<example>
|
||
<!-- TODO Update for PHP 8.0 -->
|
||
<title>Пример недопустимого смещения строки</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?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']));
|
||
|
||
?>
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
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)
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
|
||
<note>
|
||
<para>
|
||
Доступ к переменным других типов (не включая массивы, а также
|
||
объекты, реализующие соответствующие интерфейсы) через операторы <literal>[]</literal>
|
||
или <literal>{}</literal> без предупреждения возвращает &null;.
|
||
</para>
|
||
</note>
|
||
|
||
<note>
|
||
<para>
|
||
Доступ к символам в строковых литералах получают
|
||
через операторы <literal>[]</literal> или <literal>{}</literal>.
|
||
</para>
|
||
</note>
|
||
|
||
<note>
|
||
<para>
|
||
Доступ к символам в строковых литералах
|
||
через оператор <literal>{}</literal> объявлен устаревшим в PHP 7.4
|
||
и удалён в PHP 8.0.
|
||
</para>
|
||
</note>
|
||
</sect3>
|
||
</sect2><!-- end syntax -->
|
||
|
||
<sect2 xml:id="language.types.string.useful-funcs">
|
||
<title>Полезные функции и операторы</title>
|
||
|
||
<para>
|
||
Строки разрешено объединять оператором «.» (точка).
|
||
Обратите внимание, оператор сложения «+» здесь <emphasis>не работает</emphasis>.
|
||
Подробнее об этом рассказано в разделе
|
||
«<link linkend="language.operators.string">Строковые операторы</link>».
|
||
</para>
|
||
|
||
<para>
|
||
В языке предусмотрен ряд полезных функций для манипулирования строками.
|
||
</para>
|
||
|
||
<simpara>
|
||
Общие функции описаны в разделе
|
||
«<link linkend="ref.strings">Функции для работы со строками</link>», а для расширенного поиска
|
||
и замены — «<link linkend="ref.pcre">Функции Perl-совместимых регулярных выражений</link>».
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Предусмотрены также <link linkend="ref.url">функции для работы с URL</link>
|
||
и функции шифрования или дешифрования строк (<link linkend="ref.sodium">Sodium</link> и <link linkend="ref.hash">Hash</link>).
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Наконец, смотрите также
|
||
<link linkend="ref.ctype">функции символьных типов</link>.
|
||
</simpara>
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.string.casting">
|
||
<title>Преобразование в строку</title>
|
||
|
||
<para>
|
||
Значение преобразовывают в строку приведением
|
||
через оператор <literal>(string)</literal> или функцией <function>strval</function>.
|
||
В выражениях, в которых требуется строка, преобразование выполняется автоматически.
|
||
Это выполняется во время вывода через языковые конструкции <function>echo</function>
|
||
или <function>print</function>, либо когда значение переменной сравнивается
|
||
со строкой. Разделы руководства
|
||
«<link linkend="language.types">Типы</link>»
|
||
и «<link linkend="language.types.type-juggling">Манипуляции с типами</link>»,
|
||
прояснят сказанное ниже. Смотрите также описание функции <function>settype</function>.
|
||
</para>
|
||
|
||
<para>
|
||
Значение <type>bool</type> &true; преобразовывается в строку
|
||
<literal>«1»</literal>, а логическое значение &false; преобразовывается
|
||
в <literal>«»</literal> (пустую строку). Такое поведение допускает преобразование значения
|
||
в обе стороны — из логического типа в строковый и наоборот.
|
||
</para>
|
||
|
||
<para>
|
||
Целое число (<type>int</type>) или число с плавающей точкой
|
||
(<type>float</type>) преобразовывается в строку, которая будет представлять число в текстовом виде
|
||
(включая экспоненциальную часть для чисел с плавающей точкой).
|
||
Большие числа с плавающей точкой преобразовываются в экспоненциальную запись (<literal>4.1E+6</literal>).
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Начиная с PHP 8.0.0 в качестве разделителя дробной части в числах
|
||
с плавающей точкой разрешено использовать только точку («<literal>.</literal>»).
|
||
До PHP 8.0.0 символ десятичной точки определялся в настройках языкового стандарта скрипта
|
||
(категория LC_NUMERIC). Смотрите функцию <function>setlocale</function>.
|
||
</para>
|
||
</note>
|
||
|
||
<para>
|
||
Массивы преобразовываются в строку <literal>«Array»</literal>.
|
||
Поэтому конструкции <function>echo</function> или <function>print</function>
|
||
не умеют без помощи функций отображать содержимое массива (<type>array</type>).
|
||
Чтобы просмотреть отдельный элемент, пользуются
|
||
синтаксисом <literal>echo $arr['foo']</literal>. Ниже будет рассказано о том,
|
||
как отобразить или просмотреть всё содержимое.
|
||
</para>
|
||
|
||
<para>
|
||
Для преобразования объекта (<literal>object</literal>) в строку (<type>string</type>)
|
||
определяют магический метод
|
||
<link linkend="language.oop5.magic">__toString</link>.
|
||
</para>
|
||
|
||
<para>
|
||
Ресурс (<type>resource</type>) преобразовывается в строку (<type>string</type>) вида
|
||
<literal>«Resource id #1»</literal>, где <literal>1</literal> —
|
||
это номер ресурса, который PHP назначает ресурсу (<type>resource</type>) во время исполнения кода.
|
||
И хотя она уникальна для текущего запуска скрипта (т. е. веб-запроса или
|
||
CLI-процесса) и не будет использована повторно для этого ресурса,
|
||
не стоит полагаться на эту строку, потому что её могут изменить в будущем.
|
||
Тип ресурса можно получить вызовом функции <function>get_resource_type</function>.
|
||
</para>
|
||
|
||
<para>
|
||
Значение &null; всегда преобразовывается в пустую строку.
|
||
</para>
|
||
|
||
<para>
|
||
Как указано выше, прямое преобразование в строку массивов, объектов
|
||
или ресурсов не даёт полезной информации о значении, кроме типа.
|
||
Более эффективные инструменты вывода значений для отладки этих типов — это функции
|
||
<function>print_r</function> и <function>var_dump</function>.
|
||
</para>
|
||
|
||
<para>
|
||
Бо́льшая часть значений в PHP преобразуема в строку для постоянного
|
||
хранения. Этот метод преобразования называется сериализацией. Сериализуют значения
|
||
функцией <function>serialize</function>.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="language.types.string.details">
|
||
|
||
<title>Подробные сведения о строковом типе</title>
|
||
|
||
<para>
|
||
Строковый тип (<type>string</type>) в PHP реализован в виде массива
|
||
байтов и целочисленного значения, содержащего длину буфера. В этой структуре
|
||
нет информации о том, как преобразовывать байты в символы,
|
||
эту задачу решает программист. Нет ограничений на значения, из которых состоит строка,
|
||
например, байт со значением <literal>0</literal> (NUL-байт) разрешён
|
||
где угодно в строке (однако рекомендовано учитывать, что ряд функций,
|
||
которые в этом руководстве названы «бинарно-небезопасными»,
|
||
передают строки библиотекам, которые игнорируют
|
||
данные после NUL-байта).
|
||
</para>
|
||
<para>
|
||
Такая природа строкового типа объясняет, почему в PHP нет отдельного
|
||
типа «byte» — строки выполняют эту роль. Функции, которые не возвращают текстовых данных, —
|
||
например, произвольный поток данных, считываемый из сетевого сокета, —
|
||
по-прежнему возвращают строки.
|
||
</para>
|
||
<para>
|
||
С учётом того, что PHP не диктует конкретную кодировку
|
||
для строк, может возникнуть вопрос: Как тогда кодируются строковые
|
||
литералы? Например, строка <literal>«á»</literal> эквивалентна
|
||
<literal>«\xE1»</literal> (ISO-8859-1), <literal>«\xC3\xA1»</literal>
|
||
(UTF-8, форма нормализации C), <literal>«\x61\xCC\x81»</literal>
|
||
(UTF-8, форма нормализации D) или другому возможному
|
||
представлению? Ответ такой: строка будет закодирована
|
||
способом, которым она закодирована в файле скрипта. Поэтому, если
|
||
скрипт записан в кодировке ISO-8859-1, то и строка будет закодирована в
|
||
ISO-8859-1 и т. д. Однако это правило не выполняется при включённом
|
||
режиме Zend Multibyte: скрипт записывают в произвольной
|
||
кодировке, объявляя её или полагаясь на автоопределение,
|
||
а затем конвертируют в конкретную внутреннюю кодировку, которая и будет
|
||
использована для строковых литералов.
|
||
Учтите, что на кодировку скрипта (или на внутреннюю кодировку, если
|
||
включён режим Zend Multibyte) накладывается ряд ограничений:
|
||
почти в каждом случае эта кодировка должна быть надмножеством кодировки ASCII,
|
||
например, UTF-8 или ISO-8859-1. Учтите также, что кодировки, зависящие
|
||
от состояния, где одни и те же значения байтов допустимы
|
||
в начальном и не начальном состоянии сдвига, создают риск проблем.
|
||
</para>
|
||
<para>
|
||
Строковые функции, чтобы быть полезными, пробуют предположить кодировку строки.
|
||
Единство в этом вопросе не помешало бы, но PHP-функции работают с текстом по-разному:
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
Одни — предполагают, что строка закодирована в какой-то
|
||
однобайтовой кодировке, но для корректной работы
|
||
им не нужно интерпретировать байты как конкретные символы.
|
||
Сюда попадают функции вроде <function>substr</function>,
|
||
<function>strpos</function>, <function>strlen</function>
|
||
и <function>strcmp</function>. Другой способ мышления об этих функциях —
|
||
представлять, что они оперируют буферами памяти, т. е. работают
|
||
непосредственно с байтами и их смещениями.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Другим — передаётся кодировка строки или они принимают
|
||
значение по умолчанию, если кодировку не передали.
|
||
Это относится к функции <function>htmlentities</function>
|
||
и большей части функций модуля <link linkend="book.mbstring">mbstring</link>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Третьи — работают с текущими настройками локали (смотрите
|
||
<function>setlocale</function>), но оперируют побайтово.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
Наконец четвёртые — предполагают, что строка использует
|
||
конкретную кодировку, обычно UTF-8. Сюда попадает бо́льшая часть
|
||
функций из модулей <link linkend="book.intl">intl</link>
|
||
и <link linkend="book.pcre">PCRE</link>
|
||
(для последнего — только при указании модификатора <literal>u</literal>).
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
В конечном счёте, программа будет работать с кодировкой Unicode правильно,
|
||
если старательно избегать функций,
|
||
которые не будут работать с Unicode-строками или повредят данные, и вызывать вместо них те,
|
||
которые ведут себя корректно, обычно это функции из модулей <link linkend="book.intl">intl</link>
|
||
и <link linkend="book.mbstring">mbstring</link>.
|
||
Однако работа с функциями, которые умеют обрабатывать Unicode, —
|
||
это только начало. Независимо от того, какие функции предлагает
|
||
язык, рекомендовано знать спецификацию Unicode. Например, программа,
|
||
которая предполагает существование только прописных и строчных букв,
|
||
делает неверное предположение.
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|