Laravel の whereRaw メソッドでは名前付きプレースホルダは使えない

Laravel のクエリビルダの whereRaw メソッドや selectRaw メソッドなど、Raw 系のメソッドでプレースホルダを使うときは、名前付きプレースホルダではなく、疑問符プレースホルダを使う必要があります。

$orders = DB::table('orders')
    ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
    ->get();

名前付きプレースホルダを使うと、以下のエラーが出ます。

Uncaught exception 'PDOException’ with message 'SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters’

これは、Laravel が内部的に疑問符プレースホルダを使って PDO のプリペアードステートメントを組み立てているためです。また、ソースコード( /Illuminate/Database/Query/Builder.php )を確認しても

    public function whereRaw($sql, $bindings = [], $boolean = 'and')
    {
        $this->wheres[] = ['type' => 'raw', 'sql' => $sql, 'boolean' => $boolean];

        $this->addBinding((array) $bindings, 'where');

        return $this;
    }

    public function addBinding($value, $type = 'where')
    {
        if (! array_key_exists($type, $this->bindings)) {
            throw new InvalidArgumentException("Invalid binding type: {$type}.");
        }

        if (is_array($value)) {
            $this->bindings[$type] = array_values(array_merge($this->bindings[$type], $value));
        } else {
            $this->bindings[$type][] = $value;
        }

        return $this;
    }

という感じで、名前付きプレースホルダを値と対応させるロジックがそもそも入っていません。

この記事を書いた人

グッドネイバー

“ Webに悩むお客さまの「よき隣人」でありたい ” をモットーに、Web システム開発(主に Laravel)、Web マーケティング支援の仕事をしています。詳しい業務内容はこちら。お仕事のご依頼・ご相談はこちらからお気軽にどうぞ。

PHPLaravel