Laravel如何通过绑定获取查询?

Mat*_*wak 17 laravel eloquent

我有一些查询,我需要使用查询生成器传递给另一个查询

$query = DB::table('table')->whereIn('some_field', [1,2,30])->toSql();

Model::join(DB::raw("({$query}) as table"), function($join) {
    $join->on('model.id', '=', 'table.id');
})
Run Code Online (Sandbox Code Playgroud)

哪个应该结果

Select * from model join (select * from table where some_field in (1,2,30)) as table on model.id = table.id
Run Code Online (Sandbox Code Playgroud)

但绑定没有通过,这迫使我去做

   $query = DB::table('table')->whereRaw('some_field in ('. join(',', [1,2,30]) .')')->toSql();
Run Code Online (Sandbox Code Playgroud)

什么可能不安全有时.如何通过绑定获取查询?

Dou*_*sar 27

查看课程中的getBindings()方法Builder

getBindings()

$query = DB::table('table')->whereIn('some_field', [1,2,30]);

$sql = $query->toSql();

$bindings = $query->getBindings();
Run Code Online (Sandbox Code Playgroud)

  • 使用Bindings获取SQL` $ sql_with_bindings = str_replace_array('?',$ query-> getBindings(),$ query-> toSql());` (33认同)
  • 如何收藏评论?:D (3认同)
  • 请注意,不建议使用str_replace_array()。而是使用Str实用程序类:`use Illuminate \ Support \ Str; Str :: replaceArray('?',$ query-> getBindings(),$ query-> toSql())`。 (3认同)
  • @EnnioSousa,这可能非常危险,因为“getBindings”给出的绑定是未转义的。 (2认同)
  • @EnnioSousa 请查看上面 Soulriser 关于 str_replace_array() 函数的评论 (2认同)
  • @androidu str_replace_array 我们取消了,使用 Illuminate\Support\Str; 改为 Str::replaceArray()。 (2认同)

And*_*own 18

Laravel 现在可以直接在你的 Builder 上调试!!!

https://laravel.com/docs/queries#debugging

\App\User::where('age', '18')->dump();
\App\User::where('age', '18')->dd();
Run Code Online (Sandbox Code Playgroud)

输出

"select * from `users` where `age` = ?"
[
    0 => "18"
]
Run Code Online (Sandbox Code Playgroud)


小智 8

public static function getQueries(Builder $builder)
{
    $addSlashes = str_replace('?', "'?'", $builder->toSql());
    return vsprintf(str_replace('?', '%s', $addSlashes), $builder->getBindings());
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是我要找的 (2认同)
  • 有同样的问题。你可以简单地使用 str_replace(['?', '%'], ["'?'", '%%'], $builder->toSql())` ,就可以了。 (2认同)

小智 6

您可以将以下代码块定义为辅助函数并在需要时使用。它将用引号绑定数字和字符串值。

public static function getSqlWithBindings($query)
{
    return vsprintf(str_replace('?', '%s', $query->toSql()), collect($query->getBindings())->map(function ($binding) {
        return is_numeric($binding) ? $binding : "'{$binding}'";
    })->toArray());
}
Run Code Online (Sandbox Code Playgroud)

例子:

$query = Document::where('model', 'contact')->where('model_id', '1');
dd(Document::getSqlWithBindings($query));
Run Code Online (Sandbox Code Playgroud)

输出:

"select * from `document` where `model` = 'contact' and `model_id` = 1"
Run Code Online (Sandbox Code Playgroud)


小智 6

以Douglas.Sesar的回答为基础。

我发现我还需要将绑定放在单引号中,以便能够轻松地将其粘贴到我的数据库 IDE 中。

$sql = $query->toSql();
$bindings = $query->getBindings();

$sql_with_bindings = preg_replace_callback('/\?/', function ($match) use ($sql, &$bindings) {
    return json_encode(array_shift($bindings));
}, $sql);
Run Code Online (Sandbox Code Playgroud)


yar*_*www 5

$sqlQuery = Str::replaceArray(
    '?',
    collect($query->getBindings())
        ->map(function ($i) {
            if (is_object($i)) {
                $i = (string)$i;
            }
            return (is_string($i)) ? "'$i'" : $i;
        })->all(),
    $query->toSql());
Run Code Online (Sandbox Code Playgroud)