J'essaie d'afficher le journal pour une requête, mais DB::getQueryLog()
je renvoie simplement un tableau vide:
$user = User::find(5);
print_r(DB::getQueryLog());
Résultat
Array
(
)
Comment afficher le journal de cette requête?
J'essaie d'afficher le journal pour une requête, mais DB::getQueryLog()
je renvoie simplement un tableau vide:
$user = User::find(5);
print_r(DB::getQueryLog());
Résultat
Array
(
)
Comment afficher le journal de cette requête?
Réponses:
Par défaut, le journal des requêtes est désactivé dans Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448
Vous devrez activer le journal des requêtes en appelant:
DB::enableQueryLog();
ou enregistrez un écouteur d'événements:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
Si vous disposez de plusieurs connexions DB, vous devez spécifier la connexion à enregistrer
Pour activer le journal des requêtes pour my_connection
:
DB::connection('my_connection')->enableQueryLog();
Pour obtenir le journal des requêtes pour my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
Pour un cycle de vie de requête HTTP, vous pouvez activer le journal des requêtes dans la handle
méthode de certains BeforeAnyDbQueryMiddleware
middleware , puis récupérer les requêtes exécutées dans la terminate
méthode du même 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 chaîne d'un middleware ne fonctionnera pas pour les commandes artisanales, vous pouvez donc activer le journal des requêtes dans l' artisan.start
écouteur d'événements pour l'exécution de la CLI .
Par exemple, vous pouvez le mettre dans le bootstrap/app.php
fichier
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
Laravel garde toutes les requêtes en mémoire. Ainsi, dans certains cas, comme lors de l'insertion d'un grand nombre de lignes ou lors d'un travail de longue durée avec beaucoup de requêtes, cela peut amener l'application à utiliser un excès de mémoire.
Dans la plupart des cas, vous n'aurez besoin du journal des requêtes que pour le débogage, et si tel est le cas, je vous recommande de l'activer uniquement pour le développement.
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
Références
\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
fonction de rappel a une signature différente. C'est plus comme ça: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
Si tout ce qui vous importe vraiment, c'est la requête réelle (la dernière exécution) à des fins de débogage rapide:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
faites un print_r()
on $laQuery[0]
pour obtenir la requête complète, y compris les liaisons. (la $lcWhatYouWant
variable ci-dessus aura les variables remplacées par ??
)
Si vous utilisez autre chose que la connexion principale mysql, vous devrez les utiliser à la place:
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(avec votre nom de connexion où "mysql2" est)
Vous devez d'abord activer la journalisation des requêtes
DB::enableQueryLog();
Ensuite, vous pouvez obtenir des journaux de requêtes simplement:
dd(DB::getQueryLog());
Il serait préférable d'activer la journalisation des requêtes avant le démarrage de l'application, ce que vous pouvez faire dans un BeforeMiddleware, puis récupérer les requêtes exécutées dans AfterMiddleware.
Mettez ceci sur le fichier 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>';
});
Soumis par msurguy, code source dans cette page . Vous trouverez ce code de correctif pour laravel 5.2 dans les commentaires.
Apparemment avec Laravel 5.2, la fermeture DB::listen
ne reçoit qu'un seul paramètre.
Donc, si vous souhaitez utiliser DB::listen
Laravel 5.2, vous devez faire quelque chose comme:
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);
}
);
Pour laravel 5.8, ajoutez simplement dd ou dump .
Ex:
DB::table('users')->where('votes', '>', 100)->dd();
ou
DB::table('users')->where('votes', '>', 100)->dump();
Utilisez toSql()
plutôt que get()
comme ça:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'
En continuant de Apparemment avec Laravel 5.2, la fermeture dans DB :: listen ne reçoit qu'un seul paramètre ... réponse ci-dessus: vous pouvez mettre ce code dans le script Middleware et l'utiliser dans les routes.
Aditionellement:
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);
Ce code est pour:
Voici le code, basé sur la réponse de @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();
}
});
Le noyau est la if(stripos...
ligne, qui empêche la récursivité de l'insertion de l' insert into log
instruction sql dans la base de données.
Je pense que la réponse se trouve dans cet article: https://arjunphp.com/laravel-5-5-log-eloquent-queries/
est rapide et simple à réaliser la journalisation des requêtes.
Il suffit d'ajouter à AppServiceProvider
la boot
méthode un rappel pour écouter les requêtes 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));
});
}
}
Supposons que vous souhaitiez imprimer la requête SQL des instructions suivantes.
$user = User::find(5);
Il vous suffit de procéder comme suit:
DB::enableQueryLog();//enable query logging
$user = User::find(5);
print_r(DB::getQueryLog());//print sql query
Cela imprimera la dernière requête exécutée dans Laravel.
Pour laravel 5 et les versions ultérieures en utilisant uniquement DB :: getQueryLog (), cela ne fonctionnera pas. Par défaut, la valeur de
protected $loggingQueries = false;
changez-le en
protected $loggingQueries = true;
dans le fichier ci-dessous pour la requête de journalisation.
/vendor/laravel/framework/src/illuminate/Database/Connection.php
Et puis nous pouvons utiliser l' DB::getQueryLog()
endroit où vous souhaitez imprimer la requête.
vendor
fichiers. Ils doivent être conservés d'origine.