Другое

Получить сырой SQL запрос в Laravel (полное руководство)

Узнайте, как извлечь сырой SQL запрос из билдера запросов Laravel. Используйте toSql(), getBindings(), макросы и пакеты для отладки и оптимизации запросов для разработки.

Как получить строку исходного SQL‑запроса из билдера запросов Laravel?

Дан следующий код:

php
DB::table('users')->get();

Я хочу получить строку исходного SQL‑запроса, которую сгенерирует указанный выше билдер запросов. В этом примере это будет SELECT * FROM users.

Как это сделать?

Вы можете получить строку исходного SQL‑запроса из билдера запросов Laravel, используя метод toSql().
Для примера DB::table('users')->get() вызов toSql() на экземпляре билдера вернёт строку SELECT * FROM users, но запрос не будет выполнен.

Содержание

Базовый метод toSql()

Самый простой способ получить исходный SQL‑запрос – использовать метод toSql(), который возвращает строку SQL без выполнения запроса и без извлечения данных:

php
$query = DB::table('users')->where('id', 1);
$sql = $query->toSql();

Он вернёт:

select * from `users` where `id` = ?

Как объясняет Tinkerwell, этот метод полезен, когда вы не хотите изменять данные и просто хотите просмотреть сгенерированный SQL.

Получение SQL с привязками

Метод toSql() показывает запрос только с плейсхолдерами ?, но не реальными значениями. Чтобы получить полный SQL с заменёнными привязками, нужно объединить toSql() с getBindings():

Метод 1: Использование str_replace_array()

php
$query = DB::table('users')
    ->where('id', 1)
    ->where('email', 'test@example.com');
$sql = str_replace_array('?', $query->getBindings(), $query->toSql());

Для Laravel 5.8 и новее можно использовать фасад Str:

php
use Illuminate\Support\Str;

$sql = Str::replaceArray('?', $query->getBindings(), $query->toSql());

Метод 2: Использование vsprintf()

Как пишет Aryan Vania, можно применить vsprintf() для форматирования запроса:

php
$sql = vsprintf(str_replace('?', '%s', $query->toSql()), $query->getBindings());

Метод 3: Продвинутое управление привязками

Для более сложных сценариев с правильной экранизацией gist от Jesse Obrien предлагает надёжное решение:

php
use Illuminate\Database\Query\Builder;

Builder::macro('fullSql', function () {
    $sql = str_replace(['%', '?'], ['%%', '%s'], $this->toSql());
    $handledBindings = array_map(function ($binding) {
        if (is_numeric($binding)) {
            return $binding;
        }
        $value = str_replace(['\\', "'"], ['\\\\', "\\'"], $binding);
        return "'{$value}'";
    }, $this->getConnection()->prepareBindings($this->getBindings()));
    
    return vsprintf($sql, $handledBindings);
});

// Использование:
$sql = $query->fullSql();

Создание пользовательских макросов

Вы можете расширить билдер запросов Laravel, создавая макросы в сервис‑провайдере. Как отмечает DEV Community:

php
// В AppServiceProvider.php
use Illuminate\Database\Query\Builder;

public function boot()
{
    Builder::macro('toRawSql', function () {
        return vsprintf(str_replace('?', '%s', $this->toSql()), $this->getBindings());
    });
}

// Использование:
$sql = DB::table('users')->where('id', 1)->toRawSql();

Такой макрос добавит метод toRawSql(), который возвращает полный SQL‑строку с привязками.

Использование пакетов

Для более надёжного решения рассмотрите специализированные пакеты:

Пакет to-raw-sql

Как упомянуто в Reddit, пакет to-raw-sql предоставляет метод toRawSql():

bash
composer require spiralaw/to-raw-sql

Laravel Debugbar

Arie Visser рекомендует использовать Laravel Debugbar, который автоматически отображает исходный SQL с привязками в панели отладки при выполнении запросов.

Подходы к отладке

Логирование запросов

Laracoding советует включить логирование запросов, чтобы захватить несколько запросов:

php
DB::enableQueryLog();
// Ваш запрос здесь
DB::table('users')->get();
$queries = DB::getQueryLog();

Laravel Debugbar

Для комплексной отладки Arie Visser предлагает использовать Laravel Debugbar, который автоматически показывает исходный SQL с привязками при выполнении запросов.

Источники

  1. How to get the raw SQL query from the Laravel Query Builder - Tinkerwell
  2. How to Extract Raw SQL Output from the Laravel Query Builder? 2 Easiest Solutions! - Medium
  3. How to Get the Raw SQL Query from Laravel Query Builder - DEV Community
  4. Six Ways to Get Raw SQL Output From Query Builder in Laravel - Arie Visser
  5. How do I get the query builder to output its raw SQL query as a string - Medium
  6. How to Get Raw SQL Query From Laravel Query Builder or Model - Laracoding
  7. How To Get The Raw SQL Query From Laravel’s Query Builder? - Uptimia
  8. toRawSql(): Get raw SQL from Laravel Query Builder and Eloquent Builder - Reddit
  9. Bind parameters into the SQL query for Laravel ORM - GitHub Gist
  10. Laravel how to get query with bindings? - Stack Overflow

Заключение

Чтобы получить строку исходного SQL‑запроса из билдера запросов Laravel:

  1. Используйте toSql() для базового SQL без привязок.
  2. Объедините с getBindings() и методами замены строк для полного SQL с реальными значениями.
  3. Создайте пользовательские макросы для повторного использования.
  4. Рассмотрите пакеты вроде to-raw-sql для надёжной функциональности.
  5. Используйте инструменты отладки как Laravel Debugbar во время разработки.

Наиболее распространённый подход – toSql() в сочетании с getBindings() и заменой строк, но для сложных приложений создание собственных макросов или использование специализированных пакетов обеспечивает лучшую поддерживаемость и надёжность генерации SQL.

Авторы
Проверено модерацией
Модерация