如何获得在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()
以获取完整查询。 (上面的$lcWhatYouWant
variables将把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()来打印查询。