← Заметки и статьи о Laravel PHP

14 мая 2015 перевод

Отладка запросов в Laravel

Laravel предоставляет отличный конструктор запросов и ORM — Eloquent. Это позволяет писать запросы невероятно простым и понятным способом. Тем не менее, бывают случаи, когда вам нужно создать сложный запрос и увидеть, какой SQL в действительности сгенерируется.

В этом руководстве мы пройдёмся по некоторым способам получения этой информации, начиная с простых методов и заканчивая мощным пакетом.

Перед тем, как мы начнём, давайте построим запрос для вымышленного бага, который нам прислали:

Баг #22321
Проблема: Поиск пользователей выдаёт слишком много результатов
Как увидеть баг: Я ищу «John Doe john@example.org» 
и получаю назад сотни результатов.

Пройдя в код, мы нашли ту часть, где, скорее всего, скрыта ошибка:

$results = User::where(function($q) use ($request) {
    $q->orWhere('email', 'like', '%john@example.org%');
    $q->orWhere('first_name', 'like', '%John%');
    $q->orWhere('last_name', 'like', '%Doe%');
})->get();

Можете ли вы уже обнаружить проблему? Если нет, не переживайте, мы начнём отладку этого запроса и увидим, что на самом деле происходит.

Простая отладка запросов

Самый простой метод увидеть запрос, который генерируется — использовать метод toSql(). Всё, что нам нужно сделать — заменить get() на toSql() и затем вывести результаты с помощью dd().

Вот обновлённый запрос:

$results = User::where(function($q) use ($request) {
    $q->orWhere('email', 'like', '%john@example.org%');
    $q->orWhere('first_name', 'like', '%John%');
    $q->orWhere('last_name', 'like', '%Doe%');
})->toSql();
dd($results)

Запустив это в браузере, мы увидим следующий SQL:

select * from `users` where (`email` like ? or `first_name` like ? or `last_name` like ?)

Этот метод хорош для быстрого отображения SQL запросов. Тем не менее, он не отображает биндинги и показывает ? на их месте. В некоторых случаях, в зависимости от сложности биндингов, этого вам будет достаточно для отладки запроса.

Прослушивание событий базы данных

Вторым способом является прослушивание событий объекта DB. Для этого можно воспользоваться небольших хелпером ниже:

DB::listen(function($sql) {
    var_dump($sql);
});

Теперь, когда загрузится страница, вы получите тот же самый вывод, как и в предыдущем способе.

select * from `users` where (`email` like ? or `first_name` like ? or `last_name` like ?)

DB::listen — более продвинутый способ, который принимает 2 дополнительных параметра для доступа к таймингу и биндингам:

DB::listen(function($sql, $bindings, $time) {
    var_dump($sql);
    var_dump($bindings);
    var_dump($time);
});

Это выведет нам:

string 'select * from `users` where (`email` like ? or `first_name` like ? or `last_name` like ?)' (length=89)
array (size=3)
  0 => string '%john@example.org%' (length=18)
  1 => string '%John%' (length=6)
  2 => string '%Doe%' (length=5)
float 35.63

Как вы видите, этот способ предоставляет нам запрос, биндинги и время выполнения запроса.

Пакет Debugbar

Ещё одним способом отладки запросов является установка Laravel Debugbar. После установки вы сможете просмотреть все запросы в специальной вкладке панели браузера. Это достаточно мощный пакет, и он даёт большое кол-во информации о вашем приложении.

Заключение

Вы уже нашли ошибку? Вместо orWhere нужно использовать where. Финальный код с фиксом:

$results = User::where(function($q) use ($request) {
    $q->where('email', 'like', '%john@example.org%');
    $q->where('first_name', 'like', '%John%');
    $q->where('last_name', 'like', '%Doe%');
})->get();

Что даст нам корректный запрос:

select * from `users` where (`email` like '%john@example.org%' and `first_name` like '%John%' and `last_name` like '%Doe%')

Удачной отладки!

Источник: https://scotch.io/tutorials/debugging-queries-in-laravel

Плюсануть
Поделиться
Отправить