ラボ > PHPLaravel、Lumen:DB関連

PHP/PDO Laravelでbind(quote())

in()とかでbindがそのまま使えないときとか。

作成日:2020-02-01, 更新日:2023-01-12

基本

Laravelだと下記のような感じでbindさせることができる

$q = 'select * from hoge where foo=:foo';
$bind = array(
  'foo' => xxx,
);
$results = \DB::select($q, $bind);

配列で値を渡したいとき・・・in()などの中身

▼こんな感じのクエリを使いたい

select * from hoge where foo in ( aaa, bbb, ccc );

▼希望

$prms = array('aaa', 'bbb', 'ccc');
$q = 'select * from hoge where foo in (:foo)';
$bind = array(
  'foo' => $prms,
);
$results = \DB::select($q, $bind);

→手間をかけずに「aaa, bbb, ccc」をそのままbindさせるのは無理。

クエリチェーン

クエリチェーンが使えるなら・・・クエリチェーンで指定するのが正解だと思う。

問題

・「クエリは分かる」がそのクエリを「クエリチェーン」に変換出来ない
→joinやwhereが複雑な時、調べる・思い出すってのが面倒

・チームで作業するときは「教える・教えてもらう」ってのも時間が必要
→自分と相手の時間を使うコトになる

・それにチェーンの途中の改行やインデント(TAB or スペース)がチームですると統一されない(※統一は徹底しないとすぐ破綻)
→大手さんなら契約として、徹底できるし、徹底させることも可能

対策1:すべての値をbindさせる

▼in()の中に全部書く(※in()の中は予めfor()とかで作る感じ)

$q = 'select * from hoge where foo in ( :aaa, :bbb, :ccc )';
$bind = array(
  'aaa' => xxx,
  'bbb' => xxx,
  'ccc' => xxx,
);
$results = \DB::select($q, $bind);

対策2:先に調整して、bindさせない

▼予め手動で値を処理しておく

$val = 'xxx, xox, xoo';
$q = 'select * from hoge where foo in (' . $val . ')';
$results = \DB::select($q);

pdoのquote()

値をそれぞれ手動で「"」で囲めばいいんだけど・・・抜けがあったりするとダメ。
ということで、pdoのquote()を使う。

▼Laravelだとこんな感じ

$val = xxx;
$pdo = \DB::connection()->getPdo();
$q_val = $pdo->quote($val);

※Laravelじゃなければ「\DB::connection()->getPdo();」を環境に合わせて修正。

関連項目