說明
在專案開發中,有時需要列印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']);
}