Как получить запрос, выполненный в 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. Несколько соединений БД

Если у вас более одного соединения с БД, вы должны указать, какое соединение с журналом

Чтобы my_connection журнал запросов для my_connection :

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

Чтобы получить журнал запросов для my_connection :

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

2. Где включить журнал запросов?

Для жизненного цикла HTTP-запроса вы можете включить журнал запросов в методе обработки некоторого промежуточного программного обеспечения BeforeAnyDbQueryMiddleware а затем получить выполненные запросы в методе 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 событий artisan.start .

Например, вы можете поместить его в файл bootstrap/app.php

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

3. Память

Laravel сохраняет все запросы в памяти. Поэтому в некоторых случаях, например, при вставке большого количества строк или при длительном запуске задания с большим количеством запросов, это может привести к тому, что приложение будет использовать избыточную память.

В большинстве случаев вам понадобится журнал запросов только для отладки, и если это так, я бы рекомендовал вам включить его только для разработки.

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

Рекомендации

Если все, что вам действительно нужно, – это фактический запрос (последний запуск) для быстрой отладки:

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

сделайте print_r() в $laQuery[0] чтобы получить полный запрос. (переменная $lcWhatYouWant выше будет заменена переменными на ?? )

По-видимому, с Laravel 5.2 закрытие в DB::listen только получает единственный параметр.

Итак, если вы хотите использовать DB::listen в Laravel 5.2, вы должны сделать что-то вроде:

 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); } ); 

Сначала необходимо включить ведение журнала запросов

DB::enableQueryLog();

Было бы лучше, если вы включили ведение журнала запросов до запуска приложений, что вы можете сделать в формате BeforeMiddleware, а затем получить выполненные запросы в AfterMiddleware.

Поместите это на файл route.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, исходный код на этой странице . Вы найдете этот исправление для laravel 5.2 в комментариях.

Этот код предназначен для:

  • Laravel 5.2
  • Записывать операторы в базу данных 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... line, которая предотвращает рекурсию вставки insert into log инструкцию insert into log sql в базу данных.

вы просто следуете этим шагам, если хотите распечатать запрос, перейдите к поставщику \ laravel \ framework \ src \ Illuminate \ Database \ connection.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); });

Для laravel 5 и далее, используя только DB :: getQueryLog (), не будет. По умолчанию в этом значении

  protected $loggingQueries = false; 

измените его на

 protected $loggingQueries = true; 

в следующем файле для ведения журнала. /vendor/laravel/framework/src/illuminate/Database/Connection.php И тогда мы можем использовать DB :: getQueryLog (), где вы хотите распечатать запрос.