ベストプラクティス: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?行間に行間を作成する場合、どちらを使用すればよいですか?

次に、出力バッファリングとヒアドキュメント構文のオプションがあります。

オブジェクトで複数行の長い文字列を使用するにはどうすればよいですか?


3
\ nはUnixでは改行であると常に思っていました\ rはOS / Xより前のMacOSでは改行であり、\ r \ nはWindowsでは改行です。また、これが電子メールメッセージに表示される文字列になることを考えると、ほとんどのコマンドメールクライアントで、どの方法を使用しても正しく表示されることを確認する必要があります。ヒント:場合によっては、Outlookが余分な改行文字を削除するため、常に期待どおりの結果が得られるとは限りません。
ケニードロブナック、2009

1
それがそれほど重要かどうかはわかりませんが、元々2つの「改行」文字は、2つの文字を使用する物理タイプライターがあったときに由来しました。キャリッジをページの左側に戻すための1つ(CR-0xD)、およびページを次の行に移動させた1つ(LF-0xA)。これについて詳しく知っている人がいると思いますしかしながら。
mkgrunder 2009

回答:


288

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の違いは、Heredocに埋め込まれたPHPコードが実行されるのに対し、NowdocのPHPコードはそのまま印刷されることです。

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

この場合、$ textは値を持ちますMy $var

注:閉じる前にEOT;スペースやタブがあってはなりません。そうしないと、エラーが発生します


どうして?最初のEOTと2番目のEOTの間のすべてがそのまま文字列と見なされるためです。つまり、複数行の文字列全体にバックスラッシュnを付ける必要はありません。@Fabian:HEREDOCとNOWDOCの違いは何ですか、それとも同じですか?
ケニードロブナック、2009

4
@powtac:いいえ、ヒアドキュメントを終了するには改行する必要があるため。具体的には、そのEOT;前にスペースを入れないでください。
パワーロード2009

Nowdocの説明を追加しました。
ハーフダン2009

6
@halfdan、何かが足りませんか?通常の文字列と同じように、単に「Enter」キーを押して複数行の文字列を引用符で囲むことができるのに、ヒアドキュメントとノウドキュメントに煩わされるのはなぜですか。
Pacerier、2015

3
これを回答に追加してください:最後の前にEOT;スペースやタブがあってはいけません。そうしないと、エラーが発生します。
Shnd

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でそのインデントを設定しましたか(複数行の文字列を各パーツに揃えて設定するため)?
Krzysztof Trzos 2016年

25

長いテキストにはテンプレートを使用します。

email-template.txtには

hello {name}!
how are you? 

PHPではこれを行います:

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

興味深い...あなたのテンプレートはどこにWebアプリケーションのディレクトリ構造を保存していますか?
Andrew

私のコードは単なるデモです。巨大なWebアプリの場合は、/ templates / emails /、/ templates / userfeedback /のような構造を使用できます。しかし、もっと多くのものがあるなら、SMARTYのような完全なテンプレートシステムをお勧めします。
powtac 2009

Dwoo dwoo.orgはまともなSMARTY互換のPHPテンプレートシステムで、後継者としては優れていると見なされています(PHP5で開始されたため、PHP4の手荷物はありません)。
micahwittman、2009

19

文字列の途中\n\r途中に追加したり、2番目の例のように非常に長いコード行を使用したりするのは適切ではありません。コードを読むと、結果が表示されず、スクロールする必要があります。 。

このような状況では、私は常にヒアドキュメント(またはPHP> = 5.3を使用している場合はNowdoc)を使用します

例えば ​​:

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

ただ1つのこと:終了マーカー(およびその後の ' ;')は、その行で唯一のものでなければなりません:前後にスペース/タブはありません!


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."

小さいものについては、連結された文字列と比較して、配列構造を扱う方が簡単であることがよくあります。

関連:内破と連結のパフォーマンス


1

それを信じる人

"abc\n" . "def\n"

複数行の文字列が間違っています。これは、連結演算子を持つ2つの文字列であり、複数行の文字列ではありません。このような連結された文字列は、たとえば、事前定義された配列のキーとして使用できません。残念ながら、phpは実際の複数行の文字列を

"abc\n"
"def\n"

のみHEREDOCNOWDOCネストされたコードのインデントは、このような構文により破壊されるので、テンプレートに適している構文、。


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知っている行を共通に理解しているのは、2つの文字を組み合わせるときだけです。IEのHello\r\nWorld結果:

Hello
World

そしてもちろん\n\r、と同じビジュアル出力になり\r\nます。

もともとコンピュータがかかった\rし、\n文字通り。ただし、最近では、キャリッジリターンのサポートはごくわずかです。通常、すべてのシステム\nで、独自に使用することで問題を回避できます。OSに依存することはありませんが、出力を表示している対象に依存します。

それでも、\r\n可能な限り使用することを常にお勧めします!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.