给定以下代码:

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

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

我该怎么做?


当前回答

您可以使用此包获取加载页面时正在执行的所有查询

https://github.com/barryvdh/laravel-debugbar

其他回答

如果您试图使用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();

如果您使用的不是Laravel,而是Elquent包,那么:

use \Illuminate\Database\Capsule\Manager as Capsule;
use \Illuminate\Events\Dispatcher;
use \Illuminate\Container\Container;

$capsule = new Capsule;

$capsule->addConnection([
    // connection details
]);
// Set the event dispatcher used by Eloquent models... (optional)
$capsule->setEventDispatcher(new Dispatcher(new Container));

// Make this Capsule instance available globally via static methods... (optional)
$capsule->setAsGlobal();

// Setup the Eloquent ORM...(optional unless you've used setEventDispatcher())
$capsule->bootEloquent();

// Listen for Query Events for Debug
$events = new Dispatcher;
$events->listen('illuminate.query', function($query, $bindings, $time, $name)
{
    // Format binding data for sql insertion
    foreach ($bindings as $i => $binding) {
        if ($binding instanceof \DateTime) {
            $bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
        } else if (is_string($binding)) {
            $bindings[$i] = "'$binding'";`enter code here`
        }
    }

    // Insert bindings into query
    $query = str_replace(array('%', '?'), array('%%', '%s'), $query);
    $query = vsprintf($query, $bindings);

    // Debug SQL queries
    echo 'SQL: [' . $query . ']';
});

$capsule->setEventDispatcher($events);

有很多信息已经得到了回答,我将发布我自己的发现,每当我需要在执行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;

希望这也有帮助。

我通过监听查询日志并附加到日志数组来实现:

//create query
$query=DB::table(...)...->where(...)...->orderBy(...)...
$log=[];//array of log lines
...
//invoked on query execution if query log is enabled
DB::listen(function ($query)use(&$log){
    $log[]=$query;//enqueue query data to logs
});
//enable query log
DB::enableQueryLog();
$res=$query->get();//execute

从laravel 5.2开始。您可以使用DB::listen获取执行的查询。

DB::listen(function ($query) {
    // $query->sql
    // $query->bindings
    // $query->time
});

或者,如果要调试单个Builder实例,则可以使用toSql方法。

DB::table('posts')->toSql();