WindowsでCSVファイルを作成した場合と、MacでCSVを作成した場合では、どうやら改行コードの違いがあるせいで、同じようにfgetcsvで内容を取得しようと思っても、上手くいかない場合がある。これにはアキト兄さまもお手上げ侍。
これに関しては公式のリファレンス(公式だっけ?)にも書いてある。マッキントッシュで作成されたファイルを読み込む場合は、行末を認識できないという問題が発生する場合があるって。
この行末の認識ってのができないと、全部の内容を一行で取得しちゃうんですね。だから1000行くらいのCSVファイルを作成しても、1000行分の内容が一行として取得されてしまう。自分が住んでいる寮にいるヒロインを一人ずつ攻略していこうと思いつつも気がついたら全員一気に攻略しようとしていた、みたいな感じ。もうどうにもならない。
CSVファイルを作成してアップロードするのが自分くらいしかいなければどうにでもなるけど、不特定多数の、誰が何の端末からアップロードしてくるか分からないような場合は、この懸念事項も何とかつぶしておきたい。
さて、じゃあどうやって攻略しよう。誰を攻略しよう。
これは何か、んー……よく分からないけど、有効にするとfgetcsvなんかの際、行末の表記がマックで作成されたものかなどを調べることができるみたいです。
通常、デフォルトの設定は無効になっている。phpinfo()で見れば分かる。
php.iniに直接書いても良いんだけど、これはPHP_INI_ALLなので、phpのコード内でini_set()を書くのでもいける。
ちなみに僕はこれ使ってないので、実際の動作は検証してないです。
ただ、リファレンスの方に「最初の行の行末表記を検出する際にごく僅かな性能劣化がある」って書いてあるのが、ちょっと気になる……上手く検出できない場合もあるってことかしら?
これはこちらのblog.plastik.jpさんといそぱんさんいうサイトを参考にさせていただきました。まあ今さら言うまでもなく例によっていつもの通り丸パクリなんですが。
tmpfile()ってのは、テンポラリファイル……って言うんだっけ? 一時ファイルを作成する関数です。
もちろん、自分で任意に名前をつけてどっかのディレクトリにいったん保存して、それを再度読み込み直しても良いんだけど、特にそのファイルを保管しとく必要とかなければ、こんな感じで一時ファイルを作って読み込み、処理が終わったらさようならって感じで良いと思います。
こんな感じですねぇ。
WindowsとMacって、微妙なところがいろいろと違いますよね。以前も波ダッシュと全角チルダについてちょこっと語ったことがありますが、ああいうの、気づかないときは本当に気づかないからね。
まあそんなこと言い出したら、ブラウザだって各々微妙なところもそうじゃないところも差異がたくさんあるんですけどね。
こういうのに悩まされんのは、肩こりと同じでWeb屋にとっての職業病なのかもしれん。
これに関しては公式のリファレンス(公式だっけ?)にも書いてある。マッキントッシュで作成されたファイルを読み込む場合は、行末を認識できないという問題が発生する場合があるって。
この行末の認識ってのができないと、全部の内容を一行で取得しちゃうんですね。だから1000行くらいのCSVファイルを作成しても、1000行分の内容が一行として取得されてしまう。自分が住んでいる寮にいるヒロインを一人ずつ攻略していこうと思いつつも気がついたら全員一気に攻略しようとしていた、みたいな感じ。もうどうにもならない。
CSVファイルを作成してアップロードするのが自分くらいしかいなければどうにでもなるけど、不特定多数の、誰が何の端末からアップロードしてくるか分からないような場合は、この懸念事項も何とかつぶしておきたい。
さて、じゃあどうやって攻略しよう。誰を攻略しよう。
php.iniたんを攻める
これもリファレンスのページに書いてあるんですけど、auto_detect_line_endingsってやつを有効にするという手が一つある。これは何か、んー……よく分からないけど、有効にするとfgetcsvなんかの際、行末の表記がマックで作成されたものかなどを調べることができるみたいです。
通常、デフォルトの設定は無効になっている。phpinfo()で見れば分かる。
php.iniに直接書いても良いんだけど、これはPHP_INI_ALLなので、phpのコード内でini_set()を書くのでもいける。
//php.ini
auto_detect_line_endings=On
//*.php
ini_set('auto_detect_line_endings', true);
ちなみに僕はこれ使ってないので、実際の動作は検証してないです。
ただ、リファレンスの方に「最初の行の行末表記を検出する際にごく僅かな性能劣化がある」って書いてあるのが、ちょっと気になる……上手く検出できない場合もあるってことかしら?
file_get_contentsたんを攻める
通常だと、まずはfopenでファイルを開いて、それからfgetcsvを使うと思うんですけど、そうせずに、まずは一度file_get_contentsでファイルを読み込んで、改行コードを痴漢……いや置換して、読み込み直すというやり方。//fopenで読み込む場合
$fp = fopen($file, 'r');
$line = fgetcsv($fp);
//file_get_contentsたんを痴漢……いや置換
$buf = file_get_contents($file);
$buf = ereg_replace("\r\n|\r|\n","\n",$buf);
$fp = tmpfile();
fwrite($fp, $buf);
rewind($fp);
$line = fgetcsv($fp);
これはこちらのblog.plastik.jpさんといそぱんさんいうサイトを参考にさせていただきました。まあ今さら言うまでもなく例によっていつもの通り丸パクリなんですが。
tmpfile()ってのは、テンポラリファイル……って言うんだっけ? 一時ファイルを作成する関数です。
もちろん、自分で任意に名前をつけてどっかのディレクトリにいったん保存して、それを再度読み込み直しても良いんだけど、特にそのファイルを保管しとく必要とかなければ、こんな感じで一時ファイルを作って読み込み、処理が終わったらさようならって感じで良いと思います。
こんな感じですねぇ。
WindowsとMacって、微妙なところがいろいろと違いますよね。以前も波ダッシュと全角チルダについてちょこっと語ったことがありますが、ああいうの、気づかないときは本当に気づかないからね。
まあそんなこと言い出したら、ブラウザだって各々微妙なところもそうじゃないところも差異がたくさんあるんですけどね。
こういうのに悩まされんのは、肩こりと同じでWeb屋にとっての職業病なのかもしれん。