Laravel 列印請求過程中的所有 SQL

iyoungm發表於2018-08-03

說明

在專案開發中,有時需要列印SQL進行除錯,下面介紹列印SQL的方式。

列印單條SQL

DB::enableQueryLog();

DB::getQueryLog();

列印請求過程中的SQL

在AppServiceProvider.php 的 boot 方法加入以下程式碼即可:

if (config('app.env') === 'local') {
    DB::connection()->enableQueryLog();

    Event::listen(RequestHandled::class, function ($event) {
        if ($event->request->input('sql_debug')) {

            $queries = DB::getQueryLog();

            if (!empty($queries)) {
                foreach ($queries as &$query) {
                    $query['full_query'] = vsprintf(str_replace('?', '%s', $query['query']), $query['bindings']);
                }
            }

            dd($queries);
        }
    });

}

使用

在請求引數中增加 sql_debug ,引數值為 true 時即可列印出請求過程中的所有 SQL 了。

原理

在 kernel.php 的 handle 方法中,處理完成請求後,會 dispatch RequestHandled 事件,所以通過監聽這個請求完成的事件就可以了。

下面是 handle 方法:

/**
 * Handle an incoming HTTP request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function handle($request)
{
    try {
        $request->enableHttpMethodParameterOverride();

        $response = $this->sendRequestThroughRouter($request);
    } catch (Exception $e) {
        $this->reportException($e);

        $response = $this->renderException($request, $e);
    } catch (Throwable $e) {
        $this->reportException($e = new FatalThrowableError($e));

        $response = $this->renderException($request, $e);
    }

    $this->app['events']->dispatch(
        new Events\RequestHandled($request, $response)
    );

    return $response;
}

那為什麼要在 AppServiceProvider 中配置呢

Application.php 建構函式如下:

/**
 * Create a new Illuminate application instance.
 *
 * @param  string|null  $basePath
 * @return void
 */
public function __construct($basePath = null)
{
    if ($basePath) {
        $this->setBasePath($basePath);
    }

    $this->registerBaseBindings();

    $this->registerBaseServiceProviders();

    $this->registerCoreContainerAliases();
}

註冊配置檔案中的 服務提供器,程式碼如下:

/**
 * Register all of the configured providers.
 *
 * @return void
 */
public function registerConfiguredProviders()
{
    (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                ->load($this->config['app.providers']);
}

相關文章