Рядки

Рядок (string) – це набір символів, у якому символ – це те саме, що й байт. Тобто PHP підтримує набір лише 256 символів і тому не пропонує вбудовану підтримку кодування Unicode. Докладніше про це розказано у розділі «Детальна інформація про рядковий тип».

Зауваження: У 32-бітових збірках розмір рядка (string) обмежений 2 ГБ (2 147 483 647 байт максимум).

Синтаксис

Рядковий літерал визначають чотирма способами:

Одинарні лапки

Найпростіший спосіб визначити рядок - це укласти його в одинарні лапки (символ '

Щоб записати всередині рядка буквальну одинарну лапку, її екранують зворотним слішем (\). Щоб записати сам зворотний сліш, його дублюють (\). В інших випадках зворотний сліш буде оброблений як буквальний зворотний сліш: тобто послідовності на кшталт \rили\n не розглядатимуться як управляючі, а будуть виведені як записані.

Зауваження Змінні і керуючі послідовності службових символів, укладені в одинарні лапки, - не обробляються, на відміну синтаксису подвійних лапок і heredoc

Loading...

Подвійні лапки

Якщо рядок укладено в подвійні лапки ("), PHP розпізнає наступні керуючі послідовності службових символів:

Керуючі послідовності

ПоследовательностьЗначение
\nновий рядок (LF або 0x0A (10) в ASCII)
\rповернення каретки (CR або 0x0D (13) до ASCII)
\tгоризонтальна табуляція (HT або 0x09 (9) ASCII)
\vвертикальна табуляція (VT або 0x0B (11) ASCII)
\eescape-знак (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

Loading...

Результат виконання наведеного прикладу в PHP 7.3:

a
     b
    c

  a
 b
c

Якщо ідентифікатор, що закриває, зміщений далі хоча б одного рядка тіла, буде викинуто виняток ParseError :

Приклад #2 Відступу ідентифікатора, що закриває, не можна відступати більше, ніж іншим рядкам тіла

Loading...

Результат виконання наведеного прикладу в 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 Інший відступ для тіла, що закриває ідентифікатора (пробілів)

Loading...

Результат виконання наведеного прикладу в PHP 7.3:

PHP Parse error:  Invalid indentation - tabs and spaces cannot be mixed in example.php line 8

За ідентифікатором основного рядка, що закриває, не обов'язково ставити крапку з комою або новий рядок. Наприклад, починаючи з PHP 7.3.0 дозволено наступний код:

Приклад #4 Продовження виразу після ідентифікатора, що закриває

Loading...

Результат виконання наведеного прикладу в PHP 7.3:

array(2) {
  [0] =>
  string(11) "a
  b
    c"
  [1] =>
  string(5) "d e f"
}

Увага

Якщо ідентифікатор, що закриває, знайдено на початку рядка, навіть якщо це частина слова, парсер прийме його за закриваючий ідентифікатор і викине виняток ParseError

Приклад #5 Ідентифікатор, що закриває, в тілі тексту провокує виключення ParseError

Loading...

Результат виконання наведеного прикладу в 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

Loading...

Приклад #7 Приклад правильного синтаксису, навіть до PHP 7.3.0

Loading...

У цьомудокументі зі змінними не можна використовувати для ініціалізації властивостей класу.

Heredoc-текст хоч і не укладений у подвійні лапки, поводиться як рядок у подвійних лапках. Тобто в ньому лапки не екранують, але перелічені керуючі коди, як і раніше, дозволено вказувати. Змінні розгортаються, але у висловлюваннях зі складними змінними всередині неї працюють так само уважно, як і при роботі з рядками.

Приклад #8 Приклад визначення heredoc-рядка

Loading...

Результат виконання наведеного прикладу:

Меня зовут "Имярек". Я печатаю Foo.
Теперь, я вывожу Bar2.
Это должно вывести заглавную букву 'A': A

Heredoc-синтаксис дозволено також для передачі даних через аргументи функції:

Приклад #9 Приклад heredoc-синтаксису з аргументами

Loading...

Дозволено ініціалізувати статичні змінні та властивості або константи класу в heredoc-синтаксисі:

Приклад #10 Ініціалізація статичних змінних heredoc-синтаксисом

Loading...

Дозволено також оточувати йогоdoc-ідентифікатор подвійними лапками:

Приклад #11 Подвійні лапки в heredoc

Loading...

Nowdoc

Nowdoc - це те ж для рядків у одинарних лапках, що й heredoc для рядків у подвійних лапках. Nowdoc схожий на heredoc, але всередині нього не виконуються підстановки. Конструкція легко вбудовує PHP-код або інші великі текстові блоки без попереднього екранування. У цьому він частково схожий на SGML-конструкцію <![CDATA[ ]]>в тому, що він оголошує блок тексту, який не вимагає обробки.

Nowdoc задають таку ж послідовність символів <<<, що і в heredoc, але наступний за нею ідентифікатор беруть в одинарні лапки, наприклад, <<<'EOT'. Умови, які поширюються на ідентифікатори heredoc-синтаксису, дійсні також і для синтаксису nowdoc, а більше інших ті, що відносяться до ідентифікатора, що закриває.

Приклад #12 Приклад nowdoc-синтаксису

Loading...

Результат виконання наведеного прикладу:

Приклад текста,
занимающего несколько строк,
написанного синтаксисом nowdoc. Обратные слеши выводятся без обработки,
наПриклад, \\ и \'.

Приклад #13 Nowdoc зі змінними рядками з подвійними лапками

Loading...

Результат виконання наведеного прикладу:

Меня зовут "$name". Я печатаю $foo->foo.
Теперь я печатаю {$foo->bar[1]}.
Это не должно вывести заглавную 'A': \x41

Приклад #14 Приклад зі статичними даними

Loading...

Синтаксичний аналіз змінних

Якщо рядок вказується у подвійних лапках, або синтаксисом heredoc, змінні усередині неї обробляються.

У PHP передбачили два види синтаксису для вказівки змінних у рядках: простий і складний. Простим синтаксисом користуються частіше, з ним легко вбудовувати змінну значення масиву (array) або властивість об'єкта (object) з мінімумом зусиль.

Складний синтаксис легко визначити за фігурними дужками, що оточують вираз.

Простий синтаксис

Якщо інтерпретатор зустрічає знак долара ($), він захоплює якнайбільше символів, щоб сформувати правильне ім'я змінної. Якщо потрібно точно визначити кінець імені, ім'я змінної беруть у фігурні дужки.

Loading...

Результат виконання наведеного прикладу:

He drank some apple juice.
He drank some juice made of .
He drank some juice made of apples.

Аналогічно буде проаналізовано індекс масиву (array) чи властивість об'єкта (object). В індексах масиву квадратна дужка, що закриває (]) означає кінець визначення індексу. На властивості об'єкта поширюються самі правила, як і прості змінні.

Приклад #15 Приклад простого синтаксису

Loading...

Результат виконання наведеного прикладу:

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 Негативні числові індекси

Loading...

Результат виконання наведеного прикладу:

Символ с индексом -2 равен n.
Изменение символа на позиции -3 на «o» даёт следующую строку: strong

Для виразів, які складніші за ці, краще користуватися складним синтаксисом.

Складний (фігурний) синтаксис

Він називається складним не через складність синтаксису, лише тому, що дозволяє писати складні висловлювання.

Скалярна змінна, елемент масиву або властивість об'єкта, що відображається в рядок, дозволено вказувати в рядку цим синтаксисом. Вираз записується як і поза рядком, а потім береться у фігурні дужки: {и}. Оскільки знак { неможливо екранувати, цей синтаксис розпізнаватиметься лише тоді, коли знак $ йде безпосередньо за знаком {. Щоб отримати літерал {$знак долара екранують {\$. Приклади, що пояснюють:

Loading...

Дозволено отримувати доступ до властивостей класу, вказуючи змінні всередині рядків, записаних цим синтаксисом.

Loading...

Результат виконання наведеного прикладу:

I am bar.
I am bar.

Зауваження :

Значение внутри литерала{$}, До якого отримують доступ із функцій, викликів методів, статичних змінних класу та констант класу, інтерпретується як ім'я змінної в області, в якій визначено рядок. Синтаксис одинарних фігурних дужок ({}) не працюватиме для доступу до значень функцій, методів, констант класів або статичних змінних класу.

Loading...

Доступ та зміна символу в рядку

Щоб отримати доступ і змінити символ у рядку, потрібно у квадратних дужках після змінної визначити зміщення шуканого символу щодо початку рядка починаючи з нуля, наприклад $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 Приклади рядків

Loading...

Зміщення у рядку задають або цілим числом, або цілим рядком, інакше буде видано попередження.

Приклад #18 Приклад неприпустимого усунення рядка

Loading...

Результат виконання наведеного прикладу:

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-сумісних регулярних виразів».

Передбачені також функції для роботи з 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) визначають магічний метод __function toString() { [native code] }

Ресурс (resource) перетворюється на рядок (string) виду «Resource id #1», где — це номер ресурсу, який PHP призначає ресурсу під час виконання коду. І хоча вона унікальна для поточного запуску скрипта (тобто веб-запиту або CLI-процесу) і не буде використана повторно для цього ресурсу, не варто покладатися на цей рядок, тому що його можуть змінити в майбутньому. Тип ресурсу можна отримати викликом функції get_resource_type()

Значение**null** завжди перетворюється на порожній рядок.

Як зазначено вище, пряме перетворення на рядок масивів, об'єктів чи ресурсів не дає корисної інформації про значення, крім типу. Більш ефективні інструменти виведення значень для налагодження цих типів – це функції print_r() і var_dump()

Більшість значень PHP перетворюється на рядок для постійного зберігання. Цей спосіб перетворення називається серіалізацією. Серіалізують значення функцією serialize()

Детальна інформація про рядковий тип

Рядковий тип (string) в PHP реалізований у вигляді масиву байтів і цілого значення, що містить довжину буфера. У цій структурі немає інформації про те, як перетворювати байти на символи, це завдання вирішує програміст. Немає обмежень на значення, з яких складається рядок, наприклад, байт зі значенням (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-функції працюють із текстом по-різному:

  • Одні — припускають, що рядок закодований в якомусь однобайтовому кодуванні, але для коректної роботи їм не потрібно інтерпретувати байти як конкретні символи. Сюди потрапляють функції на кшталтsubstr() strpos() strlen() і strcmp(). Інший спосіб мислення про ці функції - уявляти, що вони оперують буферами пам'яті, тобто працюють безпосередньо з байтами та їх зміщеннями.
  • Іншим — передається кодування рядка або вони набирають значення за умовчанням, якщо кодування не передали. Це стосується функціїhtmlentities()та більшу частину функцій модуляmbstring
  • Треті — працюють із поточними налаштуваннями локалі (дивітьсяsetlocale()), але оперують побайтово.
  • Нарешті, четверті — припускають, що рядок використовує конкретне кодування, зазвичай UTF-8. Сюди потрапляє більша частина функцій із модулівintl і PCRE(для останнього - тільки при вказівці модифікатораu

В кінцевому рахунку, програма буде працювати з кодуванням Unicode правильно, якщо старанно уникати функцій, які не будуть працювати з Unicode-рядками або пошкодять дані, і викликати замість них ті, які поводяться коректно, зазвичай це функції з модулів intl і mbstring. Однак робота з функціями, які вміють обробляти Unicode, це лише початок. Незалежно від того, які функції пропонує мова, рекомендовано знати специфікацію Unicode. Наприклад, програма, яка передбачає існування лише великих і малих літер, робить неправильне припущення.