在Laravel 5+中,我们可以使用\DB::getQueryLog()
来检索所有已执行的查询。由于查询日志记录是一项广泛的操作并导致性能问题,因此它在L5中默认禁用,仅建议仅用于开发环境。我们可以使用方法\DB::enableQueryLog()
启用查询日志记录,如[Laravel' s文档] [1]中所述。
DB::getQueryLog()
函数很棒但有时我们希望如果我们以平面SQL格式转储它会很棒,所以我们可以在我们最喜欢的MySQL应用程序中复制/过去它,如phpMyAdmin
或{ {1}}执行它并调试或优化它。
所以,我需要一个帮助我生成转储的辅助函数,其中包含以下附加信息:
Sqlyog
等SQL
来调试/优化查询。答案 0 :(得分:3)
复制/过去路径文件顶部的以下代码块:
phpMyAdmin
# File: app/Http/routes.php
if (\App::environment( 'local' )) {
\DB::enableQueryLog();
}
}
转储上次执行的查询,在查询执行后立即使用:
if (!function_exists( 'dump_query' )) {
function dump_query( $last_query_only=true, $remove_back_ticks=true ) {
// location and line
$caller = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 1 );
$info = count( $caller ) ? sprintf( "%s (%d)", $caller[0]['file'], $caller[0]['line'] ) : "*** Unable to parse location info. ***";
// log of executed queries
$logs = DB::getQueryLog();
if ( empty($logs) || !is_array($logs) ) {
$logs = "No SQL query found. *** Make sure you have enabled DB::enableQueryLog() ***";
} else {
$logs = $last_query_only ? array_pop($logs) : $logs;
}
// flatten bindings
if (isset( $logs['query'] ) ) {
$logs['query'] = $remove_back_ticks ? preg_replace( "/`/", "", $logs['query'] ) : $logs['query'];
// updating bindings
$bindings = $logs['bindings'];
if ( !empty($bindings) ) {
$logs['query'] = preg_replace_callback('/\?/', function ( $match ) use (&$bindings) {
return "'". array_shift($bindings) . "'";
}, $logs['query']);
}
}
else foreach($logs as &$log) {
$log['query'] = $remove_back_ticks ? preg_replace( "/`/", "", $log['query'] ) : $log['query'];
// updating bindings
$bindings = $log['bindings'];
if (!empty( $bindings )) {
$log['query'] = preg_replace_callback(
'/\?/', function ( $match ) use ( &$bindings ) {
return "'" . array_shift( $bindings ) . "'";
}, $log['query']
);
}
}
// output
$output = ["*FILE*" => $info,
'*SQL*' => $logs
];
dump( $output );
}
转储所有执行的查询使用:
dump_query();
答案 1 :(得分:2)
我不明白为什么你需要这个,因为你总是知道你在哪里调用转储功能,但不要介意你有解决方案。
back-ticks
。 您不需要删除back-ticks
,因为查询在MySQL中也可以与它们一起使用。
您可以将vsprintf
用于绑定参数:
$queries = DB::getQueryLog();
foreach ($queries as $key => $query) {
$queries[$key]['query'] = vsprintf(str_replace('?', '\'%s\'', $query['query']), $query['bindings']);
}
return $queries;
我建议你查看这个github repo squareboat/sql-doctor
答案 2 :(得分:0)
将此代码添加到路由文件的顶部。 Laravel 5.2 route.php Laravel 5.3+ web.php
<?php
// Display all SQL executed in Eloquent
Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) {
var_dump($query->sql);
var_dump($query->bindings);
var_dump($query->time);
echo "<br><br><br>";
});
答案 3 :(得分:0)
对于 Laravel 8 应用程序,将以下内容放入 AppServiceProvider.php
文件可能会很有用:
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// [...]
// Dump SQL queries on demand **ONLY IN DEV**
if (env('APP_ENV') === 'local') {
DB::enableQueryLog();
Event::listen(RequestHandled::class, function ($event) {
if ( $event->request->has('sql-debug') ) {
$queries = DB::getQueryLog();
Log::debug($queries);
dump($queries);
}
});
}
// [...]
}
然后将 &sql-debug=1
附加到 url 将转储查询。
答案 4 :(得分:0)
我一直在寻找简单的解决方案,下面的解决方案对我有用。
DB::enableQueryLog();
User::find(1); //Any Eloquent query
// and then you can get query log
dd(DB::getQueryLog());
参考链接: