ハクチョウノミズウミ

雑多なごった煮。

備忘録: PDO と SQL 文

はじめに
研究で Android 端末から SQL サーバにアクセスしてデータを見るというアプリを作っています。実は今までアプリケーションを作成することがなかった(学部時代はデータ分析をしていたので元データのパース用スクリプト程度しか書いていなかった)ので、いきなり Android Java (と PHP )の勉強を強いられる事になった上、納期が3週間後(5月末)に設定されるという地獄の状況です。今現在の話です。
で、そのアプリはサーバとのデータのやり取りを PHP への POST で実現していて、端末から文字列をバイトデータとして PHP に送って、その文字列を SQL クエリの WHERE としてテーブルを抽出する、という処理を書くことになりました。そこで詰まったのでメモ。


ダメなやつ
[Android]

// 前略
URL url = new url ("http://hogehoge/.../hoge.php")
HTTPURLConnection con = (HTTPURLConnection)url.openConnection();

con.setReqestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);

// 接続
con.connect();

OutputStream out = new BufferedOutputStream (con.getOutputStream());
out.write("Hoge".getBytes("UTF-8"));
out.flush;
// 後略

[PHP]

<?php
// 前略
$data = file_get_contents ('php://input');
$stmt = $dbh -> prepare ("SELECT * FROM table_hoge WHERE hoge_id =".$data);
$stmt.execute();
// table_hoge の hoge_id は nvarchar(30)
// 後略
?>

何がまずかったか
PHP の2行目。PDO (PHP Data Objects) の prepare は引数として String を持つから、 PHP の記法上、普通はシングルクォーテーションで括るべきなのにダブルクォーテーションにしてしまっています。それから文字列と変数 $data をドットで連結しているのも問題。一応これでも動くことは動くんですが、空のデータしか返ってきません。

どうしてこうなったか

  1. いろんなインターネット上の情報を寄せ集めてパッチのごとく設計したことの弊害
  2. 実は検索対象のデータ型が int だと特に問題なかった

同様の処理を int 型の要素に対して行っていたので、それをちょこっと変えただけで適用したのがまずかったです。考えてみれば当たり前なんだけど。

修正版
[PHP]

// 前略
$data = file_get_contents ('php://input');
$stmt = $dbh -> prepare ('SELECT * FROM table_hoge WHERE hoge_id = :data');
$stmt.execute(array(':data' => $data));
// table_hoge の hoge_id は nvarchar(30)

prepare 内の文字列をシングルクォーテーションに変更。
execute() のタイミングで入力文字列を渡すように変更。

おわりに
PHP やってる人からしたら初歩の初歩なんだろうなぁ……。これで午前中潰してしまったのが悔やまれる。
他の人へ参考に、というよりは自分の戒めとして記事作成しました。