Рекомендации: работа с длинными многострочными строками в PHP?

177

Примечание: извините, если это очень простой вопрос, но я несколько одержимо компульсивен в отношении форматирования моего кода.

У меня есть класс, который имеет функцию, которая возвращает строку, которая будет составлять основной текст письма. Я хочу, чтобы этот текст был отформатирован так, чтобы он выглядел прямо в электронном письме, но также и чтобы мой код не выглядел в стиле фанк. Вот что я имею в виду:

class Something
{
    public function getEmailText($vars)
    {
        $text = 'Hello ' . $vars->name . ",

The second line starts two lines below.

I also don't want any spaces before the new line, so it's butted up against the left side of the screen.";
        return $text;
    }
}

но это также может быть записано как:

public function getEmailText($vars)
{
    $text = "Hello {$vars->name},\n\rThe second line starts two lines below.\n\rI also don't want any spaces before the new line, so it's butted up against the left side of the screen.";
    return $text;
}

но как обстоят дела с новыми линиями и возвратом каретки? Какая разница? Это \n\nэквивалент \r\rили \n\r? Что я должен использовать, когда я создаю разрыв между строками?

Тогда есть опция буферизации вывода и синтаксиса heredoc.

Как вы справляетесь с использованием длинных многострочных строк в ваших объектах?

Андрей
источник
3
Я всегда думал, что \ n - это новая строка в Unix \ r - это новая строка в MacOS до OS / X, а \ r \ n - новая строка в Windows. Кроме того, учитывая, что это будет строка, отображаемая в сообщении электронной почты, вы должны убедиться, что какой бы способ вы ни делали, он будет корректно отображаться в большинстве командных почтовых клиентов. Подсказка: Outlook удаляет лишние символы новой строки в некоторых случаях, поэтому вы не всегда получите то, что ожидаете.
Кенни Дробнак
1
Не уверен, что все это так важно, но изначально два символа «новой строки» появились, когда у вас была физическая пишущая машинка, которая использовала два символа. Один для возврата каретки в левую часть страницы (CR - 0xD), а другой - для перехода страницы на следующую строку (LF - 0xA.) Я уверен, что есть люди, которые знают об этом больше тем не мение.
Mkgrunder

Ответы:

289

Вы должны использовать HEREDOC или NOWDOC.

$var = "some text";
$text = <<<EOT
  Place your text between the EOT. It's
  the delimiter that ends the text
  of your multiline string.
  $var
EOT;

Разница между Heredoc и Nowdoc заключается в том, что код PHP, встроенный в heredoc, выполняется, а код PHP в Nowdoc будет распечатан как есть.

$var = "foo";
$text = <<<'EOT'
  My $var
EOT;

В этом случае $ text будет иметь значение My $var.

Примечание: перед закрытием EOT;не должно быть пробелов или табуляции. в противном случае вы получите ошибку

Хафдан
источник
Зачем? Потому что все между первым EOT и вторым считается строкой как есть. Это означает, что вам не нужно ставить обратную косую черту во всех ваших многострочных строках. @Fabian: В чем разница между HEREDOC и NOWDOC, или это одно и то же?
Кенни Дробнак
4
@powtac: Нет, потому что он должен быть на новой строке, чтобы покончить с наследственностью. В частности, перед ним не должно быть EOT;пробелов.
Powerlord
Я добавил объяснение для Nowdoc.
Халфдан
6
@halfdan, я что-то упустил? Зачем беспокоиться о heredocs и nowdocs, когда мы можем просто ввести клавишу «Ввод» и заключить многострочную строку в кавычки, как обычную строку?
Pacerier
3
Просто добавьте это в свой ответ: перед последним EOT;не должно быть пробелов или табуляции. в противном случае вы получите ошибку.
Шнд
44

Я использую подобную систему как pix0r, и я думаю, что это делает код вполне читабельным. Иногда я на самом деле зашел бы настолько далеко, что разделял разрывы строк в двойных кавычках и использовал одинарные кавычки для остальной части строки. Таким образом, они выделяются из остального текста, а переменные также выделяются лучше, если вы используете конкатенацию, а не вставляете их в двойные кавычки. Так что я мог бы сделать что-то вроде этого с вашим оригинальным примером:

$text = 'Hello ' . $vars->name . ','
      . "\r\n\r\n"
      . 'The second line starts two lines below.'
      . "\r\n\r\n"
      . 'I also don\'t want any spaces before the new line,'
      . ' so it\'s butted up against the left side of the screen.';

return $text;

Что касается разрывов строк, для электронной почты вы всегда должны использовать \ r \ n. PHP_EOL для файлов, которые предназначены для использования в той же операционной системе, на которой работает php.

Cvuorinen
источник
Вы установили этот отступ в вашей IDE (чтобы выровнять многострочную строку по каждой части)?
Кшиштоф Тшос
25

Я использую шаблоны для длинного текста:

email-template.txt содержит

hello {name}!
how are you? 

В PHP я делаю это:

$email = file_get_contents('email-template.txt');
$email = str_replace('{name},', 'Simon', $email);
powtac
источник
интересно ... где вы храните ваши шаблоны в структуре каталогов веб-приложения?
Андрей
Мой код просто демо. Для огромного веб-приложения вы можете использовать такую ​​структуру, как / templates / emails /, / templates / userfeedback /. Но если у вас есть больше вещей, я бы порекомендовал полную систему шаблонов, как SMARTY.
Powtac
Dwoo dwoo.org - это приличная SMARTY-совместимая система шаблонов PHP, которую некоторые считают хорошей преемницей (начиналась на PHP5, поэтому нет багажа PHP4).
micahwittman
19

Добавлять \nи / или \rв середине строки и иметь очень длинную строку кода, как во втором примере, кажется неправильным: когда вы читаете код, вы не видите результат, и вам приходится прокручивать ,

В подобных ситуациях я всегда использую Heredoc (или Nowdoc, если использую PHP> = 5.3) : легко писать, легко читать, нет необходимости в длинных строках, ...

Например :

$var = 'World';
$str = <<<MARKER
this is a very
long string that
doesn't require
horizontal scrolling, 
and interpolates variables :
Hello, $var!
MARKER;

Только одно: конечный маркер (и ' ;' после него) должен быть единственным на его строке: ни пробела, ни табуляции ни до, ни после!

Паскаль МАРТИН
источник
12

Конечно, вы можете использовать HEREDOC, но с точки зрения читабельности кода это не намного лучше, чем в первом примере, заключая строку в несколько строк.

Если вы действительно хотите, чтобы ваша многострочная строка хорошо выглядела и хорошо сочеталась с вашим кодом, я бы порекомендовал объединить строки вместе:

$text = "Hello, {$vars->name},\r\n\r\n"
    . "The second line starts two lines below.\r\n"
    . ".. Third line... etc";

Это может быть немного медленнее, чем HEREDOC или многострочная строка, но она будет хорошо сочетаться с отступами вашего кода и облегчит чтение.

pix0r
источник
9

Мне больше нравится этот метод для Javascript, но его стоит включить, потому что он еще не был упомянут.

$var = "pizza";

$text = implode(" ", [
  "I love me some",
  "really large",
  $var,
  "pies.",
]);

// "I love me some really large pizza pies."

Что касается мелких вещей, я считаю, что часто легче работать со структурами массивов по сравнению со связанными строками.

Связано: взорваться против конкат производительности

Джонни
источник
1

Тот, кто считает, что

"abc\n" . "def\n"

многострочная строка неверна. Это две строки с оператором конкатенации, а не многострочная. Такие объединенные строки нельзя использовать, например, в качестве ключей предопределенных массивов. К сожалению, php не предлагает реальные многострочные строки в виде

"abc\n"
"def\n"

только HEREDOCи NOWDOCсинтаксис, который больше подходит для шаблонов, поскольку отступ вложенного кода нарушается таким синтаксисом.

Дмитрий Синцов
источник
1

Вы также можете использовать:

<?php
ob_start();
echo "some text";
echo "\n";

// you can also use: 
?> 
some text can be also written here, or maybe HTML:
<div>whatever<\div>
<?php
echo "you can basically write whatever you want";
// and then: 
$long_text = ob_get_clean();
Алон Гулдман
источник
0

Что касается вашего вопроса о переводе строки и возврате каретки:

Я бы порекомендовал использовать предопределенную глобальную константу PHP_EOL, поскольку она решит любые проблемы кросс-платформенной совместимости.

Этот вопрос был поднят на SO заранее, и вы можете узнать больше информации, прочитав « Когда я использую PHP константу PHP_EOL »

Кори Баллу
источник
1
Комментарий к этому ответу предполагает, что я должен использовать \ r \ n для новых строк в электронных письмах: stackoverflow.com/questions/128560/…
Эндрю
0

но как обстоят дела с новыми линиями и возвратом каретки? Какая разница? Является ли \ n \ n эквивалентом \ r \ r или \ n \ r? Что я должен использовать, когда я создаю разрыв между строками?

Похоже, здесь никто не ответил на этот вопрос, поэтому я здесь.

\r представляет «возврат каретки»

\n представляет «перевод строки»

Истинная причина для них восходит к пишущим машинкам. Когда вы печатаете, «каретка» будет медленно скользить символ за символом вправо от пишущей машинки. Когда вы дойдете до конца линии, вы вернете карету и перейдете на новую линию . Чтобы перейти на новую строку, вы должны щелкнуть рычагом, который подает строки в пишущий тип. Таким образом, эти действия, вместе взятые, были названы переводом строки возврата каретки . Так что буквально

Перевод строки \n, означает переход к следующей строке.

Возврат каретки \r, означает перемещение курсора в начало строки.

В конечном итоге Hello\n\nWorldдолжен появиться следующий вывод на экран:

Hello

     World

Где как Hello\r\rWorldдолжно привести к следующему выводу .

Только при объединении двух символов \r\nу вас есть общее понимание известной линии. IE Hello\r\nWorldдолжен привести к:

Hello
World

И, конечно \n\r, приведет к тому же визуальному выводу, что и \r\n.

Изначально компьютеры взяли \rи в \nбуквальном смысле слова. Однако в наши дни поддержка возврата каретки невелика. Обычно в каждой системе вы можете использовать \nее самостоятельно. Это никогда не зависит от ОС, но зависит от того, что вы просматриваете.

Тем не менее я всегда советую использовать \r\nвезде, где вы можете!

Sancarn
источник