質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

2524閲覧

PHPでCSVデータを書き込む時にデータが新しい場合は上書きしたい。

Nickon

総合スコア18

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/12/28 01:28

###内容
現在、CSVファイルを書き込む際、氏名、郵便番号、電話番号をハッシュ化し、ハッシュ化された値が違う場合は新規データとして追加、同じ場合はCSVファイルに上書きされないという処理が行われています。そこでハッシュ化された値が同じだった場合は追加、上書きされないという処理ではなく、後から追加された方のデータを優先し上書きしたいと考えています。どなたかご教授ください。

実現できていること

・CSVファイルのデータの書き込み => 入力(氏名、郵便番号、電話番号が重複しているデータの場合は上書きしない)

実現したいこと

・CSVデータの出力時に氏名、郵便番号、電話番号のデータが重複していた場合、上書きしないのではなく最後に追加したデータを優先して上書きしたい。

###実際の処理内容

php

1//ダウンロードファイル名を定義。する 2 $download_file_name='オーディエンスリスト_'.date('YmdHis').'.csv'; 3 4 //ファイル名を定義(ダウンロードファイル名をハッシュ化して .csvをつける) 5 $file_name=md5($download_file_name).'.csv'; 6 7 //ファイルパスを定義 (サイトルート + /google_audience_list/ + ファイル名) 8 $file_path=$site_root.'/google_audience_list/'.$file_name; 9 10 //ファイルの準備 wは書き出しを意味する 11 $csv_file=fopen($file_path,'w'); 12 13 //タイトル行 14 $csv_title=array( 15 'Email', 16 'First Name', 17 'Last Name', 18 'Country', 19 'Zip', 20 'Phone' 21 ); 22 23     //データが入る配列を準備 24 $csv_data_before = array(); 25 26 //注文データをforeachで処理 27 // todo : 名前、住所、電話番号が被っている場合はデータを一つにまとめてください。 28 foreach($order_data['data'] as $order_val){ 29 30 //初期化 31 $csv_data=array(); 32 $csv_data_hash_before=array(); 33 34 //EmailをCSVデータに追加 35 $csv_data[]=$order_val['email']; 36 37 38 //========================================================================================================= 39 //半角スペース**ボールドテキスト**を全角に変換する 40 //========================================================================================================= 41 $order_val['name'] = preg_replace('/ /u',' ', $order_val['name']); 42 $order_val['name'] = preg_replace('/\s+/u', ' ', $order_val['name']); 43 44 //========================================================================================================= 45 //名前を分割=> preg_replaceによって全角スペースも半角スペースに変換されたのでexplodeには半角スペースのみを指定すれば良い。 46 //========================================================================================================= 47 $explode_name = explode(' ',$order_val['name']); 48 49 //区切れる場合は$explode_nameが2個あれば 50 if(count($explode_name) == 2 && !empty($explode_name[0]) && !empty($explode_name[1])){ 51 $csv_data[]=$explode_name[0]; 52 $csv_data[]=$explode_name[1]; 53 54 //区切れない場合はFirst Name,Last Nameに何も入れない 55 }else{ 56 $csv_data[]=''; 57 $csv_data[]=''; 58 } 59 60 //========================================================================================================= 61 //Country JP固定 62 //========================================================================================================= 63 $csv_data[]='JP'; 64 65 //========================================================================================================= 66 //Zip ハイフンありで統一する 67 //========================================================================================================= 68 $csv_data[]=$order_val['zip1'].'-'.$order_val['zip2']; 69 70 //========================================================================================================= 71 //Phone +81 000...の形式 todo:並び順を変更したため、処理を末尾に持ってきました。 72 //========================================================================================================= 73 $tel=ltrim($order_val['tel'],'0');//先頭の0を取り除く todo: ltrim関数について調べておく 74 $tel='+81 '.$tel;//国際番号にする 75 $csv_data[]=$tel; 76 77 //========================================================================================================================== 78 // 姓(FirstName), 名(LastName), 郵便番号(zip1-zip2結合), 電話番号(tel)のいずれかが違うとハッシュ化の値が変更されて違うデータとして認識される。 79 // ¥姓(FirstName), 名(LastName), 郵便番号(zip1-zip2結合), 電話番号(tel)の全てが同じ場合のみ同じデータとして追加されなくなる。 80 //========================================================================================================================== 81 //ハッシュ化予定の項目を追加(電話番号以外) todo 再度チェックしておく 82 $csv_data_hash_before[]=$explode_name[0]; //名前 (FirstName) 83 $csv_data_hash_before[]=$explode_name[1]; //名前 (LastName) 84 $csv_data_hash_before[]=$order_val['zip1'].'-'.$order_val['zip2']; //郵便番号(zip1, zip2) 85 $csv_data_hash_before[]=$tel;//電話番号(tel) 86 87 //文字列化(serialize) => ハッシュ化(sha1) => $csv_data_beforeの引数に指定することでfputcsvした時に同じハッシュの$csv_data_beforeは$csv_fileに追加されなくなる 88 $csv_data_hash = sha1(serialize($csv_data_hash_before)); 89 90 //1行分のデータを準備($csv_data_beforeにハッシュを指定する)。$csv_dataに$csv_data_beforeを入れる。 91 $csv_data_before[$csv_data_hash] = $csv_data; 92 } 93 94 //$csv_dataをCSVとしてフォーマットし、$csvファイルに書き込む。fputcsv($csv_file,$csv_data); 95 //$csv => 二次元配列なのでforeachデータにする。 96 foreach($csv_data_before as $csv_data){ 97 fputcsv($csv_file,$csv_data); 98 } 99コード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ハッシュを格納して、

array_reverseで配列の並びを逆転させてから、array_uniqueで重複データを削除ではだめでしょうかね。array_unique関数は後で重複したデータを削除するので、先に重複したデータを削除したい場合は順番を逆転させる、自分はよく使う手です。

array_unique

投稿2020/12/28 04:21

FKM

総合スコア3647

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nickon

2020/12/28 09:36 編集

array_reverseを使ってみたのですが、特に結果が変わりませんでした。処理記述の場所や書き方などに間違いあばご指摘いただけると嬉しいです。 //ハッシュ化予定の項目を追加(電話番号以外) todo 再度チェックしておく $csv_data_hash_before[]=$explode_name[0]; //名前 (FirstName) $csv_data_hash_before[]=$explode_name[1]; //名前 (LastName) $csv_data_hash_before[]=$order_val['zip1'].'-'.$order_val['zip2']; //郵便番号(zip1, zip2) $csv_data_hash_before[]=$tel;//電話番号(tel) //文字列化(serialize) => ハッシュ化(sha1) => $csv_data_beforeの引数に指定することでfputcsvした時に同じハッシュの$csv_data_beforeは$csv_fileに追加されなくなる $csv_data_hash = sha1(serialize($csv_data_hash_before)); //1行分のデータを準備($csv_data_beforeにハッシュを指定する)。$csv_dataに$csv_data_beforeを入れる。 $csv_data_before[$csv_data_hash] = $csv_data; }    //foreach終了 //== ここで並びを逆転=>重複データ削除 ==============// array_reverse($csv_data_before[$csv_data_hash]); //重複したデータを削除(並び順が逆転しているので先に重複したデータが削除される) array_unique($csv_data_before[$csv_data_hash]); //$csv_dataをCSVとしてフォーマットし、$csvファイルに書き込む。 //fputcsv($csv_file,$csv_data); //$csv => 二次元配列なのでforeachデータにする。 foreach($csv_data_before as $csv_data){ fputcsv($csv_file,$csv_data); }
FKM

2020/12/28 15:14

var_dumpで配列が本当に逆転しているか確認した方がいいです。連想配列の場合はインデックスを使って、連想配列に当たるキーを値にするなどの工夫が必要になりますので。 あとハッシュ化してしまった値は重複することはあるのでしょうか。元が同じでもハッシュ化した際に異なる羅列になるのなら、ハッシュ化前に重複チェックする必要があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問