Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Тонкости heredoc в PHP

В PHP, как и в некоторых других языках (Bash, Perl) есть конструкция heredoc — это способ задать многострочную строку. Посмотрите как удобно, не нужно экранировать кавычки:

// это PHP
$str = <<<STR
Привет, я строка "в кавычках",
'в апострофах'.
STR;

Но меня всегда раздражало, что завершающий ограничитель приходится прижимать к левому краю, пробел и табуляция дают ошибку (хотя в Perl относительно недавно разрешили делать отступы для этой конструкции).

Сегодня, в очередной раз раздражаясь по этому поводу, я решил попробовать использовать неразрывные пробелы (Alt Right+Space в раскладке Бирмана), получилось, работает даже в PHP 4.4.4. Подходит, конечно, для исходников в кодировке UTF-8. Надеюсь, вы в другой кодировке их уже и не пишете.

Правда, строки внутри, конечно, менять нельзя, но эта конструкция часто используется вместе с HTML, а ему отступы неинтересны.

$str = <<<    HTML
    <table>
        <tr class="row"><td>'Привет'</td></tr>
    </table>
    HTML;

Только не забудьте, что отступы надо делать и в начальной конструкции, и в конечной.

Ctrl ←House M.D.
13 комментариев
Victor Grinchik (wiktar.com) 2010

Спасибо! Это будет мне ОЧЕНЬ полезно!

Евгений Степанищев (bolknote.ru) 2010

Комментарий для wiktar.com:

Рад, что это ещё кому-то полезно.

Gregory 2010

Спасибо, действительно удобно.

Victor Grinchik (wiktar.com) 2010

Я привык отбивать нулевой уровень вложенности пробелами (первым считаю <?php ?>, да и лучше выглядит, чем прижатый к номерам строк). Поэтому прижимать завершение комментария было не эстетично.

Я только за переносимость боюсь. Всё же, не у всех такая возможность неразрывные пробелы ставить есть. И не каждый поймёт, что там именн они.

Евгений Степанищев (bolknote.ru) 2010

Комментарий для wiktar.com:

Всё же, не у всех такая возможность неразрывные пробелы ставить есть.

Такая — не у всех, но на других ОС есть свои решения. Где-то были версии для Линуксов, а на сайте Ильи есть версия и под Мак.

И не каждый поймёт, что там именно они.

Конечно. В code style это придётся дописать. Я это, например, использовал недавно в бесплатном проекте с закрытыми исходниками и планирую использовать в движке своего сайта.

В «Яндексе» использовать не планирую.

Victor Grinchik (wiktar.com) 2010

Яндекс использует PHP?

Евгений Степанищев (bolknote.ru) 2010

Комментарий для wiktar.com:

Да:

http://moikrug.ru/
http://nano.yandex.ru/project/yarss/
http://school-wiki.yandex.ru/HomePage

ну и так далее

maxim.vuets.name 2010

хотя в Perl относительно недавно разрешили делать отступы для этой конструкции

Каким образом?

Вероятно, следующие Perl-трюки можно будет применить и в PHP (я его не знаю просто).

  1. Завершающий ограничитель реально сдвинуть без модификации самой строки. Для этого нужно сам ограничитель объявить с пробелами. То есть:

    $str = <<’ EOT’;
multi-line text
    EOT

  1. Саму строку тоже можно безболезненно отбить пробелами слева. Нужно лишь её пост-обработать. (Это накладные, фактически бесполезные расходы, но красота требует жертв.)

($str = <<EOT) =~ s/^\s{4}//gm;
    hey there!
    what’s up?
EOT

Евгений Степанищев (bolknote.ru) 2010

Комментарий для maxim.vuets.name:

Каким образом?

Там разрешено двигать всю конструкцию.

Саму строку тоже можно безболезненно отбить пробелами слева. Нужно лишь её пост-обработать. (Это накладные, фактически бесполезные расходы, но красота требует жертв.)

В PHP так коротко не получится, а всё сверх этого уже слишком длинно и некрасиво. Красиво плюс некрасиво = некрасиво.

maxim.vuets.name 2010

Комментарий для Евгения Степанищева:

Либо всё-таки нельзя, либо я чего-то не понял. В 5.12.1 не работает.

$s = <<EOT;
string
  EOT

В результате: Can’t find string terminator «EOT» anywhere before EOF at a.pl line 1, что логично.

Евгений Степанищев (bolknote.ru) 2010

Комментарий для maxim.vuets.name:

А почему вы решили, что в Perl это именно так должно делаться? И почему вы не прочитали документацию?

Я, кстати, давно не интересовался Перлом и не уверен, что отступы в here-doc не конструкция из Perl6.

maxim.vuets.name 2010

Комментарий для Евгения Степанищева:

Решил так с ваших слов: «хотя в Perl относительно недавно разрешили делать отступы для этой конструкции». Я удивился, ещё раз проверил, переспросил. Короче, в пятом Перле нельзя. А в шестом, действительно, можно. (Шестой Перл настолько иной, что называть его просто Перлом опрометчиво.)

Евгений Степанищев (bolknote.ru) 2010

Комментарий для maxim.vuets.name:

Шестой Перл настолько иной, что называть его просто Перлом опрометчиво

Я знаю, я иногда на него всё же смотрю. Но из моих слов никак не следует, что отступы можно делать именно тем способом, который вы попробовали.