- ベストアンサー
PHPのファイル操作についてのお悩みとその原因
- 同じ環境の別ドメインでのPHPファイル操作において、改行される場合とされない場合があります。その原因はなぜでしょうか?
- ファイルへのデータ保存時に改行の有無が異なるため、別ドメインでの挙動が異なります。
- ドメインが異なる場合には、文末に改行コードの指定が必要となります。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
>> 【疑問点3】で回答頂いている内容なのですが、 >> array_unshiftを使用した場合、 >> ... 【疑問点1】で書いている通り、$blankに何が代入されているかによって結果が変化します。改行コードであれば前者のようになり、空文字列・NULL・FALSEが代入されている、あるいはそもそも未定義変数の場合は後者のようになります。未定義変数の場合に関してはE_NOTICEレベルのエラーも発生します。 このファイル自体では何も代入している記述は見当たらりません。元のレンタルサーバにあるファイルは本当にこの記述と完全に等しく、且つ全く同じ実行の仕方をしていましたか?どちらかが違うとしか思えない結果になっています。
その他の回答 (1)
【疑問点1】 $blankって未定義変数じゃないんですか?変数の名前からして $blank = "\n"; と代入されているべきだと思います。この操作を行っているドメインと行っていないドメインがあるのではないでしょうか?(requireから呼び出している場合その呼び出し元でやっているかやっていないかの差がある…など) 【疑問点2】 >> if(preg_match("/^[0-9]{10}<>+/",$lines[$i])){$check = 1;}else{$check = 0;} このチェックの意味が分かりません。(修正例では無視します) 【疑問点3】 array_unshiftを使っているなら新データは先頭に追加されるはずですが、 >> ▼実行後(abc.txtの中身) >> りんご<>ばなな<>ぶどう<> >> すもも<>あんず<>すいか<> この結果と整合性がありません。入力内容は「りんご」「ばなな」「ぶどう」ですよね? 【その他】 コードからものすごく(よくない意味で)古典的Perl臭がします…改善すべき点をあげると ・セパレータを「<>」にしている。このやり方は全てをHTMLエスケープして格納することが広く行われていた時代の遺産。現在は「出力直前にのみその都度エスケープすべき」 という正しい認識が広く認知されるようになったため、新たに使われることは少ない。具体的にはCSV、JSONといったフォーマットが一般的。 ・出来るだけPerl由来の「エイリアス」は避けてPHP的に命名された関数を用いる方がいい。 chop→rtrim fputs→fwrite set_file_buffer→stream_set_write_buffer ・set_file_bufferでバッファリングをOFFにする必要はない。(ログをtailコマンドにてリアルタイムで表示したいなどの場合を除き)バッファリングを行わないことはハードディスクあるいはSSDへのダメージとなる。 ・全体的にコードが読みにくく冗長。もっと短く書こうと思えば書ける。 【修正例 (全てPHP5.4以降を想定)】 A. HTMLエスケープと改行<br>変換をやった上で<>セパレータを使う(非推奨) $cols = ['すもも', 'あんず', 'すいか']; file_put_contents( ____'abc.txt', ____nl2br(implode('<>', array_map('htmlspecialchars', $cols)), false) . "\n", ____FILE_APPEND | LOCK_EX ); B. 行単位のJSONフォーマットを用いる(推奨) $cols = ['すもも', 'あんず', 'すいか']; file_put_contents( ____'abc.txt', ____json_encode($cols) . "\n", ____FILE_APPEND | LOCK_EX ); C. CSVフォーマットを用いる (推奨) $cols = ['すもも', 'あんず', 'すいか']; $fp = fopen('abc.txt', 'a+b'); flock($fp, LOCK_EX); fputcsv($fp, $cols); flock($fp, LOCK_UN); fclose($fp); D. 全体を配列とするJSONフォーマットを用いる(データサイズが大きくなる予定ならば非推奨) $cols = ['すもも', 'あんず', 'すいか']; $fp = fopen('abc.txt', 'a+b'); flock($fp, LOCK_EX); $list = json_decode(stream_get_contents($fp)); $list[] = $cols; ftruncate($fp, 0); fwrite($fp, json_encode($list)); flock($fp, LOCK_UN); fclose($fp);
お礼
回答を頂きましてありがとうございます。 ネットと本で色々調べたのですが、理解出来ない事が多く 困っておりました。 教えて頂いた内容も知識を遥かに超えていましたので、 時間をかけて勉強させて頂きます。 【疑問点3】で回答頂いている内容なのですが、 array_unshiftを使用した場合、 りんご<>ばなな<>ぶどう<> すもも<>あんず<>すいか<> が正しいのでしょか?もしくは りんご<>ばなな<>ぶどう<>すもも<>あんず<>すいか<> が正しいのでしょうか? ※入力内容は、「りんご」「ばなな」「ぶどう」です。(質問文が間違っていました)
お礼
To_aru_User 様 ありがとうございます。 試しに、改行されるPHPファイルの$blankを削除して保存した所 改行されずに保存されました。 という事は$blank内に改行文字が入っていた様です。 全体を見直してみると、 外部のデータファイルを以下の様に取り込んでいる箇所があります。 if(file_exists($log02_file)){ $log2_lines = file($log02_file); for($i=0;$i<count($log2_lines);$i++){ list($aaa,$bbb,$text) = explode("<>",$log2_lines[$i]); list($data02_01,$data02_02,$blank) = explode("<::>",$text); $set_data02[] = $data02_01; } } このデータの$blankも同様に「空」なので、同じ変数名にしても 問題ないと思っていました。 挙動が異なったのは、 $log02_fileにデータが「ある場合」と「ない場合」で発生していました。 上記の変数名($blank)を別の変数名に変更する事で解決できました。 その他、初回時に教えて頂いた事など修正箇所、勉強する事はまだたくさんありますが、 今回の件について原因を知る事が出来ました。 本当に感謝しています。 ありがとうごさいました。