给定以下代码:

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

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

我该怎么做?


当前回答

对于laravel 5.5.X

如果希望接收应用程序执行的每个SQL查询,可以使用listen方法。此方法对于记录查询或调试非常有用。您可以在服务提供商中注册查询侦听器:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        DB::listen(function ($query) {
            // $query->sql
            // $query->bindings
            // $query->time
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

来源

其他回答

如果你使用laravel 5.1和MySQL,你可以使用我制作的这个函数:

/*
 *  returns SQL with values in it
 */
function getSql($model)
{
    $replace = function ($sql, $bindings)
    {
        $needle = '?';
        foreach ($bindings as $replace){
            $pos = strpos($sql, $needle);
            if ($pos !== false) {
                if (gettype($replace) === "string") {
                     $replace = ' "'.addslashes($replace).'" ';
                }
                $sql = substr_replace($sql, $replace, $pos, strlen($needle));
            }
        }
        return $sql;
    };
    $sql = $replace($model->toSql(), $model->getBindings());
    
    return $sql;
}

作为输入参数,可以使用以下任一项

照明\数据库\口才\生成器照亮\数据库\口才\关系\ HasMany照明\数据库\查询\生成器

第一种方式:

只需使用toSql()方法,

$query = DB::table('users')->get();

echo $query->toSql();

如果它不起作用,你可以从laravel文档中设置它。

第二种方式:

另一种方法是

数据库::getQueryLog()

但是如果它返回一个空数组,那么默认情况下它被禁用,

只需使用DB::enableQueryLog()启用即可:)

有关更多信息,请访问Github Issue了解更多信息。

希望有帮助:)

将此代码添加到AppServiceProvider并获取日志文件

         \DB::listen(function ($query) {
             \Log::info(
                 $query->sql,
                 $query->bindings,
                 $query->time
             );
         });

有很多信息已经得到了回答,我将发布我自己的发现,每当我需要在执行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::listen(function ($sql, $bindings, $time) {
    $bound = preg_replace_callback("/\?/", function($matches) use ($bindings) {
        static $localBindings;
        if (!isset($localBindings)) {
            $localBindings = $bindings;
        }
        $val = array_shift($localBindings);

        switch (gettype($val)) {
            case "boolean":
                $val = ($val === TRUE) ? 1 : 0;  // mysql doesn't support BOOL data types, ints are widely used
                // $val = ($val === TRUE) ? "'t'" : "'f'";   // todo: use this line instead of the above for postgres and others
                break;

            case "NULL":
                $val = "NULL";
                break;

            case "string":
            case "object":
                $val = "'". addslashes($val). "'";   // correct escaping would depend on the RDBMS
                break;
        }
        return $val;
    }, $sql);
    array_map(function($x) { 
        (new \Illuminate\Support\Debug\Dumper)->dump($x); 
    }, [$sql, $bindings, $bound]);
});

请阅读代码中的注释。我知道,它并不完美,但对于我的日常调试来说,它还可以。它试图以或多或少的可靠性构建绑定查询。但是,不要完全信任它,数据库引擎以不同的方式对值进行转义,而这个短函数并没有实现这些值。所以,仔细观察结果。