Ce tuto se base sur un Laravel 9.18
Vous exécutez probablement quotidiennement des requêtes SQL dans votre application Laravel que ce soit depuis Eloquent ou bien le Query Builder.
Mais que faire si vous êtes amené à debugger ces requêtes ? Comment visualiser la query, vérifier les arguments, le temps d'exécution ...
Nous allons voir dans cet article les différentes options qui s'offrent à nous afin de débugger efficacement nos requêtes dans votre application Laravel !
toSql & getBindings
Probablement les plus vieilles méthodes de cet article, les méthodes toSql
et getBindings
datent de l'époque de Laravel 4.
La premiere, une fois ajoutée à votre requête affichera la query sous la forme d'un string sans l'exécuter.
1$dump = User::where('name', 'Taylor')->toSql();2 3echo $dump;4 5# "select * from `users` where `name` = ?"
Tandis que la seconde affichera dans un array
les bindings de votre requête.
1$dump = User::where('name', 'Taylor')->getBindings();2 3dd($dump);4 5# array:1 [6# 0 => "Taylor"7# ]
Une association des deux comportements, requête et binding, est possible grâce à la méthode toRawSql
:
1$dump = User::where('name', 'Taylor')->toRawSql();2 3dd($dump);4 5# select * from "users" where "name" = 'Taylor'
Une façon plus concise d'obtenir ce résultat consistera à utiliser la méthode ddRawSql
:
1User::where('name', 'Taylor')->ddRawSql();2 3# select * from "users" where "name" = 'Taylor'
dd & dump
La méthode dd
combine nos deux précédentes méthodes en une, elle retournera dans un array
la requête ainsi que les bindings sans l'exécuter.
1User::where('name', 'Taylor')->dd();2 3# "select * from "users" where "name" = ?"4#5# array:1 [6# 0 => "Taylor"7# ]
La méthode dump
diffère quelque peu de dd
en retournant une instance de Builder vous permettant d'exécuter dans un second temps la requête !
1$builder = User::where('name', 'Taylor')->dump(); 2 3# array:1 [ 4# 0 => "Taylor" 5#] 6 7$user = $builder->first(); 8 9dd($user);10 11# {#271312# +"id": 113# +"name": "Taylor"14# }
Dans cet exemple, la query, les bindings ainsi que le résultat du first()
s'afficheront sur votre écran.
Query logs
Toutes les méthodes que nous venons de voir étaient pratiques mais relativement intrusives vous obligeant à placer judicieusement les dumps dans vos requêtes.
Mais comment faire pour log plusieurs requêtes successives ?
Pour répondre à cette problématique la façade DB de Laravel propose une méthode enableQueryLog
enregistrant toutes les requêtes suivant son utilisation.
1use Illuminate\Support\Facades\DB; 2 3DB::connection()->enableQueryLog(); 4 5User::where('name', 'Taylor')->get(); 6User::where('name', 'Abigail')->get(); 7 8$queries = DB::getQueryLog(); 9 10dd($queries);
Une fois vos requêtes exécutées, cette même façade DB
dispose d'une méthode getQueryLog
récupérant les logs sour la forme d'un tableau associatif.
1^ array:1 [▼ 2 0 => array:3 [▼ 3 "query" => "select * from `users` where `name` = ?" 4 "bindings" => array:1 [▼ 5 0 => "Taylor" 6 ] 7 "time" => 33.1 8 ] 9 ...10]
Listen
Dernière possibilité offerte par Laravel, la façade DB
dispose d'un observer listen
attrapant toutes les requêtes que votre application exécute.
Une fois placé judicieusement dans le boot d'un ServiceProvider
cette méthode sera la moins intrusive de toutes.
1use Illuminate\Support\Facades\DB;2 3DB::listen(function($query) {4 /* Illuminate\Database\Events\QueryExecuted */5 dd($query);6});
Dans cette closure, la variable $query
est une instance de QueryExecuted correspondant à la requête dernièrement exécutée et contenant plusieurs propriétés publiques.
1$query->sql;2$query->bindings;3$query->time;
Ray
Ray est un logiciel open source cherchant à améliorer notre expérience de debug, il fonctionne sur bon nombre de système (PHP, Vue, Javascript ...) mais une attention particulière fut portée sur Laravel.
Ray est un logiciel payant, une offre trial est disponible pour tester l'outil.
Le logiciel permet de debug en live vos applications, d'ajouter une multitude de breakpoints semblables à l'utilisation de xdebug ainsi que de visualiser les performances de vos requêtes SQL !
Après avoir installé le logiciel et ajouté cette dépendance à votre projet :
1composer require spatie/laravel-ray --dev
Vous n'avez plus qu'à activer le log des requêtes avec la méthode showQueries()
.
1ray()->showQueries();
D'une façon semblable au listen que nous avons vu précédemment le boot
d'un ServiceProvider
sera un lieu judicieux pour accueillir cette méthode.
Désormais toutes les requêtes que le framework exécute arriveront dans le logiciel !
Utilisateurs de docker, une configuration spécifique est requise.
When Querying For Longer Than
Toute nouvelle méthode qui fut incluse au framework durant l'écriture de cet article, whenQueryingForLongerThan
est désormais disponible à partir d'un Laravel 9.18.
Contrairement aux précédentes méthodes que nous venons de voir, cette dernière ne permet pas de debugger à proprement parler mais d'exécuter une closure quand une requête dépasse un certain temps d'execution.
1use Illuminate\Support\Facades\DB;2use Illuminate\Database\Connection;3 4DB::whenQueryingForLongerThan($milliseconds = 500, function (Connection $connection) {5 /* Illuminate\Database\Connection */6 $connection;7});
A lire
Autres articles de la même catégorie
Améliorer ses requêtes en base de données
L'ORM de Laravel est un outil remarquable. Mais tout n'est pas forcément dans la doc : connaissiez-vous ces astuces ?
Laravel Jutsu
Optimisez votre application avec le chunk de Laravel
Voyons ce que propose Laravel pour traiter de grandes quantités de données efficacement
Mathieu De Gracia
Traquer un utilisateur dans les logs
Laravel offre la possibilité d'ajouter un contexte unique à chaque ligne de log, voyons comment utiliser cette feature pour traquer les erreurs d'un utilisateur !
Mathieu De Gracia