Laravel的toSql()方法是否掩盖了ids?(列值被问号代替)

Zac*_*ith 11 laravel eloquent

我正在尝试调试我在测试套件中进行的一些SQL查询.使用以下调试代码:

\Log::debug(User::first()->jobs()->toSql());
Run Code Online (Sandbox Code Playgroud)

打印出来的SQL是:

`select * from `jobs` where `jobs`.`deleted_at` is null and `jobs`.`managed_by_id` = ? and `jobs`.`managed_by_id` is not null`
Run Code Online (Sandbox Code Playgroud)

在那里做那个问号是什么?我已经测试了查询,它按预期工作.是因为我正在选择第一个()用户发生这种情况吗?

Wad*_*der 16

Laravel使用Prepared Statements.它们是一种编写SQL语句而不直接将变量删除到SQL字符串中的方法.在?你看到的是稍后将取代和自动PDO消毒的信息占位符或绑定.有关预准备语句的更多信息,请参阅PHP文档http://php.net/manual/en/pdo.prepared-statements.php

要查看将替换为查询字符串的数据,您可以getBindings()在查询上调用该函数,如下所示.

$query = User::first()->jobs();

dd($query->toSql(), $query->getBindings());
Run Code Online (Sandbox Code Playgroud)

绑定数组的替换顺序?与SQL语句中出现的顺序相同.

  • @giovannipds目前我这样做; `vsprintf(str_replace(['?'],['\'%s \''],$ query-> toSql()),$ query-> getBindings())` (2认同)
  • @sulaiman 很多。你不应该仅仅为了调试而需要这一切,请参阅 laravel-debugbar。 (2认同)

pho*_*nix 8

只是重申@giovannipds 很好的答案...我正在这样做:

vsprintf(str_replace(['?'], ['\'%s\''], $query->toSql()), $query->getBindings())
Run Code Online (Sandbox Code Playgroud)


Ija*_*een 6

除了@wader的答案外,还有一种“宏”的方式来获取带有绑定的原始SQL查询。

  1. 在方法中添加以下宏功能。AppServiceProvider boot()

    \Illuminate\Database\Query\Builder::macro('toRawSql', function(){
        return array_reduce($this->getBindings(), function($sql, $binding){
            return preg_replace('/\?/', is_numeric($binding) ? $binding : "'".$binding."'" , $sql, 1);
        }, $this->toSql());
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将别名添加到Eloquent Builder。

    \Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
        return ($this->getQuery()->toRawSql());
    });
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后照常调试。

    \Log::debug(User::first()->jobs()->toRawSql());
    
    Run Code Online (Sandbox Code Playgroud)

注意:从Laravel 5.1到5.3,由于Eloquent Builder不使用Macroable特征,因此无法动态toRawSql地向Eloquent Builder 添加别名。请按照下面的示例来实现相同的目的。

例如Eloquent BuilderLaravel 5.1-5.3

\Log::debug(User::first()->jobs()->getQuery()->toRawSql());
Run Code Online (Sandbox Code Playgroud)