ラボ > PHPFuelPHP:DB関連、Laravel、Lumen:DB関連

PDO 「in()」を配列で渡したい

FuelPHPだと渡せてたんだけどLaravelだとエラーになる。調べたら基本ムリっぽいらしい

作成日:2023-01-03, 更新日:2023-01-12

やりたいこと

PDOで「in ()」を配列で渡して良い感じにしたい…
→ laravelのDBファサードで使いたい(※Eloquentは学習コストが高いので出来る限り使わない方針)

結論

良い感じになってくれないので良い感じになってくれるようなメソッドを自作する

bindしたいのが「in()」しか無い or すべて「?」にするとき

bindの方法には「:xxx」と「?」のどちらかを置き換えてもらうってのがあるんだけど…「?」でやるときは下記のような感じでいけるらしい

▼多くの人がやっている方法

$ids = array(1,2,3,4);
echo 'id in (' . substr(str_repeat(',?', count($ids)), 1) . ')';
// id in (?,?,?,?)

bindを「?」にしないとき

「?」だと確認が面倒なので避けたい。「:hoge」みたいな感じにしたい…

FuelPHPだといけるヤツ

$where = 'id in :id';
$bind = array(
    'id' => array(1,2,3,4),
);

→FuelPHPでクエリを投げれば「id in (1,2,3,4)」と置き換えてくれる

自作 / laravel(DBファサード)

良い方法が思いつかなかったので書いてみる(※省略できると思うけど調べたりするのが面倒なので回りくどい感じでいく)

▼laravelでDBファサードで実行(※Eloquentは知らない)

$prefix = 'id';
$seed_many = array(1,2,3,4);
$seed_q = array();
$bind = array();
foreach ( $seed_many as $k=>$v ) {
    $tmp_key = $prefix . $k;
    $seed_q[] = ':' . $prefix . $k;
    $bind[$tmp_key] = $v;
}

$q = 'select * from xxx where id in (' . implode(',', $seed_q) . ')';
DB::select($q, $bind);

※bindが他にあっても問題無し。配列のキーが数字であろうが文字列であろうが問題無し。foreachのとこを関数にしてエラー処理を追加しておけば良いと思う

関数化

function makeWhereIn_bind($seed_WhereIn, $prefix='bind_') {
    if ( !is_array($seed_WhereIn) || count($seed_WhereIn) == 0 ) {
        return array('', array());
    }

    $seed_q = array();
    $bind = array();
    foreach ( $seed_WhereIn as $k=>$row_WhereIn ) {
        $tmp_key = $prefix . $k;
        $seed_q[] = ':' . $tmp_key;
        $bind[$tmp_key] = $row_WhereIn;
    }
    return array( implode(',', $seed_q), $bind );
}

$bind = array();

$seed_many = array(1,2,3,4);
list($in_q, $in_bind) = makeWhereIn_bind($seed_many, 'id_');
if ( $in_q != '' ) {
    $q = 'select * from xxx where id in (' . $in_q . ')';
    $bind = array_mearg($bind,$in_bind);
    DB::select($q, $bind);
}

pdo

上記のやり方だと「:xxxx」があるので普通にbindが可能

関連項目