如何获得在Laravel 5中执行的查询? DB :: getQueryLog返回空数组

DB :: getQueryLog返回空数组

$user = User::find(5); print_r(DB::getQueryLog()); 

结果是空数组

 Array ( ) 

默认情况下,在Laravel 5中禁用查询日志: https : //github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448

您将需要通过调用以启用查询日志:

 DB::enableQueryLog(); 

或者注册一个事件监听器:

 DB::listen( function ($sql, $bindings, $time) { // $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1 // $bindings - [5] // $time(in milliseconds) - 0.38 } ); 

一些技巧

1.多个数据库连接

如果您有多个数据库连接,则必须指定要login的连接

要为my_connection启用查询日志:

 DB::connection('my_connection')->enableQueryLog(); 

要获取my_connection查询日志:

 print_r( DB::connection('my_connection')->getQueryLog() ); 

2.在哪里启用查询日志?

对于HTTP请求生命周期,可以在某些BeforeAnyDbQueryMiddleware 中间件的handle方法中启用查询日志,然后在同一个中间件的terminate方法中检索执行的查询。

 class BeforeAnyDbQueryMiddleware { public function handle($request, Closure $next) { DB::enableQueryLog(); return $next($request); } public function terminate($request, $response) { // Store or dump the log data... dd( DB::getQueryLog() ); } } 

中间件链不会运行artisan命令,因此对于CLI执行,您可以在artisan.start事件侦听器中启用查询日志。

例如,你可以把它放在bootstrap/app.php文件中

 $app['events']->listen('artisan.start', function(){ \DB::enableQueryLog(); }); 

3.记忆

Laravel将所有查询保留在内存中。 因此,在某些情况下(例如插入大量行时)或长时间运行大量查询时,这可能会导致应用程序使用多余的内存。

在大多数情况下,您只需要查询日志进行debugging,如果是这种情况,我会build议您只为开发启用它。

 if (App::environment('local')) { // The environment is local DB::enableQueryLog(); } 

参考

如果您真正关心的是实际查询(最后一次运行)以进行快速debugging:

 DB::enableQueryLog(); # your laravel query builder goes here $laQuery = DB::getQueryLog(); $lcWhatYouWant = $laQuery[0]['query']; # <------- # optionally disable the query log: DB::disableQueryLog(); 

$laQuery[0]上执行print_r()以获取完整查询。 (上面的$lcWhatYouWantvariables将把variablesreplace为??

显然,在Laravel 5.2中, DB::listen的闭包只接收一个参数。

所以,如果你想在Laravel 5.2中使用DB::listen ,你应该这样做:

 DB::listen( function ($sql) { // $sql is an object with the properties: // sql: The query // bindings: the sql query variables // time: The execution time for the query // connectionName: The name of the connection // To save the executed queries to file: // Process the sql and the bindings: foreach ($sql->bindings as $i => $binding) { if ($binding instanceof \DateTime) { $sql->bindings[$i] = $binding->format('\'Ymd H:i:s\''); } else { if (is_string($binding)) { $sql->bindings[$i] = "'$binding'"; } } } // Insert bindings into query $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql); $query = vsprintf($query, $sql->bindings); // Save the query to file $logFile = fopen( storage_path('logs' . DIRECTORY_SEPARATOR . date('Ym-d') . '_query.log'), 'a+' ); fwrite($logFile, date('Ymd H:i:s') . ': ' . $query . PHP_EOL); fclose($logFile); } ); 

您需要先启用查询日志logging

DB::enableQueryLog();

如果您在应用程序启动之前启用查询日志logging,那么您可以在BeforeMiddleware中执行查询日志,然后在AfterMiddleware中检索执行的查询。

把这个放在routes.php文件中:

 \Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) { echo'<pre>'; var_dump($query->sql); var_dump($query->bindings); var_dump($query->time); echo'</pre>'; }); 

由msurguy提交,源代码在这个页面 。 你会在评论中find这个laravel 5.2的修正码。

此代码适用于:

  • Laravel 5.2
  • 将这些语句logging到mysql数据库中

这里是代码,这是基于@ milz的答案:

  DB::listen(function($sql) { $LOG_TABLE_NAME = 'log'; foreach ($sql->bindings as $i => $binding) { if ($binding instanceof \DateTime) { $sql->bindings[$i] = $binding->format('\'Ymd H:i:s\''); } else { if (is_string($binding)) { $sql->bindings[$i] = "'$binding'"; } } } // Insert bindings into query $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql); $query = vsprintf($query, $sql->bindings); if(stripos($query, 'insert into `'.$LOG_TABLE_NAME.'`')===false){ $toLog = new LogModel(); $toLog->uId = 100; $toLog->sql = $query; $toLog->save(); } }); 

核心是if(stripos...行,它可以防止insert into log sql语句插入到数据库中的recursion。

你只要按照这些步骤,如果你想打印查询转到供应商\ laravel \骨架\ src \ Illuminate \数据库\连接.php

  protected $loggingQueries = false; 

通过把真正的启用它

  protected $loggingQueries = true; 

在控制器中你必须这样做

 dd(DB::getQueryLog()); 

你会得到所需的输出

在继续使用Laravel 5.2的情况下,DB :: listen中的闭包只能收到一个参数…上面的响应:您可以将这些代码放入Middleware脚本中并在路由中使用它。

另外:

 use Monolog\Logger; use Monolog\Handler\StreamHandler; $log = new Logger('sql'); $log->pushHandler(new StreamHandler(storage_path().'/logs/sql-' . date('Ym-d') . '.log', Logger::INFO)); // add records to the log $log->addInfo($query, $data); 

(Laravel 5.2)我发现最简单的方法就是添加一行代码来监视sql查询: \DB::listen(function($sql) {var_dump($sql); });

对于仅使用DB :: getQueryLog()的laravel 5及以上版本,将不会执行此操作。 默认情况下在这个值

  protected $loggingQueries = false; 

改变它

 protected $loggingQueries = true; 

在下面的文件中进行日志查询。 /vendor/laravel/framework/src/illuminate/Database/Connection.php然后我们可以使用DB :: getQueryLog()来打印查询。