Как получить сырой SQL-запрос из Query Builder в Laravel в виде строки?
Способы получения полного SQL-запроса в Laravel
Вы столкнулись с типичной ситуацией при отладке запросов. К сожалению, встроенный метод toSql() действительно возвращает только запрос с плейсхолдерами. Однако существует несколько проверенных способов получить готовый SQL со всеми значениями.
Способ 1: Использование макроса для Query Builder (рекомендуется)
Добавьте этот макрос в AppServiceProvider::boot():
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Query\Builder;
// В методе boot() вашего AppServiceProvider
Builder::macro('toRawSql', function() {
$sql = $this->toSql();
$bindings = $this->getBindings();
foreach ($bindings as $binding) {
$value = is_numeric($binding) ? $binding : "'" . $binding . "'";
$sql = preg_replace('/\?/', $value, $sql, 1);
}
return $sql;
});
Теперь вы можете использовать:
$query = DB::table('users')
->join('orders', 'users.id', '=', 'orders.user_id')
->where('users.active', 1)
->whereIn('orders.status', ['pending', 'processing'])
->orderBy('users.created_at', 'desc');
dd($query->toRawSql()); // Выведет готовый SQL
Способ 2: Встроенная функция для Eloquent моделей
Если вы работаете с Eloquent, можно использовать комбинацию методов:
$users = User::join('orders', 'users.id', '=', 'orders.user_id')
->where('users.active', 1)
->whereIn('orders.status', ['pending', 'processing'])
->orderBy('users.created_at', 'desc');
// Получаем SQL с плейсхолдерами
$sql = $users->toSql();
// Получаем массив bindings
$bindings = $users->getBindings();
// Форматируем для вывода
dump([
'sql' => $sql,
'bindings' => $bindings
]);
Способ 3: Использование Laravel Debugbar
Самый удобный способ для разработки — установить пакет barryvdh/laravel-debugbar:
composer require barryvdh/laravel-debugbar --dev
После установки на каждой странице будет отображаться панель с выполненными SQL-запросами, их временем выполнения и полным текстом запроса с подставленными значениями.
Способ 4: Логирование всех запросов
Включите логирование запросов в глобальном масштабе:
// В AppServiceProvider::boot()
DB::listen(function ($query) {
$sql = $query->sql;
$bindings = $query->bindings;
// Логирование в файл
\Log::info('SQL: ' . $sql, $bindings);
// Или вывод в консоль (если используете artisan tinker)
// dump($sql, $bindings);
});
Способ 5: Использование artisan tinker для отладки
В консоли выполните:
php artisan tinker
// Затем введите запрос
> $query = DB::table('users')->where('id', 1);
> $query->dd(); // dump and die — покажет SQL и bindings
Метод dd() — это встроенная возможность Laravel, которая выводит отладочную информацию и прекращает выполнение.
Рекомендация
Для быстрой отладки используйте макрос toRawSql() из первого способа. Для постоянного мониторинга — установите Debugbar. Метод dd() хорош для разовых проверок в tinker или контроллерах.
Важно: никогда не используйте эти методы в production-окружении, так как они могут раскрыть структуру базы данных и чувствительные данные.
<<Альтернативный подход: использование пакета spatie/laravel-sql-commenter
Если вам нужно не просто увидеть SQL, а понять, какой код его сгенерировал, рекомендую пакет от Spatie. Он добавляет комментарии к SQL-запросам с указанием файла и строки вызова.
composer require spatie/laravel-sql-commenter
После установки в логах MySQL вы увидите:
/* App\Http\Controllers\UserController::index:25 */
SELECT * FROM `users` WHERE `active` = 1
Это особенно полезно, когда в проекте много запросов и нужно быстро найти проблемный участок кода.
Ещё один способ: метод dump()
В Laravel 8+ появился метод dump() для Query Builder, который выводит запрос с bindings, но не прекращает выполнение:
$users = DB::table('users')
->where('active', 1)
->dump() // Выведет SQL и bindings
->get(); // Продолжит выполнение
Это удобно, когда нужно отладить цепочку запросов, не прерывая их выполнение.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги