Best Practices: Arbeiten mit langen, mehrzeiligen Zeichenfolgen in PHP?

177

Hinweis: Es tut mir leid, wenn dies eine äußerst einfache Frage ist, aber ich bin etwas zwanghaft in Bezug auf die Formatierung meines Codes.

Ich habe eine Klasse, die eine Funktion hat, die eine Zeichenfolge zurückgibt, die den Haupttext einer E-Mail bildet. Ich möchte, dass dieser Text so formatiert wird, dass er in der E-Mail richtig aussieht, aber auch, damit mein Code nicht funky aussieht. Folgendes meine ich:

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;
    }
}

es könnte aber auch geschrieben werden als:

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;
}

Aber wie sieht es mit neuen Linien und Wagenrückläufen aus? Was ist der Unterschied? Ist \n\ndas Äquivalent \r\roder \n\r? Was soll ich verwenden, wenn ich eine Linienlücke zwischen Linien erstelle?

Dann gibt es die Möglichkeit der Ausgabepufferung und der Heredoc-Syntax.

Wie gehen Sie mit langen mehrzeiligen Zeichenfolgen in Ihren Objekten um?

Andrew
quelle
3
Ich hatte immer gedacht, dass \ n unter Unix Newline ist. \ R ist Newline unter MacOS vor OS / X und \ r \ n ist Newline unter Windows. Wenn Sie bedenken, dass dies eine Zeichenfolge ist, die in einer E-Mail-Nachricht angezeigt wird, sollten Sie sicherstellen, dass die meisten Befehls-Mail-Clients auf jede Art und Weise korrekt angezeigt werden. Tipp: Outlook entfernt in einigen Fällen zusätzliche Zeilenumbrüche, sodass Sie nicht immer das bekommen, was Sie erwarten.
Kenny Drobnack
1
Ich bin mir nicht sicher, ob das alles so wichtig ist, aber ursprünglich stammten die beiden "Zeilenumbrüche", als Sie eine physische Schreibmaschine hatten, die zwei Zeichen verwendete. Eine, um den Wagen wieder auf die linke Seite der Seite zu stellen (CR - 0xD), und eine, die dazu führte, dass die Seite in die nächste Zeile ging (LF - 0xA). Ich bin sicher, dass es Leute gibt, die mehr darüber wissen jedoch.
mkgrunder

Antworten:

288

Sie sollten HEREDOC oder NOWDOC verwenden.

$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;

Der Unterschied zwischen Heredoc und Nowdoc besteht darin, dass in einen Heredoc eingebetteter PHP-Code ausgeführt wird, während PHP-Code in Nowdoc unverändert ausgedruckt wird.

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

In diesem Fall hat $ text den Wert My $var.

Hinweis: Vor dem Schließen EOT;sollten keine Leerzeichen oder Tabulatoren vorhanden sein. Andernfalls wird eine Fehlermeldung angezeigt

Halfdan
quelle
Warum? Weil alles zwischen dem ersten EOT und dem zweiten als String wie er ist betrachtet wird. Dies bedeutet, dass Sie Ihren mehrzeiligen Zeichenfolgen keinen Backslash n hinzufügen müssen. @Fabian: Was ist der Unterschied zwischen einem HEREDOC und einem NOWDOC oder sind sie dasselbe?
Kenny Drobnack
4
@powtac: Nein, weil es in einer neuen Zeile sein muss, um einen Heredoc zu beenden. Insbesondere muss es EOT;keine Leerzeichen davor geben.
Powerlord
Ich habe eine Erklärung für Nowdoc hinzugefügt.
Halfdan
6
@halfdan, vermisse ich etwas? Warum sich mit Heredocs und Nowdocs beschäftigen, wenn wir einfach die Eingabetaste eingeben und die mehrzeilige Zeichenfolge wie eine normale Zeichenfolge mit Anführungszeichen umgeben können?
Pacerier
3
Fügen Sie dies bitte zu Ihrer Antwort hinzu: Vor dem letzten EOT;sollten keine Leerzeichen oder Tabulatoren vorhanden sein. Andernfalls wird eine Fehlermeldung angezeigt.
Shnd
44

Ich benutze ein ähnliches System wie pix0r und ich denke, das macht den Code gut lesbar. Manchmal ging ich sogar so weit, die Zeilenumbrüche in doppelte Anführungszeichen zu setzen und für den Rest der Zeichenfolge einfache Anführungszeichen zu verwenden. Auf diese Weise heben sie sich vom Rest des Textes ab, und Variablen heben sich auch besser hervor, wenn Sie die Verkettung verwenden, anstatt sie in eine doppelte Anführungszeichenfolge einzufügen. Also könnte ich mit Ihrem ursprünglichen Beispiel so etwas machen:

$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;

In Bezug auf die Zeilenumbrüche sollten Sie bei E-Mails immer \ r \ n verwenden. PHP_EOL ist für Dateien gedacht, die unter demselben Betriebssystem verwendet werden sollen, auf dem PHP ausgeführt wird.

Cvuorinen
quelle
Haben Sie diesen Einzug in Ihrer IDE festgelegt (um eine mehrzeilige Zeichenfolge festzulegen, die an jedem Teil ausgerichtet ist)?
Krzysztof Trzos
25

Ich benutze Vorlagen für Langtext:

email-template.txt enthält

hello {name}!
how are you? 

In PHP mache ich das:

$email = file_get_contents('email-template.txt');
$email = str_replace('{name},', 'Simon', $email);
powtac
quelle
interessant ... wo speichern Sie Ihre Vorlagen in der Verzeichnisstruktur einer Webanwendung?
Andrew
Mein Code ist nur eine Demo. Für eine große Web-App können Sie eine Struktur wie / templates / email /, / templates / userfeedback / verwenden. Aber wenn Sie mehr Zeug haben, würde ich ein vollständiges Vorlagensystem wie SMARTY empfehlen.
Powtac
Dwoo dwoo.org ist ein anständiges SMARTY-kompatibles PHP-Template-System, das einige als guten Nachfolger betrachten (gestartet auf PHP5, also kein PHP4-Gepäck).
Micahwittman
19

Das Hinzufügen \nund / oder \rin der Mitte der Zeichenfolge und eine sehr lange Codezeile, wie im zweiten Beispiel, fühlen sich nicht richtig an: Wenn Sie den Code lesen, sehen Sie das Ergebnis nicht und müssen scrollen .

In solchen Situationen verwende ich immer Heredoc (oder Nowdoc, wenn PHP> = 5.3 verwendet wird) : einfach zu schreiben, leicht zu lesen, keine superlangen Zeilen erforderlich, ...

Zum Beispiel :

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

Nur eins: Der Endmarker (und das ' ;' danach) muss das einzige in seiner Zeile sein: kein Leerzeichen / Tabulator davor oder danach!

Pascal MARTIN
quelle
12

Sicher, Sie könnten HEREDOC verwenden, aber was die Lesbarkeit des Codes betrifft, ist es nicht wirklich besser als im ersten Beispiel, den String über mehrere Zeilen zu wickeln.

Wenn Sie wirklich möchten, dass Ihre mehrzeilige Zeichenfolge gut aussieht und gut zu Ihrem Code passt, würde ich empfehlen, Zeichenfolgen als solche zu verketten:

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

Dies ist möglicherweise etwas langsamer als HEREDOC oder eine mehrzeilige Zeichenfolge, passt jedoch gut zum Einzug Ihres Codes und erleichtert das Lesen.

pix0r
quelle
9

Ich mag diese Methode etwas mehr für Javascript, aber es scheint sich zu lohnen, sie hier aufzunehmen, da sie noch nicht erwähnt wurde.

$var = "pizza";

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

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

Bei kleineren Dingen finde ich es oft einfacher, mit Array-Strukturen zu arbeiten als mit verketteten Strings.

Verwandte: implodieren vs concat Leistung

Johnny
quelle
1

Derjenige, der das glaubt

"abc\n" . "def\n"

ist mehrzeilige Zeichenfolge ist falsch. Das sind zwei Zeichenfolgen mit Verkettungsoperator, keine mehrzeilige Zeichenfolge. Solche verketteten Zeichenfolgen können beispielsweise nicht als Schlüssel für vordefinierte Arrays verwendet werden. Leider bietet PHP keine echten mehrzeiligen Strings in Form von

"abc\n"
"def\n"

Nur HEREDOCund NOWDOCSyntax, die besser für Vorlagen geeignet ist, da verschachtelter Codeeinzug durch eine solche Syntax unterbrochen wird.

Dmitriy Sintsov
quelle
1

Sie können auch verwenden:

<?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();
Alon Gouldman
quelle
0

In Bezug auf Ihre Frage zu Zeilenumbrüchen und Wagenrückläufen:

Ich würde empfehlen, die vordefinierte globale Konstante PHP_EOL zu verwenden, da sie alle plattformübergreifenden Kompatibilitätsprobleme löst.

Diese Frage wurde bereits zuvor auf SO gestellt. Weitere Informationen finden Sie unter " Wann verwende ich die PHP-Konstante PHP_EOL ".

Corey Ballou
quelle
1
Der Kommentar zu dieser Antwort schlägt vor, dass ich \ r \ n für neue Zeilen in E-Mails verwenden sollte: stackoverflow.com/questions/128560/…
Andrew
0

Aber wie sieht es mit neuen Linien und Wagenrückläufen aus? Was ist der Unterschied? Ist \ n \ n das Äquivalent von \ r \ r oder \ n \ r? Was soll ich verwenden, wenn ich eine Linienlücke zwischen Linien erstelle?

Niemand hier schien diese Frage tatsächlich zu beantworten, also bin ich hier.

\r steht für "Wagenrücklauf"

\n steht für "Zeilenvorschub"

Der eigentliche Grund für sie geht auf Schreibmaschinen zurück. Während Sie tippten, rutschte der Wagen langsam Zeichen für Zeichen rechts von der Schreibmaschine. Wenn Sie am Ende der Zeile angekommen sind, geben Sie den Wagen zurück und wechseln dann zu einer neuen Zeile . Um zur neuen Zeile zu gelangen, betätigen Sie einen Hebel, der die Zeilen dem Typschreiber zuführt. Daher wurden diese Aktionen zusammen als Wagenrücklaufleitungsvorschub bezeichnet . Also ganz wörtlich:

Ein Zeilenvorschub \nbedeutet, zur nächsten Zeile zu wechseln.

Ein Wagenrücklauf \rbedeutet, den Cursor an den Zeilenanfang zu bewegen.

Letztendlich Hello\n\nWorldsollte folgende Ausgabe auf dem Bildschirm angezeigt werden:

Hello

     World

Wo wie Hello\r\rWorldsollte in der folgenden Ausgabe führen .

Nur wenn Sie die 2 Zeichen kombinieren \r\n, haben Sie das gemeinsame Verständnis der bekannten Linie. IE Hello\r\nWorldsollte führen zu:

Hello
World

Und \n\rwürde natürlich zu der gleichen visuellen Ausgabe führen wie \r\n.

Ursprünglich nahmen Computer \rund \nim wahrsten Sinne des Wortes. Heutzutage ist die Unterstützung für den Wagenrücklauf jedoch gering. Normalerweise können Sie auf jedem System davonkommen, wenn Sie es \nalleine verwenden. Es hängt nie vom Betriebssystem ab, aber es hängt davon ab, in was Sie die Ausgabe anzeigen.

Trotzdem würde ich immer raten, \r\nwo immer du kannst!

Sancarn
quelle