--> -->
#title(ExcelVBAで出力したUTF-8はBOM付きだからPHPで読む際には除去が必要); * ExcelVBAで出力したUTF-8はBOM付きだからPHPで読む際には除去が必要 [#o409f901] LaravelっちゅうかPHPですが、掲題のような事で数十分浪費したのでメモです。~ ** 概要 [#h71d9327] Excelでテストデータを作成し自動でSQL文を出力するようにしたとしましょう。~ そのSQL文をLaravelで読み込んで一行ずつ実行するという寸法です。~ ** Excel側 [#ea5c2a62] そのまま書き出すとSJISになってしまうので、UTF-8で書き出します。~ ググるとすぐ出てきますが、こんな感じです。追記型です。~ #code(php){{ With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile [ファイル名] .Position = .Size .WriteText str, 1 .Savetofile [ファイル名], 2 .Close End With }} ** Laravel側 [#ma1a7b3b] これを一行ずつ読み込んで実行します。大体こんな感じ。 #code(php){{ $filename = [ファイル名]; $sqls = file($filename); if($sqls!==false){ try{ DB::beginTransaction(); // SQL文を順に実行 foreach( $sqls as $sql ){ if( !empty($sql) ){ DB::statement($sql); } } DB::commit(); } catch(\Exception $e){ // 1つでもエラーが起きたらrollback DB::rollBack(); logger()->error(__METHOD__.':'.$e->getMessage()); } } else { // エラー: ファイルが無い } }} ~ と・こ・ろ・が、これは1行目のSQL文からエラーになります。~ >App\Http\Controllers\****Controller::setDemoData:SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'delete from company' at line 1 (SQL: delete from company) < 試しに生のSQL文をそのまま&inlinecode{DB::statement('delete from company');};のように書いて実行すると正常に完了します。~ 何が違うのかと、エラーログからコピペして比べてみると、PHPStorm上で何故か表現が違う・・・。~ ~ CENTER:#ref(e1.png);~ ~ どうやらエラーになる方はSQL文の先頭に1文字''何か''が入っているようです。~ 文字コードを確認すべくサクラエディタで開くとエンコードの欄に「UTF-8 BOM付」の文字が・・・。~ ~ CENTER:#ref(e2.png);~ ~ そう、ExcelVBAでUTF-8で書き出したファイルはBOM付きになるのです。(メモ帳とかでもなるらしいです) というわけで、BOMを除去してあげれば良いことが分かりました。 ** BOM除去 [#pd7e9bb7] 検索すると以下の方法が見つかりました。 $data = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string) しかし、これだとその他の日本語まで全て除去してしまうようでした。 最終的にはこちらを採用。 $bom = pack('H*', 'EFBBBF'); $data = preg_replace("/^$bom/", '', $string); http://blog.higty.xyz/post/php-bom/~ これで無事ExcelでUTF-8出力したSQL文をPHPで実行することができました。~ おしまい。 ---- #htmlinsert(20190217_bom.html)