在原始sql查询Laravel中插入变量

在原始sql查询Laravel中插入变量,sql,laravel,Sql,Laravel,我在控制器的一个函数中 从表格中,我得到一个变量的值,比如: $x = "whatever"; 然后我需要在WHERE语句中嵌入这个变量,它的值。如果我硬编码这个值,它会产生一个正确的结果,但是我尝试了各种方法来插入这个变量,但没有成功。好吧,假设我设法使用了那个变量,那么我将不得不研究绑定以避免sql注入,但到目前为止,我想说,看看这个变量是否可以在查询中使用 我试过,双引号,串联$vx,花括号{$x},变量与此$variable类似,但在某些情况下会出现语法错误、连接,或者如果我只是将此变

我在控制器的一个函数中

从表格中,我得到一个变量的值,比如:

$x = "whatever";
然后我需要在WHERE语句中嵌入这个变量,它的值。如果我硬编码这个值,它会产生一个正确的结果,但是我尝试了各种方法来插入这个变量,但没有成功。好吧,假设我设法使用了那个变量,那么我将不得不研究绑定以避免sql注入,但到目前为止,我想说,看看这个变量是否可以在查询中使用

我试过,双引号,串联$vx,花括号{$x},变量与此$variable类似,但在某些情况下会出现语法错误、连接,或者如果我只是将此变量嵌入author=$x,它会告诉我找不到名为$x的列

$x = "whatever";
$results = DB::select(DB::raw('SELECT 
                           t.id, t.AvgStyle, r.RateDesc
                       FROM (
                           SELECT
                               p.id, ROUND(AVG(s.Value)) AS AvgStyle
                           FROM posts p

                           INNER JOIN styles s
                               ON s.post_id = p.id
                           WHERE author = $x    
                           GROUP BY p.id
                       ) t
                       INNER JOIN rates r
                           ON r.digit = t.AvgStyle'
                           ));

这似乎是一个简单的PHP变量插值问题

DB::raw需要真正的原始SQL。因此,在您传递的SQL字符串中有几个问题需要解决

PHP变量插值只有在字符串周围使用双引号时,才会将变量注入字符串。使用单引号,它将成为字符串常量。 如果Author是char/varchar,那么SQL语法需要在原始SQL语句中的字符串周围加引号。查询构建器通常会为您处理这些问题,但您需要绕过它们。 因此,这个问题的固定版本是:

$x = "whatever";
$results = DB::select(DB::raw("SELECT 
                       t.id, t.AvgStyle, r.RateDesc
                   FROM (
                       SELECT
                           p.id, ROUND(AVG(s.Value)) AS AvgStyle
                       FROM posts p

                       INNER JOIN styles s
                           ON s.post_id = p.id
                       WHERE author = '$x'    
                       GROUP BY p.id
                   ) t
                   INNER JOIN rates r
                       ON r.digit = t.AvgStyle"
                   ));
$x = "whatever";
$results = DB::select(DB::raw("SELECT 
                       t.id, t.AvgStyle, r.RateDesc
                   FROM (
                       SELECT
                           p.id, ROUND(AVG(s.Value)) AS AvgStyle
                       FROM posts p

                       INNER JOIN styles s
                           ON s.post_id = p.id
                       WHERE author = :author
                       GROUP BY p.id
                   ) t
                   INNER JOIN rates r
                       ON r.digit = t.AvgStyle"
                   ),
                       array('author' => $x)
                   );
与所有插值一样,如果要插值的变量来自用户输入,那么这就为SQL注入打开了大门。从最初的问题来看,不清楚这是否是一个问题

DB::select有一个选项,允许您传递一组参数,这些参数本质上是不受SQL注入影响的。在这种情况下,解决方案是:

$x = "whatever";
$results = DB::select(DB::raw("SELECT 
                       t.id, t.AvgStyle, r.RateDesc
                   FROM (
                       SELECT
                           p.id, ROUND(AVG(s.Value)) AS AvgStyle
                       FROM posts p

                       INNER JOIN styles s
                           ON s.post_id = p.id
                       WHERE author = '$x'    
                       GROUP BY p.id
                   ) t
                   INNER JOIN rates r
                       ON r.digit = t.AvgStyle"
                   ));
$x = "whatever";
$results = DB::select(DB::raw("SELECT 
                       t.id, t.AvgStyle, r.RateDesc
                   FROM (
                       SELECT
                           p.id, ROUND(AVG(s.Value)) AS AvgStyle
                       FROM posts p

                       INNER JOIN styles s
                           ON s.post_id = p.id
                       WHERE author = :author
                       GROUP BY p.id
                   ) t
                   INNER JOIN rates r
                       ON r.digit = t.AvgStyle"
                   ),
                       array('author' => $x)
                   );
关于


这是一个在原始sql数据库中插入变量的示例

        $query_result = Event::select(
            DB::raw('(CASE WHEN status = "draft" THEN "draft" 
            WHEN events.end_time <= \''.$now.'\' THEN "closed"
            ELSE "available"
            END) AS status'))
            ->orderBy('status')
            ->get();

所以让我们从简单的开始:除非使用双引号,否则php不会进行变量插值。让我们从这个开始。将sql语句更改为使用SELECT。。。请报告正在发生的任何行为。我看到的第二件明显的事情是author一个char/varchar值?如果是这样,您的sql语法必须位于author='$x'的位置。RAW方法的目的是注入原始sql,因此它不会给您带来任何好处。你必须构造一个可以复制到命令行工具并运行的字符串。你解决了它!请把它作为一个答案来获得你的信用。你没有那些超过6000点的智力。好吧,不用担心,很高兴能帮助你。我更感激,但如果我们不把它作为一个答案,每个人都会来检查它,因为它仍然像未解决的。旁注:这里没有参数绑定,也没有逃避,因此,使用此代码的读者应该确保$x不是来自用户输入。@根据我的测试,该参数是安全的,因为我能够使用where name=:name with['name'=>o'brien]。如果没有避开撇号,查询将失败。@halfer:您的评论与非参数传递版本相关,我个人不主张也不会使用该版本。如果您不需要转义,那么参数化查询就是一种选择,这也使您免于SQL注入。如果选择方法中有多个值,则此方法不起作用我不知道您的意思-选择方法中有多个值。请解释您的解决方案,而不是仅显示代码。如果选择方法中有多个值,则此方法不起作用