忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/07/26 15:48 |
PHP:file()のFILE_IGNORE_NEW_LINESの動作が不可解な件
先日
	$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


2011/04/07 22:52 | Comments(0) | TrackBack(0) | PHP

トラックバック

トラックバックURL:

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<今週の実績 2011/04/10 | HOME | 買ったものリスト 2011/04/03>>
忍者ブログ[PR]