4

假设我想显示 type="color" 的完整奖项列表:

Awards        Type     2013 Winner
======        ====     ===========
Blue Award    color       Tom
Red Award     color
Green Award   color       Dan  

为了达到这个结果,我可以在 Laravel 中进行如下查询:

$year = '2013';

$awards = DB::table('awards')
             ->leftJoin('winners', function($join) use ($year)
                   {
                        $join->on('awards.id','=','winners.award_id');
                        $join->on('winners.year','=',DB::raw("'".$year."'"));
                   }
             ->where('awards.type','color')
             ->get();

如果你输出 Laravel 生成的 SQL,你会看到只有WHERE 子句是参数化的,如果我从不受信任的来源获取它,ON 子句中的 $year容易受到 sql 注入的影响。此外,查询的缓存潜力也会降低,因为 $year 会经常更改。注意:如果您认为我只是将第二个左连接条件添加到查询的 WHERE 中, 则它们并不相同

关于如何将查询的 $year 部分参数化的任何想法?

4

3 回答 3

6

这是一个奇怪的解决方法(不想扩展 Builder 和 JoinClause 类):
注意:这将破坏查询链接,->因此请注意where下面是分开的。

$query = DB::table('awards')
         ->leftJoin('winners', function($join)
               {
                    $join->on('awards.id','=','winners.award_id');
                    $join->on('winners.year','=',DB::raw('?'));  
               }
         ->setBindings(array_merge($query->getBindings(),array($year)));

$query->where('awards.type','color');

$awards = $query->get();

更新泰勒补充说 joinWhereleftJoinWhere......他说“如果你有一个函数连接,只需在闭包内使用->where->orWhere。” 不过,我还没有尝试过。

于 2013-07-19T01:57:43.097 回答
1

目前您可以使用$join->where

$year = '2013';

$awards = DB::table('awards')
         ->leftJoin('winners', 
               function($join) use ($year)
               {
                    $join
                        ->on('awards.id','=','winners.award_id')
                        // "where" instead of "on":
                        ->where('winners.year', '=', $year);
               }
         ->where('awards.type','color')
         ->get();
于 2016-07-21T21:50:30.007 回答
-1

这直接来自 Laravel 文档:

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

您根本不需要对其进行消毒。应该没问题。但是,如果您对此感到担心,则可以根据需要使用Validator该类来验证它。

于 2013-07-18T21:47:21.297 回答