Sto cercando di visualizzare il registro per una query, ma DB::getQueryLog()
sta solo restituendo un array vuoto:
$user = User::find(5);
print_r(DB::getQueryLog());
Risultato
Array
(
)
Come posso visualizzare il registro per questa query?
Sto cercando di visualizzare il registro per una query, ma DB::getQueryLog()
sta solo restituendo un array vuoto:
$user = User::find(5);
print_r(DB::getQueryLog());
Risultato
Array
(
)
Come posso visualizzare il registro per questa query?
Risposte:
Per impostazione predefinita, il registro delle query è disabilitato in Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448
Sarà necessario abilitare il registro delle query chiamando:
DB::enableQueryLog();
o registra un listener di eventi:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
Se si dispone di più di una connessione DB, è necessario specificare quale connessione registrare
Per abilitare il registro delle query per my_connection
:
DB::connection('my_connection')->enableQueryLog();
Per ottenere il registro delle query per my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
Per un ciclo di vita delle richieste HTTP, è possibile abilitare il registro delle query nel handle
metodo di alcuni BeforeAnyDbQueryMiddleware
middleware e quindi recuperare le query eseguite nelterminate
metodo dello stesso middleware.
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()
);
}
}
La catena di un middleware non verrà eseguita per comandi artigianali, quindi per l'esecuzione della CLI è possibile abilitare il registro delle query nel artisan.start
listener di eventi.
Ad esempio, puoi inserirlo nel bootstrap/app.php
file
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
Laravel mantiene tutte le domande in memoria. Pertanto, in alcuni casi, ad esempio quando si inserisce un numero elevato di righe o si esegue un processo di lunga durata con molte query, ciò può far sì che l'applicazione utilizzi memoria in eccesso.
Nella maggior parte dei casi è necessario il registro delle query solo per il debug e, in tal caso, consiglierei di abilitarlo solo per lo sviluppo.
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
Riferimenti
\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
funzione di callback ha una firma diversa. È più così: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
Se tutto ciò che ti interessa è la query effettiva (l'ultima esecuzione) per scopi di debug rapido:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
fare un print_r()
on $laQuery[0]
per ottenere la query completa, inclusi i binding. (la $lcWhatYouWant
variabile sopra avrà le variabili sostituite con ??
)
Se stai usando qualcosa di diverso dalla connessione mysql principale, dovrai invece utilizzare questi:
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(con il nome della tua connessione dove si trova "mysql2")
È necessario prima abilitare la registrazione delle query
DB::enableQueryLog();
Quindi puoi ottenere i log delle query semplicemente:
dd(DB::getQueryLog());
Sarebbe meglio se abiliti la registrazione delle query prima dell'avvio dell'applicazione, cosa che puoi fare in un BeforeMiddleware e poi recuperare le query eseguite in AfterMiddleware.
Metti questo sul file 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>';
});
Inserito da msurguy, codice sorgente in questa pagina . Troverai questo codice di correzione per laravel 5.2 nei commenti.
Apparentemente con Laravel 5.2, la chiusura in DB::listen
riceve solo un singolo parametro.
Quindi, se vuoi usare DB::listen
in Laravel 5.2, dovresti fare qualcosa del tipo:
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('\'Y-m-d 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('Y-m-d') . '_query.log'),
'a+'
);
fwrite($logFile, date('Y-m-d H:i:s') . ': ' . $query . PHP_EOL);
fclose($logFile);
}
);
Per laravel 5.8 basta aggiungere dd o dump .
Ex:
DB::table('users')->where('votes', '>', 100)->dd();
o
DB::table('users')->where('votes', '>', 100)->dump();
riferimento: https://laravel.com/docs/5.8/queries#debugging
Usa toSql()
invece di get()
così:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'
Nel proseguimento di Apparently with Laravel 5.2, la chiusura in DB :: Listen riceve solo un singolo parametro ... risposta sopra: è possibile inserire questo codice nello script Middleware e utilizzarlo nelle route.
Inoltre:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('sql');
$log->pushHandler(new StreamHandler(storage_path().'/logs/sql-' . date('Y-m-d') . '.log', Logger::INFO));
// add records to the log
$log->addInfo($query, $data);
Questo codice è per:
Ecco il codice, che si basa sulla risposta di @milz:
DB::listen(function($sql) {
$LOG_TABLE_NAME = 'log';
foreach ($sql->bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$sql->bindings[$i] = $binding->format('\'Y-m-d 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();
}
});
Il nucleo è la if(stripos...
linea, che impedisce la ricorsione dell'inserimento insert into log
dell'istruzione sql nel database.
Penso che la risposta si trovi in questo articolo: https://arjunphp.com/laravel-5-5-log-eloquent-queries/
è rapido e semplice per ottenere la registrazione delle query.
Non vi resta che aggiungere al AppServiceProvider
nel boot
metodo di un callback per ascoltare le query DB:
namespace App\Providers;
use DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
DB::listen(function($query) {
logger()->info($query->sql . print_r($query->bindings, true));
});
}
}
Supponiamo di voler stampare la query SQL delle seguenti istruzioni.
$user = User::find(5);
Devi solo fare come segue:
DB::enableQueryLog();//enable query logging
$user = User::find(5);
print_r(DB::getQueryLog());//print sql query
Questo stamperà l'ultima query eseguita in Laravel.
Per laravel 5 e successivi utilizzando solo DB :: getQueryLog (), non funzionerà. DA predefinito in questo il valore di
protected $loggingQueries = false;
cambiarlo in
protected $loggingQueries = true;
nel file seguente per la registrazione della query.
/vendor/laravel/framework/src/illuminate/Database/Connection.php
E quindi possiamo usare il punto in DB::getQueryLog()
cui desideri stampare la query.
vendor
file. Devono essere mantenuti originali.