在原始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注入。如果选择方法中有多个值,则此方法不起作用我不知道您的意思-选择方法中有多个值。请解释您的解决方案,而不是仅显示代码。如果选择方法中有多个值,则此方法不起作用