• ベストアンサー

CSVに追加データを挿入したいです。

この前質問したばかりなのですが、別の質問させてください。 数日頑張ったのですがどうしても出来なくて… やりたいこと ↓のようなものが書かれてあるCSVファイルがあります。 服 トップス 服 ボトムス 服 ブランド このCSVファイルに、 服 トップス なら01&01_01 服 ボトムス なら01&01_02 服 ブランド なら01&01_03 という情報を1列目に付け足したいです。 そこで、以下の配列を作り、 $data array("01&01_01" => "トップス", "01&01_02" => "ボトムス",   "01&01_03" => "ブランド") csvファイルの、「服 トップス」をexplodeで分けました。 $log = "list.csv"; # ログ名 $lines = file("$log"); foreach ($lines as $l) {  $line = explode(",",$l);  $push = $line[0].",".$line[1].",".$line[2].",".$line[3].",\n";  $cate = explode(" ",$line[2]); # $line[2]は、上記の「服 トップス」というデータを挿入しています。  $catea = $cate[1]; # サブカテゴリ名を格納 $cate[1]=トップス  foreach($data as $key => $value){   if($value == $catea){    $LOG[$catea] .= $key.",".$push."\n"; # カテゴリ情報を追加したcsvデータを1行ずつ保存   } } foreach($LOG as $keys => $values){ $file = fopen("list2.csv", 'w'); # カテゴリ情報を追加したcsvデータを書き込み fwrite($file, $values); fclose($file); } すると、foreach($LOG as $keys => $values){ の部分でforeachエラーが出ます。 根本的に記述が間違っているのでしょうか。 お手数かけますが、ご指南よろしくお願いします<(_ _)>

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

  • ベストアンサー
  • oskosn
  • ベストアンサー率100% (3/3)
回答No.3

>実行すると、2425行から最後の2448行までがlist2.csvに正常に書き込まれます。 >その書き込まれているものは、$keyに「10&10_06」と合致したもののみです。 これは最後に出現した$cateaが10&10_06なのでそうなっていると思います。 理由は下記部分です。 foreach($LOG as $keys => $values){ # ←$LOGのキーでループ $file = fopen("list2.csv", 'w'); # ←毎回新規ファイル作成でオープン fwrite($file, $values); fclose($file); } # 出力例で、実際にはカテゴリ(?)毎に違うファイルなのかなと重い#2の回答では、そのままにしておきました。 全てのカテゴリのデータをlist2.csvに出力するのでしたら、下記コードになります。 $file = fopen("list2.csv", 'w'); foreach($LOG as $keys => $values){fwrite($file,$values);} fclose($file); 改行の処理の件ですが、 $log = "list.csv"; $lines = file("$log");  : foreach ($lines as $l) { $line = explode(",",$l); この状態ですと、$line配列の最後の値(今回だと$line[16]の紹介文かな?)に改行\nが含まれています。 #2の返事で頂いたデータでしたら、最後のデータが破棄されているので問題ありません。 # 最初の質問ではその辺りが判らなかったので… file関数よりfgetcsvの方が良いかと思ったり、色々有りますが、ソースをコンパクトにしてみました。 $push_line = $line[0].",".$line[1]."," …をarray_popとimplodeに foreach($data as $key => $value){ …をarray_serachに それぞれ変更しました。元のコードと同じ動作をします。 ---ソースココから foreach ($lines as $l) { $line = explode(",",$l); array_pop ($line); # 最後の値を取り除く $push_line = implode(",",$line)."\n"; $cate = explode(" ",$line[8]); # サブカテゴリ用 $catea = $cate[0].$cate[1]; # 例:$catea=カーテン・敷物・ファブリックカーペット・ラグ echo "$catea\n"; if($key=array_search ($catea,$data)){$LOG[$catea] .= $key.",".$push_line;} # $dataから$cateaを探し出してあればキーをくっつけて$LOGに入れる } $file = fopen("list2.csv", 'w'); foreach($LOG as $keys => $values){fwrite($file, $values);} fclose($file);

yamasan0829
質問者

お礼

できました<(_ _)> 出力方法に問題があったのですね… オプションをwにしているから毎回上書きされてしまっていたんですね。 とても勉強になりました。ソースもきれいにしていただいてとてもありがたいです。 もう質問しなくて済むように今後も勉強していきたいと思います。 質問に答えてくださった方、本当にありがとうございました。

その他の回答 (2)

  • oskosn
  • ベストアンサー率100% (3/3)
回答No.2

回答 #1の方で }は問題無しと言うことですので、 Invalid argument supplied for foreach() が発生するようでしたら、$LOGが空なのだと思いますよ。 if($value == $catea)に一致するものが無かった為、 $LOGが空になっているのではないでしょうか? 入力ファイル(list.csv)の内容が以下ですとエラーは発生しません。 ●●,▲▲,服 トップス,■■ ●●,▲▲,服 ボトムス,■■ ●●,▲▲,服 ブランド,■■ 一度入力ファイルの1行のサンプルを書かれた方がよろしいかと思います。 # ただ、改行の処理や出力が同一名ファイル(list2.csv)に対し複数回行なわれているので、望まれる出力は得られないと思います。

yamasan0829
質問者

お礼

ありがとうございます。 あれから改良した結果、なぜか作成CSVファイルに、もとのCSVファイルの最後から20行近くだけ生成されています。 以下もとのCSVファイルの形式 list.csvのサンプル(ID,タイトル,URL,0_0,2005/04/02(Sat) 08:40,パスワード,紹介文,,カーテン・敷物・ファブリック カーペット・ラグ ラグ ,,管理人,メール,,1146400480_0,画像URL,0_0_0_0,価格,紹介文) ↑この形式で2448行存在しています。今回使用するのは、9番目の列データ「例:カーテン・敷物・ファブリック カーペット・ラグ ラグ」のみ。 ↓ここからソース $log = "list.csv"; $lines = file("$log"); $data = array("01&01_01" => "ティーンズファッションコート・ジャケット", "01&01_02" => "ティーンズファッションスーツ・ワンピース", -中略- "10&10_06" => "美容・健康・サプリメント衛生用品", "10&10_07" => "美容・健康・サプリメント化粧品", "10&10_08" => "美容・健康・サプリメント健康器具"); foreach ($lines as $l) { $line = explode(",",$l); $push_line = $line[0].",".$line[1].",".$line[2].",".$line[3].",".$line[4].",".$line[5].",".$line[6].",".$line[7].",".$line[8].",".$line[9].",".$line[10].",".$line[11].",".$line[12].",".$line[13].",".$line[14].",".$line[15].",\n"; $cate = explode(" ",$line[8]); # サブカテゴリ用 $catea = $cate[0].$cate[1]; # 例:$catea=カーテン・敷物・ファブリックカーペット・ラグ foreach($data as $key => $value){ if($value == $catea){ $LOG[$catea] .= $key.",".$push_line; } } } foreach($LOG as $keys => $values){ $file = fopen("list2.csv", 'w'); fwrite($file, $values); fclose($file); } ↑ここまで 実行すると、2425行から最後の2448行までがlist2.csvに正常に書き込まれます。 その書き込まれているものは、$keyに「10&10_06」と合致したもののみです。 「01」が「01」として認識されていないのでしょうか。カタカナと「・」が問題なのでしょうか。 ># ただ、改行の処理や出力が同一名ファイル(list2.csv)に対し複数回行なわれているので・・・ それでしたらどうすればよいのでしょうか…お手数かけますがよろしくお願いします<(_ _)>

  • aqucent
  • ベストアンサー率39% (78/200)
回答No.1

foreach の括弧を閉じ忘れていますね。 インデントの付け方から推察するに、付け忘れは foreach($data as $key => $value) の方でしょうか。 あと、$data はどこから出てきたのでしょう? ソースコードの一部を省略していますか? # ここからは朧気な記憶を頼りにしているので、自信なしです。 foreachはネストを許さなかったと記憶しています。 foreach ($lines as $l) を for文, 又は while文 にすれば、案外簡単に解決するかもしれません。

yamasan0829
質問者

お礼

早速の回答ありがとうございます。 ごめんなさい、}は私の付け忘れです… $dataは、 >そこで、以下の配列を作り、 >$data array("01&01_01" => "トップス", > "01&01_02" => "ボトムス", >   "01&01_03" => "ブランド") この部分です。 ># ここからは朧気な記憶を頼りにしているので、自信なしです。 >foreachはネストを許さなかったと記憶しています。 >foreach ($lines as $l) を for文, 又は while文 にすれば、案外簡単に解決するかもしれません。 for文、while文ですね。 こういった配列操作ってforeach以外ではやったことがないんですよね。 for($i=0;$i<=count($lines);$i++){ } こんな感じなのでしょうか。。

関連するQ&A