【问题标题】:Laravel Query Builder, selectRaw or select and rawLaravel 查询生成器,selectRaw 或 select and raw
【发布时间】:2019-07-10 20:24:19
【问题描述】:

两者有什么区别:

DB::table('some_table')
->selectRaw('COUNT(*) AS result')
->get();

和:

DB::select(DB::raw(" 
SELECT COUNT(*) AS result
FROM some_table"));

https://laravel.com/docs/5.6/queries 的文档中,他们宣传使用raw()due SQL Injection,但它与selectRaw 相同?

【问题讨论】:

  • 是的,这些都是一样的
  • 请注意,DB::select 已经接受原始 SQL 查询字符串,因此第二个示例中的内部 DB::raw 是不必要的,并且实际上会搞砸查询日志等内容。

标签: laravel laravel-query-builder


【解决方案1】:

两者的最终结果是相同的,即但有一些区别:

第一个:

DB::table('some_table')
    ->selectRaw('COUNT(*) AS result')
    ->get();
  • 返回 PHP 对象的集合,
  • 您可以在结果上流畅地调用集合方法
  • 它更干净。

而第二个:

DB::select(DB::raw(" 
    SELECT COUNT(*) AS result
    FROM some_table"
));
  • 返回一个 数组 的 Php 对象。

虽然它们有相似之处:原始查询字符串。

【讨论】:

  • 我选择了这个作为正确的,因为我的问题是它们之间的区别不仅仅是 SQL 注入部分。谢谢。
【解决方案2】:

这两个示例产生相同的结果,但结果数据类型不同。

如果您不对查询中使用的值(尤其是来自用户输入的值)进行转义,那么使用原始查询确实可以成为攻击向量。

但是,通过使用作为任何原始查询方法的第二个参数传递的绑定可以很容易地缓解这种情况,如 the same documentation 所示(selectRaw 接受第二个参数作为绑定数组以及其他原始方法来自查询生成器,例如 whereRaw 等)。实际上,在您引用的docs page 的开头,第二段还说明了以下内容:

Laravel 查询构建器使用 PDO 参数绑定来保护您的应用程序免受 SQL 注入攻击。无需清理作为绑定传递的字符串。

因此,只要您小心并确保任何参数都作为绑定传递,而不是作为原始查询字符串中的纯值连接,您应该是安全的。

【讨论】:

  • 只是想知道 - DB::raw 不接受第二个参数 - 你从哪里得到这些信息?我只知道selectRaw - 这个真的接受绑定并充当附加程序。
  • @jave.web 你说得对。 DB::raw 不接受第二个参数,因为它的主要目的是返回一个查询 Expression 实例,以便查询构建器可以根据它是表达式还是其他数据类型来确定何时应该对参数进行转义。这是我的错误。感谢您指出错误,我已经更新了答案。
猜你喜欢
  • 2015-11-15
  • 2013-06-28
  • 1970-01-01
  • 2014-02-14
  • 2018-11-18
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
相关资源
最近更新 更多