• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PHP ファイル操作について)

PHPのファイル操作についてのお悩みとその原因

このQ&Aのポイント
  • 同じ環境の別ドメインでのPHPファイル操作において、改行される場合とされない場合があります。その原因はなぜでしょうか?
  • ファイルへのデータ保存時に改行の有無が異なるため、別ドメインでの挙動が異なります。
  • ドメインが異なる場合には、文末に改行コードの指定が必要となります。

質問者が選んだベストアンサー

  • ベストアンサー
noname#244856
noname#244856
回答No.2

>> 【疑問点3】で回答頂いている内容なのですが、 >> array_unshiftを使用した場合、 >> ... 【疑問点1】で書いている通り、$blankに何が代入されているかによって結果が変化します。改行コードであれば前者のようになり、空文字列・NULL・FALSEが代入されている、あるいはそもそも未定義変数の場合は後者のようになります。未定義変数の場合に関してはE_NOTICEレベルのエラーも発生します。 このファイル自体では何も代入している記述は見当たらりません。元のレンタルサーバにあるファイルは本当にこの記述と完全に等しく、且つ全く同じ実行の仕方をしていましたか?どちらかが違うとしか思えない結果になっています。

stockme
質問者

お礼

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)を別の変数名に変更する事で解決できました。 その他、初回時に教えて頂いた事など修正箇所、勉強する事はまだたくさんありますが、 今回の件について原因を知る事が出来ました。 本当に感謝しています。 ありがとうごさいました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

noname#244856
noname#244856
回答No.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);

stockme
質問者

お礼

回答を頂きましてありがとうございます。 ネットと本で色々調べたのですが、理解出来ない事が多く 困っておりました。 教えて頂いた内容も知識を遥かに超えていましたので、 時間をかけて勉強させて頂きます。 【疑問点3】で回答頂いている内容なのですが、 array_unshiftを使用した場合、 りんご<>ばなな<>ぶどう<> すもも<>あんず<>すいか<> が正しいのでしょか?もしくは りんご<>ばなな<>ぶどう<>すもも<>あんず<>すいか<> が正しいのでしょうか? ※入力内容は、「りんご」「ばなな」「ぶどう」です。(質問文が間違っていました)

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PHPによる行データのアップダウン

    PHPによる行データのアップダウン フォームからデータ行をGETした内容をアップダウンさせたいのですが、どうにも入れ替えができません。 プログラムコードのアドバイスをください。 *ログファイルの中(data.dat) ゴリラ チューリップ ばなな ストロベリー ペンギン <?php $data = "data.dat"; function row_up() { $lines = @file($data); $lines[$ont] = $lines[$_GET[row]]; //自分 $lines[$_GET[row]] = $lines[$_GET[row]-1]; //前の人 $fp = fopen($data,"w"); rewind($fp); for($i=0;$i<count($lines);$i++) { if($lines[$i] == $lines[$_GET[row]]){ fputs($fp,$lines[$_GET[row]]); } elseif($lines[$i] == $lines[$ont]){ fputs($fp,$lines[$ont]); } fputs($fp,$lines[$i]); } fclose($fp); } function row_down() { $lines = @file($data); $lines[$ont] = $lines[$_GET[row]]; //自分 $lines[$_GET[row]] = $lines[$_GET[row]+1]; //次の人 $fp = fopen($data,"w"); rewind($fp); for($i=0;$i<count($lines);$i++) { if($lines[$i] == $lines[$ont]){ fputs($fp,$lines[$ont]); } elseif($lines[$i] == $lines[$_GET[row]]){ fputs($fp,$lines[$_GET[row]]); } fputs($fp,$lines[$i]); } fclose($fp); } switch($_GET[mode]) { case up: row_up(); break; case down: row_down(); break; default: break; } ?>

    • ベストアンサー
    • PHP
  • PHPについて質問です。

    PHPについて質問です。 <?php $lines0 = file('data.txt'); $lines = array_reverse($lines0); foreach ($lines as $line_num => $line) { echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n"; } ?> でファイルの内容は表示することができるようになったのですが、 次に、$linesをテキストエリアに表示させようとすると、Arrayと表示されます。 <textarea name="textarea" cols="50" rows="5" disabled="disabled">$lines</textarea> どうすれば解決できるでしょうか?

    • ベストアンサー
    • PHP
  • CSVファイルの改行

    似たような質問はあったのですが、解決できませんでした。 複数のテーブル(mysql)から抽出したデータをCSVファイルにして ダウンロードという動きを作りましたが、Excelでは改行されているのに メモ帳だと改行されません。 配列の最後に"\r\n"を挿入してみたところ、メモ帳での改行はできたのですが、 Excelに必要ない改行が入ってしまいます。(あたりまえですよね) 改行コードの入れるタイミングと方法を教えて頂けますか。 select文 while($rows = @mysql_fetch_array($result)){ $list[$i] = array ($aaa,$bbb,$ccc); $i++; } $filename = 'ファイル名'; $fp = fopen($filename.'.csv', 'w'); foreach ($list as $line) { fputcsv( $fp , $line ); } fclose($fp); ZIP圧縮処理後ダウンロード 環境:php5,mysql5

    • 締切済み
    • PHP
  • PHPで外部ファイルを読み込むときの行の最後の改行の消し方について

    PHPについての質問です。 初歩的な質問ですがどうかお付き合いいただけたらと思います。 PHPで外部ファイルを読み込む際、csvファイルなどを1行ずつ読み込んだ場合、行の最後の改行まで代入されます。 例えば ////test.php/////////////// <?php $filename = list.csv; $fp = @fopen($filename,"r"); $data = @file($filename); @fclose($fp); ?> //////////////////////////// ////list.csv//////////////// 1,2,3,4,5 6,7,8,9,10 //////////////////////////// とする場合 $data[0]には 1,2,3,4,5 プラス改行のデータ $data[1]には 6,7,8,9,10 プラス改行のデータ が代入されます。 この改行のデータを除くためにはどのようにすればよいですか? 初歩的な質問で申し訳ないのですが、よろしくお願いします。

    • 締切済み
    • PHP
  • 任意の行を修正し、ファイルを上書きしたいのですが…

    <html> <head> <title>修正・変更</title> </head> <body> <?php  $aaa = $_POST['aaa'];  $bbb = $_POST['bbb'];  $ccc = $_POST['ccc'];  $dummy = $_POST['hidden'];  $lines = array($aaa, $bbb, $ccc,$dummy);  $lines = implode(",", $lines);  $lines = mb_convert_encoding($lines, "SHIFT-JIS" , "EUC-JP");  $file = file('sample.csv');  $file[$i] = $lines."\n";  $fp = fopen("sample.csv","w+");  for($i=0 ; $i<count($file) ; $i++) {   flock($fp, LOCK_EX);   fwrite($fp, $file[$i]);  }  fclose($fp); ?> <div align="center"> 修正・変更しました!! <br><br> <input type="button" name="button" value="戻る" onClick="location.href='aaa.php'"> </div> </body> </html> 上記の様なプログラムを「CSVファイルを書き込む方法」を基に書いて みました。 しかしながら、どうしても任意の行のデータを修正して上書きする ことができません(涙 どうやったら任意の行のデータかどうかを認識して、上書きする事が できるのでしょうか?? 皆様お忙しい中かとは思いますが、ご教授して頂けませんでしょうか。 宜しくお願い致します。

    • ベストアンサー
    • PHP
  • テキストファイルにあるシリアライズされた複数の多次元配列データを日付順にソートした後に10レコードずつ表示する方法について

    PHPプログラミング初心者のAJYAMAと申します。 表題にあるようなことが、したいのですが、以下のコードでできなくて困っています。どなたか、良きアドバイスをいただけないでしょうか? <POSTされた値のテキストファイルへの書き込み> $lines=array($recordID,$nickname,$date,$area,$num,$item,$size); //データをシリアル化 $serializedLines=serialize($lines); //テキストファイルに改行を入れ、一行にデータを収納する $serializedLines=$serializedLines."\n"; //txtファイルに書き込み $fp=fopen("report.txt","a"); flock($fp, LOCK_EX); fputs($fp,$serializedLines); fclose($fp); /* <データ(変数)の値> テキストファイルにシリアル化して格納されたデータの状態 array(0 => $recordID  例)array(1) $nickname  例)array(Ajyama) $date 例)array(2008/8/30,2008/9/3,2008/9/4) $area 例)array(東京,大阪,名古屋) $num 例)array(01,02,03) $item 例)array(りんご,バナナ,メロン) $size 例)array(大,中,小) ) */ <テキストファイルからデータを読み込み、HTMLへの展開> <?php //ファイルを開く $handle=fopen(dirname(__FILE__)."/../mod/report.txt","r"); //データを呼び出す while(($serialrow=fgets($handle,1024))!==FALSE){ //シリアライズを解除して変数に格納 $row=unserialize($serialrow); //展開したデータを配列に格納(ソートするため) $data[]=array($recordID,$nickname,$date,$area,$num,$item,$size) } fclose($handle); //変数の展開 foreach($data as $key=>$row){ //ソート array_multisort($d,SORT_DESC,SORT_NUMERIC,$num,SORT_DESC,SORT_NUMERIC,$data); //レコード数毎にページを制御 $Cid=$_GET['cid']; $Size=sizeof($data); $P=$_GET["p"]; if($P>0){ $Prev=$P-1; $PrevPage="<a href=".$_SERVER['PHP_SELF']."?p={$Prev}&&cid={$Cid}>前の10件</a>"; } if($Size/10-1>$P){ $Next=$P+1; $NextPage="<a href=".$_SERVER['PHP_SELF']."?p={$Next}&&cid={$Cid}>次の10件</a>"; } if($P==0&&$Size/10<=1){ $NextPage=""; } ?> <h2><?php echo $CatTitle?></h2><BR> 全 <?=$Size?>件 | <?=$PrevPage?> <?=$NextPage?> <?=$NumP?> //配列変数の展開 <?php for($i=$P*10;$i<$P*10+10;$i++){ for($j=0;$j<$no;$j++){ echo <<<EOF <table > <tr> <td>{$recordID[$i]}</td> <td>{$nickname[$i]}</td> <td>{$date[$i][$j]} {$area[$i][$j]} {$num[$i][$j] {$item[$i][$j]} {size[$i][$j]}</td> </tr> </table> EOF; } } ?>

    • 締切済み
    • PHP
  • PHPから書き換え

    尻取りゲーム用に書いたPHPスクリプトの一部ですが CGIに書き換える方法がよくわかりません。 教えていただけませんでしょうか。 ============================================ if(isset($_POST['shiritori'])){ $rest = mb_substr($shiritori, -1, 1, "SJIS"); $hajime = mb_substr($shiritori, 0, 1, "SJIS"); if(($name != "") && ($shiritori != "")){ if($hajime == $key){ setcookie("name", $name, $expire); $key = file($keyfile); $fp = fopen($keyfile, "w"); fputs($fp,$rest); fclose ($fp); $word = "".$shiritori."<hr>"; $lines = file($logfile); $fp = fopen($logfile, "w"); fputs($fp,$word); for($i = 0; $i < $logmax-1; $i++) fputs($fp, $lines[$i]); fclose ($fp); } } else{ print"記入漏れはありませんか<br>"; print"次は<b>" .$key. "</b>から始まる語です。<br>"; } ============================================ どうぞよろしくお願いします。

    • 締切済み
    • CGI
  • ファイルに書き込む時の負荷について

    PHPバージョン5.2.4を使っています。 次のような // ------------------------------------ $fp = fopen("data.txt", "w"); $buf = ""; for ($i = 1; $i <= 3; $i++) { $buf .= "aaa$i\n"; } fwrite($fp, $buf); fclose($fp); // ------------------------------------ という変数にいったん保存してから書き込む場合と // ------------------------------------ $fp = fopen("data.txt", "w"); for ($i = 1; $i <= 3; $i++) { $buf = "aaa$i\n"; fwrite($fp, $buf); } fclose($fp); // ------------------------------------ というその都度ファイルに書き込む場合とでは どちらが良い悪いというのはあるのでしょうか? たとえばこちらのやり方は負荷がかかるなど ループが多くなっていった場合に違いがでてくるのでしょうか?

    • ベストアンサー
    • PHP
  • 多次元配列のオーソドックスなファイル書き込みについて教えてください

    PHP勉強中のAJAMAです。 下記にありますようなプログラムによって配列構造を持った変数をCSVファイルに書き込み、一行を1レコードとして管理をしたいと考えています。書き込み処理は、一意である変数の場合は、きっちりと書き込まれるのですが、配列変数の部分はarrayと書き込まれてしまいます。配列変数の中身を書き込むには、join(",",$xxxx)とすることで、すべてを同じ一行に書き込むことができました。しかしこれですと、すべてが、,区切りの二次元構造になってしまうので、これらのデータを読み込んで活用したい場合に、多次元構造を把握する処理をしなくてはいけないように見えるのですが、どうにもその仕組みを思考することができないので、模範的な手法を教えていただけないでしょうか。 serialize()も試してみましたが、知識がオブジェクト指向にまでいたっていないこともあり、うまくいきませんでした。(実行環境がPHP4だからかもしれません) 以 下、作成中のソースコードです。                     ※$numから右が配列変数部 $lines=array("$recordID",$nickname,$date,$area,$num,$item,$size); $lines=implode(",",$lines); $lines=$lines."\n"; serialize($lines); ←試行して不成功だった加筆部分。 //CSVファイルに書き込み $fp=fopen("report.csv","a"); flock($fp, LOCK_EX); fputs($fp,$lines); fclose($fp); 宜しくお願いいたします。

    • ベストアンサー
    • PHP
  • phpのユーザーエージェント取得方法

    プログラマーに作ってもらったphp(プログラマーに連絡取れず)なんですが、新しく借りたサーバーのphpのバージョンが一つだか新しいらしくユーザーエージェント取得方法が違うらしく動作しません。。。 どなたか教えてください・・・・ if (!isset($_SESSION[user])){ global $HTTP_USER_AGENT; $ua=$HTTP_USER_AGENT; $lines2=@file("./rendou/rendou.dat"); $date_file2="./rendou/rendou.dat"; $fp2=@fopen($date_file2, "w") or die("File open error."); stream_set_write_buffer($fp2, 0); flock($fp2, LOCK_EX); for($i=1; $i<=count($lines2); $i++){ list($tmp_ua[$i-1], $tmp_time[$i-1])=explode(':',$lines2[$i-1]); if($tmp_ua[$i-1]==$ua){ $_SESSION[user]=$ua; }else{ fwrite($fp2, $lines2[$i-1]); } } flock($fp2, LOCK_UN); fclose($fp2); } if(!$click_flag){ }elseif($click_flag){ if(!isset($_SESSION[user])){ 参考にしろ言われたURLです。 http://oku.edu.mie-u.ac.jp/~okumura/php/registerglobals.html

    • 締切済み
    • PHP