Кращі практики: робота з довгими багаторядковими рядками в 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, коли ми можемо просто набрати клавішу "Enter" і оточити багаторядковий рядок цитатами так само, як звичайний рядок?
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.


Ви встановили цей відступ у вашій IDE (щоб встановити багатоскладовий рядок, вирівняний до кожної частини)?
Кшиштоф Тцос

25

Я використовую шаблони для довгого тексту:

email-template.txt містить

hello {name}!
how are you? 

У PHP я роблю це:

$email = file_get_contents('email-template.txt');
$email = str_replace('{name},', 'Simon', $email);

цікаво ... де ви зберігаєте свої шаблони в структурі каталогів веб-програми?
Андрій

Мій код - лише демонстрація. Для величезного веб-додатка ви можете використовувати таку структуру, як / шаблони / електронні листи /, / шаблони / 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 або багаторядковий рядок, але це буде добре відповідати відступі вашого коду та полегшує його читання.


9

Мені цей метод трохи більше подобається для Javascript, але він, здається, варто включити сюди, оскільки він ще не згадувався.

$var = "pizza";

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

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

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

Пов'язане: виконання implode vs concat


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де завгодно!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.