Laravel 5:如何转储 SQL 查询?

Muh*_*nan 5 mysql logging dump laravel

Laravel 5 的内置解决方案

在 Laravel 5+ 中,我们可以使用\DB::getQueryLog()检索所有执行的查询。由于查询日志记录是一项广泛的操作并会导致性能问题,因此默认情况下在 L5 中禁用它,仅推荐用于开发环境。我们可以使用\DB::enableQueryLog()[Laravel 的文档][1] 中提到的方法启用查询日志记录。

内置解决方案中的问题

DB::getQueryLog()功能很棒,但有时我们希望如果我们以平面 SQL 格式进行转储会很棒,因此我们可以在我们最喜欢的 MySQL 应用程序中复制/传递它,例如phpMyAdminSqlyog执行它并调试或优化它。

所以,我需要一个辅助函数来帮助我生成带有以下附加信息的转储:

  • 转储调用的文件和行号。
  • 从查询中删除反引号。
  • 扁查询,所以没有需要手动更新绑定的参数,我可以复制/粘贴SQLphpMyAdmin等调试/优化查询。

Muh*_*nan 4

定制解决方案

第 1 步:启用查询日志记录

将以下代码块复制/粘贴到路由文件顶部:

# File: app/Http/routes.php
if (\App::environment( 'local' )) { 
   \DB::enableQueryLog();
}
Run Code Online (Sandbox Code Playgroud)

第二步:添加辅助函数

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 );
}
Run Code Online (Sandbox Code Playgroud)

}

如何使用?

转储最后执行的查询,在查询执行后使用:

dump_query();
Run Code Online (Sandbox Code Playgroud)

使用转储所有执行的查询:

dump_query( false );
Run Code Online (Sandbox Code Playgroud)