先日
とりあえず検証。
中身が「text\r\n」だけのテキストファイルを用意し、「file.txt」「file.csv」という名前で保存します。
file_ignore_new_lines.php
ローカルのWindows用XAMPP、Apache2.2.14、PHP5.3.1
よく見てみたらアップ後のファイルサイズが、「file.txt」は5バイト、「file.csv」は6バイトになっていました。
実は前者はテキストモード、後者はバイナリモードで転送していたっていう。
Windowsの改行は\r\n、Linuxの改行は\nなので、最近のFTPソフトはこの改行を自動変換してくれる機能があります。
「file.txt」はテキストモード転送で\r\nが勝手に\nになっていたので改行が出なくなっていただけでした。
両者ともバイナリモードで転送したところ、無事に
5バイトなので最後の\nが削除され、\rが残っています。
元々FILE_IGNORE_NEW_LINESは\nだけを対象としたもので、\rは対象外なのです。
ではなんで\r\nのままのはずのローカルでは改行コードが外れてるんだという話ですが、
file_ignore_new_lines.php
Windows用PHPなので気を利かせて\r\nどちらも消してくれたのかもしれません。
まあこんなふうに挙動が違うせいでバグが発生したりするんですがね!
ところでauto_detect_line_endingsという設定項目があります。
> onにした場合、PHPは fgets() および file() により読み込まれたデータを評価し、UNIX、MS-DOS、Machintoshの行末表記を使用しているかどうかを調べます。
> これにより、PHPがMacintoshシステムと相互運用できるようになりますが、 デフォルトはOffとなっています。
つまり…これを設定すれば改行コードを気にしなくてもよくなるってことなんだよ!
XAMPP
あれえ?
$file = @file('hoge.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);ってやったのに行末の改行が消えたり消えなかったりしてあれえ?ってなりました。
とりあえず検証。
中身が「text\r\n」だけのテキストファイルを用意し、「file.txt」「file.csv」という名前で保存します。
file_ignore_new_lines.php
<?php $fileTxt = @file('file.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $fileCsv = @file('file.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); print('<pre>');var_dump($fileTxt[0],$fileCsv[0]);print('</pre><hr>');一分の隙もない完璧な検証実験だ。
ローカルのWindows用XAMPP、Apache2.2.14、PHP5.3.1
string(4) "text" string(4) "text"色々おかしな設定のRHEL、Apache2.0.63、PHP5.2.1
string(4) "text" string(5) "text "サーバ単位で動作が違うとかならまだしも拡張子で動作が違うってどういうこった?
よく見てみたらアップ後のファイルサイズが、「file.txt」は5バイト、「file.csv」は6バイトになっていました。
実は前者はテキストモード、後者はバイナリモードで転送していたっていう。
Windowsの改行は\r\n、Linuxの改行は\nなので、最近のFTPソフトはこの改行を自動変換してくれる機能があります。
「file.txt」はテキストモード転送で\r\nが勝手に\nになっていたので改行が出なくなっていただけでした。
両者ともバイナリモードで転送したところ、無事に
string(5) "text " string(5) "text "となりました。
5バイトなので最後の\nが削除され、\rが残っています。
元々FILE_IGNORE_NEW_LINESは\nだけを対象としたもので、\rは対象外なのです。
ではなんで\r\nのままのはずのローカルでは改行コードが外れてるんだという話ですが、
file_ignore_new_lines.php
<?php $fileTxt = @file('file.txt'); $fileCsv = @file('file.csv'); print('<pre>');var_dump($fileTxt[0],$fileCsv[0]);print('</pre><hr>');
string(6) "text " string(6) "text "6バイトになっており、\r\n共に消えていません。
Windows用PHPなので気を利かせて\r\nどちらも消してくれたのかもしれません。
まあこんなふうに挙動が違うせいでバグが発生したりするんですがね!
ところでauto_detect_line_endingsという設定項目があります。
> onにした場合、PHPは fgets() および file() により読み込まれたデータを評価し、UNIX、MS-DOS、Machintoshの行末表記を使用しているかどうかを調べます。
> これにより、PHPがMacintoshシステムと相互運用できるようになりますが、 デフォルトはOffとなっています。
つまり…これを設定すれば改行コードを気にしなくてもよくなるってことなんだよ!
<?php ini_set('auto_detect_line_endings',1); $fileTxt = @file('file.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $fileCsv = @file('file.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); print('<pre>');var_dump($fileTxt[0],$fileCsv[0]);print('</pre><hr>');
XAMPP
string(4) "text" string(4) "text"RHEL
string(5) "text " string(5) "text "
あれえ?
PR
トラックバック
トラックバックURL: