给定以下代码:

DB::table('users')->get();

我想得到上面的数据库查询生成器将生成的原始SQL查询字符串。在本例中,它将是SELECT*FROM用户。

我该怎么做?


当前回答

DB::QueryLog()仅在使用$builder->get()执行查询后才起作用。

如果要在执行查询之前或不执行查询时获取原始查询,可以使用$builder->toSql()方法。

获取原始SQL并替换“?”的示例具有实际绑定值:

$query = str_replace(array('?'), array('\'%s\''), $builder->toSql());
$query = vsprintf($query, $builder->getBindings());
dump($query);

$result = $builder->get();

或者,您可以故意触发错误,例如,使用不存在的表或列。然后,您可以在异常消息中看到生成的查询。

其他回答

在我看来,这将是初学者的最佳方法:

echo "<pre>";
print_r($query->toSql());
print_r($query->getBindings());

这里也描述了这一点。https://stackoverflow.com/a/59207557/9573341

如果您试图使用Illuminate而不使用Laravel获取日志,请使用:

\Illuminate\Database\Capsule\Manager::getQueryLog();

你也可以像这样设置一个快速功能:

function logger()
{
    $queries = \Illuminate\Database\Capsule\Manager::getQueryLog();
    $formattedQueries = [];
    foreach ($queries as $query) :
        $prep = $query['query'];

        foreach ($query['bindings'] as $binding) :

            if (is_bool($binding)) {
                $val = $binding === true ? 'TRUE' : 'FALSE';
            } else if (is_numeric($binding)) {
                $val = $binding;
            } else {
                $val = "'$binding'";
            }

            $prep = preg_replace("#\?#", $val, $prep, 1);
        endforeach;
        $formattedQueries[] = $prep;
    endforeach;
    return $formattedQueries;
}

EDIT

更新的版本似乎在默认情况下禁用了查询日志记录(上面返回了一个空数组)。要重新启用,在初始化Capsule Manager时,获取连接的实例并调用enableQueryLog方法

$capsule::connection()->enableQueryLog();

再次编辑

考虑到实际问题,您实际上可以执行以下操作来转换当前的单个查询,而不是之前的所有查询:

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

有很多信息已经得到了回答,我将发布我自己的发现,每当我需要在执行sql查询之前输出它时,我都会使用这些发现。

考虑以下示例:

$user = DB::table('user')->where('id',1);
echo $user->toSql();

echo$user->toSql()=这将只输出原始查询,但不会显示传递的参数。

要输出带有传递参数的查询,我们可以使用laravel getBindings()和helper str_replace_array,如下所示:

$queryWithParam = str_replace_array('?',$user->getBindings(),$user->toSql());
echo $queryWithParam;

希望这也有帮助。

要将上次运行的查询输出到屏幕,可以使用以下命令:

\DB::enableQueryLog(); // Enable query log

// Your Eloquent query executed by using get()

dd(\DB::getQueryLog()); // Show results of log

我相信最近的查询将位于阵列的底部。

你会得到这样的东西:

array(1) {
  [0]=>
  array(3) {
    ["query"]=>
    string(21) "select * from "users""
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    string(4) "0.92"
  }
}

(感谢约书亚在下面的评论。)

用于获取带有绑定的SQL查询的“可宏”替换。

在AppServiceProvider boot()方法中添加以下宏函数。\Illuminate\Database\Query\Builder::宏('toRawSql',function(){return array_reduce($this->getBindings(),函数($sql,$binding){return preg_replace('/\?/',is_numeric($binding)$绑定:“”$结合“'”,$sql,1);},$this->to SQL());});为Elquent Builder添加别名。(Laravel 5.4+)\Illuminate\Database\Elquent\Builder::宏('toRawSql',函数(){return($this->getQuery()->toRawSql());});然后照常调试。(Laravel 5.4+)例如,查询生成器\日志::debug(\DB::table('users')->limit(1)->toRawSql())例如,Elquent Builder\日志::debug(\App\User::limit(1)->toRawSql());

注意:从Laravel 5.1到5.3,由于Elquent Builder不使用Macroable特性,因此不能在RawSql中添加Elquent生成器的别名。遵循以下示例以实现相同的效果。

例如,Elquent Builder(Laravel 5.1-5.3)

\Log::debug(\App\User::limit(1)->getQuery()->toRawSql());