PHPでLOAD DATA INFILEをした話

エンチャント逆引きを作ったときにdbを構築したのですが、頻繁にデータを追加しないといけないのが面倒でLOAD DATA INFILEを使おうと思いつきました。
しかしこのスペースを借りているusamimi.infoさんではdb接続を内部からのみ許可しているので、phpからアクセスする他なくスクリプトを書きました。
(もしphpなしでできる方法があったら教えてください)

PDOで接続

あらかじめ’name’->’filename’の形の連想配列$pathを宣言してあります。
LOAD DATA LOCAL INFILEを使うときにはPDO::MYSQL_ATTR_LOCAL_INFILE => true
を設定しておかないとLOCALが使えません。
$queryにクエリ文を配列の形で追加していき、最後にimplodeで繋げてexecしています。
最初このやり方を見たときは頭いいなあって思いました(小並感)。
csvによって区切り文字や囲み文字が違うので分岐させているのですが、統一しておけばよかったです。めちゃくちゃ面倒くさい。

「”」と「’」に気をつける

最初はmysqlで通るクエリをそのまま$queryに追加していたのですが、

FAILEDSQLSTATE[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 ‘LINES TERMINATED BY ‘ ” at line 1

のようなエラーが発生し続けていました。

エスケープのあたりで引っかかっているのはわかったのですが、ちゃんとエスケープしてるにもかかわらずなぜエラーになるのかさっぱりわかりませんでした。

実はこれまで変数への文字列代入の際にずっとシングルクォーテーションを使っていて、今回も単純にクエリ文をシングルクォーテーションで囲んでやっていました。

実はこれが罠。


エスケープシーケンスは、「’」(シングルクォーテーション)で囲まれていても展開されず、そのまま表示されてしまいますので必ず「”」(ダブルクォーテーション)で囲むようにしましょう。

PHP 改行、タブ(エスケープシーケンス)の使い方 – Web Development Blog

ええそうです。これをすっかり忘れていたアホは私です。
というわけでクエリ文をダブルクォーテーションで囲み、スクリプトは無事動くようになりましたとさ。めでたしめでたし。

追記(2019/01/29)

ローカル環境(MySQL 8.0.13)だとLOAD DATA INFILEで追加できたcsvがサーバー(MySQL 5.5.13)では500 Internal Errorで追加できないことがありました。

ファイルサイズは500kb~700kbなのでサイズ超過というわけではないのですが、BigDumpを使うことで追加することができました。

BigDump: Staggered MySQL Dump Importer

bigdump.phpを開き、

$db_server = ‘サーバーアドレス’;
$db_name = ‘データベース名’;
$db_username = ‘ユーザー名’;
$db_password = ‘パスワード’;

を入力してサーバーへアップロード。
同じディレクトリに追加したいsqlファイルをアップロードしてbigdump.phpにアクセスします。

Start ImportでDBへ追加することができます。

アウトプットの重要さ

今やっている逆引き検索の作成にあたって、いろいろなページを検索しまくっている(特にQiita)のですが、どこへ行っても「上達するならアウトプットすべき」ということが書いてあります。

確かにアウトプットは重要で、見る•聞くだけだと10回やっても覚えられないことが、人に1回教えるだけで頭に定着しているということはよくあります。友人にホラーおもちゃになんの盾を持っていくのか毎回答えているといつの間にかしっかり覚えていたりします。おそらく『自分で考えて何かをする』ことは脳みそへの経験値がすごく多いのでしょう。人のマネやコピペの経験値が1だとしたらアウトプットは10みたいな。

しかしアウトプットが重要だと頭で理解していても慣れてないとなかなか難しいものです。記事を書いている途中はどうにも頭がしっかり回っていないというか、ぼんやり書いている感じです。書き終えたあと見返すともっといい書き方があったり、本当に書きたいことじゃないことを書いてたり。

文章の書き方は良記事や本を読んで覚えていくしかなさそうです。そして一番大事であろうことは自分が何を言いたいのか、それをどう組み立てて文章にするのかということでしょう。自分のしたいことを組み立てるという点ではものを書くということとプログラミングは似ているように感じます。