###前提・実現したいこと
全体の流れ
DBからCSVファイルを出力 → ユーザがそのCSVファイルをエクセルで編集 → DBにCSVファイルを入力
の ”DBにCSVファイルを入力” 部分の質問になります。
このプログラムはartisanコマンドで呼び出され実行されます。
csvを読み込んで配列に格納し、その配列をもとにDBのデータを更新するプログラムです。
###発生している問題・エラーメッセージ
下記のエラーが出てしまいました。
SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'phone_number' at row 16876
###該当のソースコード
該当箇所をvar_dumpで見ると下記のようになっており、
php
1array(11) { 2 [0]=> 3 string(13) "001r357820094" 4 [1]=> 5 string(3) "001" 6 [2]=> 7 string(57) "あいう機構",00-1234-5678""
csvの区切り文字がうまく読まれません。本来は[3]に下記のように入るはずです。
php
1array(10) { 2 [0]=> 3 string(13) "001r357820094" 4 [1]=> 5 string(3) "001" 6 [2]=> 7 string(57) "あいう機構" 8 [3]=> 9 string(12) "00-1234-5678"
初心者ながら自力で調べたところ0x5c問題というもので、構の文字の2バイト目が¥になり,がエスケープされているということに気が付きました。
しかし読み込まれるcsvの文字コードはsjis(エクセルの保存関係で)であり、それをうまくデータベースに戻さなければならず、どう解決すればいいかわかりません。
またsjisのファイルをsjis-winとしてmb_convert_variablesをかけていいのでしょうか?そうすることでハシゴの高(髙)などの問題は解決できました。しかしそれがやっていいことなのかはわかっていません。
csvの読み込みは、下記のようにSplFileObjectを使い、それをlist関数を使い変数に詰めています。
(変数名$aなどは簡略化して書いています)
php
1public function handle() 2{ 3 // CSVファイル読み込み 4 $filePath = './aaa.csv'; 5 $file = new SplFileObject($filePath); 6 $file->setFlags(SplFileObject::READ_CSV); 7 8 // ファイル内のデータをループ 9 foreach ($file as $row) { 10 // 文字コード変換 11 mb_convert_variables('utf8', 'sjis-win', $row); 12 13 // list関数を使い変数にデータを格納 14 list( 15 $a, 16 $b, 17 $c, 18 $d, 19 $e, 20 $f, 21 $g, 22 $h, 23 $i, 24 $j, 25 $k 26 ) = $row; 27
その後、DBは下記のようにクエリービルダーを使い必要項目だけアップデートしています。
DBはutf8-unicode-ciでMySQLを使っています。
php
1// CSVから取得したデータをDBに戻す 2DB::table('test_database')->where('a', $a)->update([ 3 'b' => $b, 4 'c' => $c, 5 'updated_at' => date("Y-m-d H:i:s") 6]);
###補足情報(言語/FW/ツール等のバージョンなど)
開発環境:Vagrant + VirtualBox / Homestead
言語:php-7.1.14 (NTS)
フレームワーク:Laravel5.5 (LTS)
サーバー:nginx
DB:MySQL
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。