いつ PHP_EOL
を使用するのが得策ですか?
私は時々これをPHPのコードサンプルで見ます。これはDOS/Mac/Unixのエンドライン問題を扱いますか?
はい、PHP_EOL
は、クロスプラットフォーム互換の方法で改行文字を見つけるために表面上使用されているので、DOS/Unixの問題を処理します。
PHP_EOL は、現在のシステムの終了文字を表します。たとえば、UNIX系のシステムで実行した場合、Windowsのエンドラインは見つかりません。
PHPバージョン7.1.1およびバージョン5.6.30のmain/php.h
から:
#ifdef PHP_WIN32
# include "tsrm_win32.h"
# include "win95nt.h"
# ifdef PHP_EXPORTS
# define PHPAPI __declspec(dllexport)
# else
# define PHPAPI __declspec(dllimport)
# endif
# define PHP_DIR_SEPARATOR '\\'
# define PHP_EOL "\r\n"
#else
# if defined(__GNUC__) && __GNUC__ >= 4
# define PHPAPI __attribute__ ((visibility("default")))
# else
# define PHPAPI
# endif
# define THREAD_LS
# define PHP_DIR_SEPARATOR '/'
# define PHP_EOL "\n"
#endif
ご覧のとおり、PHP_EOL
は"\r\n"
(Windowsサーバーの場合)または"\n"
(その他のすべての場合)になります。 PHPバージョン5.4.0RC8より前では、PHP_EOL
に3つ目の可能な値がありました:"\r"
(MacOSXサーバー上)。それは間違っていて、2012-03-01に バグ61193 で修正されています。
他の人があなたに言ったように、あなたはあなたが望むところでどんな種類の出力でもPHP_EOL
を使うことができます(ここでanyは有効です - HTML、XML、logs ...)。統一された 改行 。価値を決定するのはサーバーであり、クライアントではありません。あなたのWindowsビジターはあなたのUnixサーバーから価値を得るでしょうが、それは彼らにとって時々不便です。
まだここには表示されていないので、PHPソースに裏打ちされたPHP_EOL
の可能な値を表示したいだけです….
改行したいとき、そしてクロスプラットフォームになりたいときにはPHP_EOL
を使います。
これは、ファイルシステムにファイルを書き込んでいるとき(ログ、エクスポート、その他)の可能性があります。
生成したHTMLを読みやすくしたい場合はこれを使用できます。それであなたは<br />
の後にあなたのPHP_EOL
をたどるかもしれません。
あなたがcronからスクリプトとしてphpを実行していて、あなたが何かを出力しそれをスクリーン用にフォーマットする必要があるならば、あなたはそれを使うでしょう。
あなたがそれを送るために電子メールを作成しているならば、あなたはそれを使うかもしれませんそれは何らかのフォーマットを必要としました。
PHP_EOL(文字列)このプラットフォーム用の正しい 'End Of Line'シンボル。 PHP 4.3.10およびPHP 5.0.2から使用可能
サーバーのファイルシステム上でテキストファイルを読み書きするときにこの定数を使用できます。
ほとんどのソフトウェアは、その起源に関係なくテキストファイルを処理することができるので、行末は問題になりません。あなたはあなたのコードと一致しているべきです。
行末が重要な場合は、定数を使用する代わりに行末を明示的に指定してください。例えば:
\r\n
で区切る必要があります\r\n
を使用する必要があります。まだカバーされておらず、使用されていると想像できるので、「いつ使用しないに使用するか」という質問に答えてください。盲目的に、そして誰かが問題があることに気付くことは、後になるまではありません。これのいくつかは既存の答えのいくつかと幾分矛盾している。
HTMLでWebページに出力する場合、特に<textarea>
、<pre>
または<code>
のテキストの場合は、おそらく\n
ではなくPHP_EOL
を使用したいと思うでしょう。
これは、Windowsホスト(Windows Azureプラットフォームなど)にデプロイした場合、コードが正常に機能する可能性がある一方で、Unixに似たプラットフォームであることが原因で、コードがうまく機能する場合があるためです。 (特にInternet Explorer - そのバージョンによっては\ nと\ rの両方が表示されます)。
これがIE6以降まだ問題になっているのかどうかわからないので、それはかなり議論の余地があるかもしれませんが、文脈について考えるように人々に促すならそれは言及する価値があるようです。プラットフォームによっては\r
が突然出力される場合がある(厳密なXHTMLのような)他のケースがあるかもしれません、そして私はそのような他のEdgeケースがあると私は確信しています。
すでに誰かが指摘したように、HTTPヘッダを返すときにそれを使用したくないでしょう - それらはどんなプラットフォームでも常にRFCに従うべきです。
(誰かが提案したように)私はCSVファイルの区切り文字のようなものにそれを使用しないでしょう。サーバーが実行されているプラットフォームは、生成されたファイルまたは消費されたファイルの行末を判断するべきではありません。
いいえ。PHP_EOLはエンドラインの問題を処理しません。その定数を使用するシステムは、出力を送信するシステムと同じではないためです。
私はPHP_EOLを使うことを全く推奨しません。 Unix/Linuxは\ nを使用しますが、MacOS/OS Xも\ rから\ nに変更され、Windowsでは多くのアプリケーション(特にブラウザ)もそれを正しく表示できます。 Windowsでは、既存のクライアント側のコードを変更して、\ nのみを使用して下位互換性を維持することも簡単です。行のトリミングの区切り文字を\ r\nから\ nに変更し、関数のようにtrim()でラップするだけです。 。
私はPHP_EOLがファイル処理に非常に有用であることを発見しました、特にあなたがファイルに複数行の内容を書いているならば。
たとえば、普通のファイルに書き込むときに複数の行に分割したい長い文字列があります。\r\nを使ってもうまくいかないかもしれないので、単にPHP_EOLをあなたのスクリプトに入れるだけで、結果は最高です。
下記のこの簡単な例をチェックしてください。
<?php
$output = 'This is line 1' . PHP_EOL .
'This is line 2' . PHP_EOL .
'This is line 3';
$file = "filename.txt";
if (is_writable($file)) {
// In our example we're opening $file in append mode.
// The file pointer is at the bottom of the file hence
// that's where $output will go when we fwrite() it.
if (!$handle = fopen($file, 'a')) {
echo "Cannot open file ($file)";
exit;
}
// Write $output to our opened file.
if (fwrite($handle, $output) === FALSE) {
echo "Cannot write to file ($file)";
exit;
}
echo "Success, content ($output) wrote to file ($file)";
fclose($handle);
} else {
echo "The file $file is not writable";
}
?>
PHP_EOLの定義は、作業中のオペレーティングシステムの改行文字を与えるということです。
実際には、これはほとんど必要ないはずです。いくつかのケースを考えます。
あなたがWebに出力しているとき、あなたが一貫しているべきであることを除いて実際にはいかなる慣習もありません。ほとんどのサーバはUnix系のものなので、とにかく "\ n"を使いたいでしょう。
ファイルに出力する場合、PHP_EOLは良い考えのように思えるかもしれません。しかし、ファイルの中に文字通りの改行を入れることで同様の効果を得ることができ、既存の改行を乱用することなく(デュアルブートシステムの人として)UnixでCRLFフォーマットのファイルを実行しようとする場合に役立ちます。 、私は後者の行動を好むと言うことができます)
PHP_EOLは非常にばかげて長いので、実際に使用する価値はありません。
DOS/Windows標準の「改行」はCRLF(=\r\n)であり、LFCR(\ n\r)ではありません。後者を置くと、予想外の(よく、実際にはある種の予想される!:Dの)動作が発生する可能性があります。
今日では、ほとんどすべての(よく書かれた)プログラムが改行コードとしてUNIX標準のLF(\ n)を受け入れています。メール送信者デーモンでさえ(RFCはCRLFを 改行 ヘッダおよびメッセージ本文用).
それが役に立つかもしれない明らかな場所が1つあります。シングルクォート文字列を主に使うコードを書くとき。かどうかについては議論の余地があります:
echo 'A $variable_literal that I have'.PHP_EOL.'looks better than'.PHP_EOL;
echo 'this other $one'."\n";
それの芸術は一貫していることです。 ''と ""の組み合わせとマッチングの問題は、長い文字列を取得するときに、どの種類の引用符を使用するのかを探す必要がないということです。
人生のすべてのものと同様に、それは状況に依存します。
私は、ログ記録スクリプトが、任意のOSを使用している可能性があるユーザーからのアクションの後にテキストファイルに新しいテキスト行を書き込むサイトを持っています。
この場合、PHP_EOLを使用するのが最適ではないようです。ユーザーがMac OS上でテキストファイルに書き込むと、\ nが書き込まれます。 Windowsコンピュータでテキストファイルを開くと、改行は表示されません。このため、代わりに "\ r\n"を使用します。これは、任意のOSでファイルを開くときに機能します。
あなたは主に一重引用符を使ったコードを書いています。
echo 'A $variable_literal that I have'.PHP_EOL.'looks better than'.PHP_EOL;
echo 'this other $one'."\n";
複数行を出力している場合は、error_log()で便利です。
開発者は文字列を分割するときにUNIXの終わりを想定しているので、私のWindowsインストールでは多くのデバッグステートメントが奇妙に見えることがわかりました。
私はWebCalendarを使用していますが、Mac iCalは生成されたicsファイルをインポートする際に、行末がxcal.phpで "\ r\n"としてハードコードされているため、barfsを使用することを禁じます。私は中に入り、すべての出現箇所をPHP_EOLに置き換えました。そして今iCalは幸せです!私はまたVistaでそれをテストし、Outlookは同様に行末文字が "\ n"であってもファイルをインポートすることができました。
Jumi(PHP用のjoomlaプラグイン)が何らかの理由でコードをコンパイルすると、コードからバックスラッシュがすべて削除されます。 $csv_output .= "\n";
のようなものが$csv_output .= "n";
になるようなもの
非常に迷惑なバグ!
あなたがした結果を得るために代わりにPHP_EOLを使用してください。
私が書かなければならなかったいくつかのコマンドラインスクリプトでPHP_EOL定数を使います。私は自分のローカルのWindowsマシン上で開発してからLinuxサーバーボックス上でテストします。定数を使用することで、異なるプラットフォームごとに正しい行末を使用することについて心配する必要がなくなりました。
システムによっては、この定数を使用すると便利な場合があります。たとえば、電子メールを送信している場合は、PHP_EOLを使用してシステム間スクリプトをより多くのシステムで実行できます。最新のphpエンジンを使った、定数未定義の、最新のホスティングでは、この問題はありませんが、良いことは、このような状況を回避するコードを書くことです:
<?php
if (!defined('PHP_EOL')) {
if (strtoupper(substr(PHP_OS,0,3) == 'WIN')) {
define('PHP_EOL',"\r\n");
} elseif (strtoupper(substr(PHP_OS,0,3) == 'MAC')) {
define('PHP_EOL',"\r");
} elseif (strtoupper(substr(PHP_OS,0,3) == 'DAR')) {
define('PHP_EOL',"\n");
} else {
define('PHP_EOL',"\n");
}
}
?>
それで、あなたは問題なくPHP_EOLを使うことができます... PHP_EOLはもっと多くのシステムで同時に働くべきスクリプトで使われるべきであることは明らかです。
注意:PHP_EOLは
1) on Unix LN == \n
2) on Mac CR == \r
3) on Windows CR+LN == \r\n
この回答がお役に立てば幸いです。