【问题标题】:Laravel query builder parameter bindingLaravel 查询构建器参数绑定
【发布时间】:2016-06-27 21:32:16
【问题描述】:

我正在尝试将相同的值绑定到原始查询中的某个参数 (Laravel 5.2)

//this is a non practical example ,only for clarify the question

DB::table('users as u')
->select('id')
->whereRaw('u.id > ? or u.id < ? or u.id = ?',[2,2,2])
->first();

有没有办法一次性绑定相同的参数(防止在[2,2,2]中重复值)?

【问题讨论】:

  • 您是否总是知道会有很多占位符,或者您是否想用相同的值填充查询中的所有占位符,无论有多少?
  • 在我的例子中,我知道会有多少个占位符,特别是在这个例子中所有它们也是一样的。我尝试:=someparameter:someparameter 按名称分隔占位符,但它不起作用。似乎只有? 有效!
  • 您使用whereRaw 有什么特别的原因吗?在没有whereRaw 的情况下重写它的答案是否有效?

标签: php laravel binding parameterbinding


【解决方案1】:

正如@tremby 回答的那样,您可以使用

DB::table('users as u')
  ->select('id')
  ->whereRaw('u.id > :id or u.id < :id or u.id = :id',['id'=>2])
  ->first();

使用命名绑定。

此外,您必须在config/database.php 中设置PDO::ATTR_EMULATE_PREPARES =&gt; true 才能消除Invalid parameter number 异常,例如:

config/database.php

'mysql' => [
  'driver'    => 'mysql',
  ...
  'options' => [
    PDO::ATTR_EMULATE_PREPARES => true,
  ],
],

参考:https://github.com/laravel/framework/issues/12715#issuecomment-197013236

【讨论】:

    【解决方案2】:

    使用命名参数。它们包含在 Running Raw SQL Queries section of the Database page 的文档中,位于使用命名绑定的子标题下。引用:

    您可以使用命名绑定来执行查询,而不是使用? 来表示您的参数绑定:

    $results = DB::select('select * from users where id = :id', ['id' => 1]);
    

    在你的情况下,你应该能够运行这个:

    DB::table('users as u')
        ->select('id')
        ->whereRaw('u.id > :id or u.id < :id or u.id = :id', [
            'id' => 2,
        ])
        ->first();
    

    但似乎 Laravel 抛出了 QueryException 和消息 Invalid parameter number。我已将此报告为a bug

    如果您真的想使用whereRaw,您可以改为从变量构建参数数组:

    $id = 2;
    DB::table('users as u')
        ->select('id')
        ->whereRaw('u.id > ? or u.id < ? or u.id = ?', [
            $id, $id, $id,
        ])
        ->first();
    

    或者使用array_fill为你重复值:

    $id = 2;
    DB::table('users as u')
        ->select('id')
        ->whereRaw('u.id > ? or u.id < ? or u.id = ?', array_fill(0, 3, $id))
        ->first();
    

    如果您不需要whereRaw,您可以改用查询构建器的其他功能并逐位构建查询,参数来自变量:

    $id = 2;
    DB::table('users')
        ->select('id')
        ->where('id', '>', $id)
        ->orWhere('id', '<', $id)
        ->orWhere('id', $id)
        ->first();
    

    查询构建器非常强大,要获得更复杂的逻辑,您可以嵌套闭包。有关示例,请参阅relevant section of the docs

    【讨论】:

    • 谢谢。但它不起作用。你不能在查询中使用同名参数。只需测试一下:$results = DB::select('select * from users where id = :id or id &gt; :id', ['id' =&gt; 1]); 它会抛出异常
    • 有趣。对我来说,这看起来像一个 Laravel 错误。我在跟踪器上将其报告为laravel/framework#12715。我将更新答案的前半部分以反映这一点。但是下半场呢?
    • 我以为 laravel 命名参数绑定就像 PHP 的一样。似乎我错了,或者可能是你所说的错误。你的答案后半部分是我正在使用的,没关系!等待错误报告回复...
    • 不能多次使用同一个参数。另外,请确保顺序相同:例如 DB::select('select * from users where id = :id2 or id &gt; :id1', ['id1' =&gt; 1, 'id2' =&gt; 2]) 将绑定 id2=1id2=1
    • @ursuleacv,您是否阅读了完整的答案?另外,我认为您的代码 sn-p 中有错字。假设您要输入“id2=1id1=2”,这听起来像是另一个错误——这是 Laravel 中的错误还是在哪里?
    猜你喜欢
    • 2015-06-05
    • 2017-06-14
    • 2021-09-25
    • 2014-09-08
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多