- ベストアンサー
phpで、可変項目のcsvデータを読み込みたい
csvでデータを読み込む方法はネットで見つけたのですが、下記の条件を加えた場合どうすればいいか分かりません。 ネットで見つけた方法は、ファイルを1行ごと読み込み、コンマごとに区切って配列にいれる方法です。 しかし、項目が可変の場合、名前を入れたいところに別のデータが入ったりします。 【条件】 csvの項目名は、 A,B,C,D,E,F とする それぞれの項目は、省略可能(どこが省略されるか分からない) そのため、 A,D,E,F など、項目名が少ないCSVファイルもある。 こんな場合は、どのように処理をすればよいでしょうか? 実際は、項目名が50個ほどあります。 今回の例のように、少なければ何とかできそうなのですが・・・ 【補足・データファイル】 "A","B","C","D","E","F",←項目名 "山田","太郎","東京","15","123-221","男",←データ "山田","次郎","東京","13","124-567","男", ・・・・・・・・・↓続く ・・・・・・・・・
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
少々アクロバチックな方法かも知れませんが、ロジックを思いついたので書いてみました。 項目名が信頼できる(郵便番号/〒/ZIP/ZIP-CODEのように、同じものを指すのにバラバラの表記ではない)なら、以下のような感じでできると思います。 バラバラの表記があり得るなら、候補のリストをどこかに用意しておいて、ループで一つ一つ調べていく方法に変更すれば何とかなりそうですね。 //タイトル名からタイトルの格納番号に変換する連想配列(初期値は0 ※1) $Titles = array("姓"=>0,"名"=>0,"郵便番号"=>0,"住所"=>0,"電話番号"=>0); //CSVからタイトル行を読み込む $CSVLine = split(",",CSVから読み込んだタイトル行); //タイトル行のデータ順序を、連想配列に格納 for($i=0;$i<count($CSVLine);$i++){ $Titles[$CSVLine[$i]] = $i+1;//+1してデータを保存する(※2) } //確認用 if ($Titles["姓"]){ echo "姓は{$Titles["姓"]}番目に格納されています。"; }else{ echo "姓は省略されています。"; } if ($Titles["名"]){ echo "名は{$Titles["名"]}番目に格納されています。"; }else{ echo "名は省略されています。"; } if ($Titles["住所"]){ echo "住所は{$Titles["住所"]}番目に格納されています。"; }else{ echo "住所は省略されています。"; } if ($Titles["電話番号"]){ echo "電話番号は{$Titles["電話番号"]}番目に格納されています。"; }else{ echo "電話番号は省略されています。"; } //CSVからデータ行を読み込む $CSVLine = split(",",CSVから読み込んだデータ行); //0番目の配列を空にしておく array_unshift($CSVLine,"Dummy");//(※3)テスト用に空文字列ではなく、文字列"Dummy"を格納 echo "氏名:".$CSVLine[$Titles["姓"]]." ".$CSVLine[$Titles["名"]]; echo "郵便番号:".$CSVLine[$Titles["郵便番号"]]; echo "住所:".$CSVLine[$Titles["住所"]]; (※1)で初期値を0にし、(※2)で格納順序を+1して、(※3)で0番目に空の要素を用意することで、その項目が省略されているか否かの判定が不要になる。
その他の回答 (3)
- tany180sx
- ベストアンサー率63% (239/379)
>項目名が少ないCSVファイルもある。 の意味が、ファイルごとに項目数が違うのか、1ファイル内で項目数が違うのか。 できないということなので私も後者として受け取ったのだけど。 前者なら1行目の項目定義を見て振り分ければよし、 後者なら基本的に無理。データが既に構造化されていないから。 省略される項目を絞ることができて、データ自体に型なり候補なりが 推測できるのであれば力技でやれるかもしれませんけど。
補足
ありがとうございます。 >前者なら1行目の項目定義を見て振り分ければよし、 ここの部分が思いつきません。 考え付くのは、力技になりそうです。 何かスマートな方法があればと思って質問しました。
- singlecat
- ベストアンサー率33% (139/418)
取り敢えず、1行目の項目名を見て、実際の項目番号を判定すれば 大丈夫なのでは?
お礼
ありがとうございます。 >1行目の項目名を見て、実際の項目番号を判定すれば大丈夫なのでは? どうすればいいのでしょうか? どうしても、力技のようなことしか思いつきません。
- himajin100000
- ベストアンサー率54% (1660/3060)
無理だと思う。 苗字 名前 都道府県 とあったときに 山田 東京 は 「山田 東京」という姓名の人なのか 山田という姓の人が東京に住んでいるのか, 山田という名の人が東京に住んでいるのか, プログラムからは区別できないから。
お礼
ありがとうございます。 一行目の項目で判断して、データを振り分けたいと考えています。 実際に、そのようなシステムがあり、どうやっているのか疑問に思ったので質問しました。
お礼
ありがとうございます。 これを参考にして、試行錯誤したいと思います。 今回の質問は、これから作ろうとしているプログラムの一部です。 これからも、もっとわからないことが出てくると思います。 そのときは、またお願いします。