Одинарные кавычки
Простейший способ определить строку — это заключить её в одинарные кавычки
(символ '
).
Чтобы записать внутри строки буквальную одинарную кавычку, её необходимо заэкранировать обратным слешем
(\
). Когда нужно написать сам обратный слеш, его дублируют
(\\
). Во всех остальных случаях обратный слеш будет
интерпретирован как буквальный обратный слеш: то есть
последовательности вроде \r
или
\n
не будут рассматриваться как управляющие, а будут выведены как есть.
Замечание:
Переменные и управляющие последовательности для специальных символов,
заключённые в одинарные кавычки, — не обрабатываются,
в отличие от синтаксиса двойных кавычек
и heredoc.
Двойные кавычки
Если строка заключена в двойные кавычки ("), 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
Третий способ определения строк — это использование 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:
Если закрывающий идентификатор смещён дальше, чем любая строка тела,
будет выброшено 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
Если закрывающий идентификатор отбит символом табуляции,
то в теле также можно использовать табуляции. Однако табуляции и пробелы относительно закрывающего идентификатора и тела
не должны смешиваться (вплоть до закрывающего идентификатора).
В любом из этих случаев будет выброшено исключение ParseError.
Эти ограничения на пробельные отступы были включены, потому что смешивание табуляций
и пробелов для отступов вредно для разбора.
Пример #3 Другой отступ для закрывающего идентификатора тела (пробелов)
<?php
// Весь следующий код не работает.
// Другой отступ для закрывающего идентификатора (табов) тела (пробелов)
{
echo <<<END
a
END;
}
// смешивание пробелов и табуляции в теле
{
echo <<<END
a
END;
}
// смешивание пробелов и табуляции в закрывающем идентификаторе
{
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 продолжит его поиск
дальше. Если в этом случае верный закрывающий идентификатор так и не будет найден,
то это вызовет ошибку парсинга с номером строки в конце скрипта.
Пример #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
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;
}
?>
Обработка переменных
Если строка указывается в двойных кавычках, либо синтаксисом heredoc,
переменные внутри неё обрабатываются.
Существует два типа синтаксиса:
простой и
сложный.
Простой синтаксис легче и удобнее. Он помогает
в обработке переменной, значения массива (array) или
свойства объекта (object) с минимумом усилий.
Сложный синтаксис может быть определён
по фигурным скобкам, окружающим выражение.
Простой синтаксис
Если интерпретатор встречает знак доллара ($
), он захватывает настолько
много символов, насколько возможно, чтобы сформировать правильное имя переменной. Если
вы хотите точно определить конец имени, заключайте имя переменной в фигурные скобки.
Аналогично могут быть обработаны элемент массива (array) или свойство
объекта (object). В индексах массива закрывающая квадратная скобка
(]
) обозначает конец определения индекса. Для свойств объекта
применяются те же правила, что и для простых переменных.
Пример #15 Пример простого синтаксиса
<?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."; // Не сработает
?>
Результат выполнения данного примера:
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 .
В 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
Для чего-то более сложного лучше пользоваться сложным синтаксисом.
Сложный (фигурный) синтаксис
Он называется сложным не потому, что труден в понимании,
а потому что позволяет использовать сложные выражения.
Любая скалярная переменная, элемент массива или отображаемое в строку свойство объекта
могут быть представлены в строке этим синтаксисом. Выражение записывается так же,
как и вне строки, а затем заключается в фигурные скобки: {
и }
.
Поскольку знак {
не может быть экранирован, этот синтаксис будет
распознаваться только тогда, когда знак $
следует непосредственно за знаком {
.
Экранируйте знак доллара {\$
, чтобы напечатать: {$
.
Несколько поясняющих примеров:
С помощью этого синтаксиса также возможен доступ к свойствам объекта внутри строк.
Замечание:
Значение внутри {$}
, к которому будет выполняться доступ из функций,
вызовов методов, статических переменных класса и констант класса, будет интерпретироваться как имя
переменной в области, в которой определена строка. Синтаксис
одинарных фигурных скобок ({}
) не будет работать
для доступа к значениям функций, методов,
констант классов или статических переменных класса.
Доступ к символу в строке и его изменение
Символы в строках можно использовать и модифицировать,
определив их смещение относительно начала строки, начиная с
нуля, в квадратных скобках после строки, например, $str[42].
Для этой цели о строке думают, как о массиве символов.
Если нужно получить или заменить более 1 символа, можно использовать
функции 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';
?>
Смещение в строке должно задаваться либо целым числом, либо строкой,
содержащей цифры, иначе будет выдаваться предупреждение.
Пример #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.