Bagaimana cara mendapatkan pembangun kueri untuk mengeluarkan kueri SQL mentah sebagai string?

544

Diberikan kode berikut:

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

Saya ingin mendapatkan string kueri SQL mentah yang akan dihasilkan oleh pembuat kueri basis data di atas. Dalam contoh ini, itu akan menjadiSELECT * FROM users .

Bagaimana saya melakukan ini?

meiryo
sumber
14
Laravel Eloquent ORM mendapatkan kueri mentah:echo User::where('status', 1)->toSql();
Muhammad Shahzad
Saya menggunakan paket untuk Laravel - Telescope, ia mencatat semua pertanyaan dan melakukan lebih banyak hal.
vinsa

Jawaban:

660

Untuk menampilkan ke layar pertanyaan terakhir dijalankan, Anda dapat menggunakan ini:

DB::enableQueryLog(); // Enable query log

// Your Eloquent query executed by using get()

dd(DB::getQueryLog()); // Show results of log

Saya percaya pertanyaan terbaru akan berada di bagian bawah array.

Anda akan memiliki sesuatu seperti itu:

array(1) {
  [0]=>
  array(3) {
    ["query"]=>
    string(21) "select * from "users""
    ["bindings"]=>
    array(0) {
    }
    ["time"]=>
    string(4) "0.92"
  }
}

(Terima kasih atas komentar Joshua di bawah ini.)

jfortunato
sumber
2
hmm saya tidak yakin tetapi Anda mungkin dapat menyertai apa yang Anda inginkan dengan paket komposer stackoverflow.com/a/17339752/813181
jfortunato
9
Bahkan mungkin lebih baik untuk menampilkannya ke log aplikasi Anda menggunakan Logkelas: Log::debug(DB::getQueryLog())
msturdy
35
Anda mungkin perlu mengaktifkan ini karena dinonaktifkan secara default sekarang. Anda dapat menggunakan perintah ini untuk menyalakannya sementara:DB::enableQueryLog();
Joshua Fricke
5
Saya mencoba jawaban Anda. Apa yang saya coba adalah DB::enableQueryLog(); dd(DB::getQueryLog());Tapi itu mengembalikan hanya []....
Saya Orang Paling Bodoh
6
Jika Anda memiliki banyak basis data, Anda mungkin perlu melakukannyaDB::connection('database')->getQueryLog()
Damien Ó Ceallaigh
745

Gunakan toSql()metode ini pada QueryBuildercontoh.

DB::table('users')->toSql() akan kembali:

pilih * dari `pengguna`

Ini lebih mudah daripada membuat daftar pendengar acara, dan juga memungkinkan Anda memeriksa seperti apa bentuk kueri pada saat Anda membangunnya.

Steven Mercatante
sumber
6
Saya pikir ini adalah cara termudah ketika menggunakan Eloquent di luar Laravel
Gab
8
@Stormsson Itu tidak mungkin karena PHP tidak pernah memiliki permintaan dengan binding diganti dengan nilainya. Untuk mendapatkan kueri secara keseluruhan, Anda harus mencatatnya dari MySQL. Ada info lebih lanjut di sini: stackoverflow.com/questions/1786322/…
Matthew
40
@ Stormson Anda dapat menggunakan getBindingsmetode. Ini akan mengembalikan binding agar mereka terikat pada pernyataan SQL.
danronmoon
2
Sangat membantu untuk men-debug kueri rumit yang Eloquent menolak untuk dijalankan karena tidak muncul di log kueri.
BobChao87
34
Untuk mendapatkan permintaan dengan bindinds$query = \DB::table('users')->where('id', 10); $sql = str_replace_array('?', $query->getBindings(), $query->toSql()); dd($sql);
Ennio Sousa
88

DB::QueryLog()hanya berfungsi setelah Anda menjalankan kueri $builder->get(). jika Anda ingin mendapatkan kueri sebelum mengeksekusi kueri Anda dapat menggunakan $builder->toSql()metode. ini adalah contoh cara mendapatkan sql dan mengikatnya:

    $query = str_replace(array('?'), array('\'%s\''), $builder->toSql());
    $query = vsprintf($query, $builder->getBindings());
    dump($query);

    $result = $builder->get();

ATAU cukup buat kesalahan kueri Anda seperti memanggil tabel atau kolom yang tidak ada, Anda akan melihat kueri yang dihasilkan dalam pengecualian XD

Kakashi
sumber
3
Sejauh ini, inilah jawaban terbaik, sederhana dan langsung pada intinya. Terima kasih :)
Sobakus
18
Sebagai satu $query = vsprintf(str_replace(array('?'), array('\'%s\''), $builder->toSql()), $builder->getBindings());
kalimat
Ini harus dimasukkan dalam kerangka kerja sebagai fungsi asli .. terima kasih
Tomáš Mleziva
Perhatikan bahwa ini tidak akan berfungsi jika kueri Anda sudah memiliki tanda persen seperti untuk LIKEkueri atau saat memformat tanggal. Anda harus melarikan diri dari yang pertama dengan tanda dua persen.
The Unknown Dev
Apakah ada masalah keamanan saat melakukan ini? Apakah binding datang dari sanitasi $builder->getBindings()?
solidau
56

Anda dapat mendengarkan acara 'illuminate.query'. Sebelum kueri tambahkan pendengar acara berikut:

Event::listen('illuminate.query', function($query, $params, $time, $conn) 
{ 
    dd(array($query, $params, $time, $conn));
});

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

Ini akan mencetak sesuatu seperti:

array(4) {
  [0]=>
  string(21) "select * from "users""
  [1]=>
  array(0) {
  }
  [2]=>
  string(4) "0.94"
  [3]=>
  string(6) "sqlite"
}
Rubens Mariuzzo
sumber
1
Saya mendapatkan Call to undefined method Illuminate \ Database \ Query \ Builder :: listen () di Laravel 4
Miguel Stevens
2
Terima kasih, ini bagus. Baik untuk dicatat bahwa dd adalah fungsi yang menghasilkan Dump, variabel yang diberikan dan eksekusi akhir skrip dan juga untuk mengimpor Event, termasukuse Illuminate\Support\Facades\Event;
radtek
1
@radtek: Daripada use Illuminate\Support\Facades\Event;Anda hanya dapat melakukan use Event;karena itu adalah fasad .
TachyonVortex
50

Jika Anda mencoba untuk mendapatkan Log menggunakan Illuminate tanpa Laravel use:

\Illuminate\Database\Capsule\Manager::getQueryLog();

Anda juga dapat mengaktifkan fungsi cepat seperti:

function logger() {
    $queries = \Illuminate\Database\Capsule\Manager::getQueryLog();
    $formattedQueries = [];
    foreach( $queries as $query ) :
        $prep = $query['query'];
        foreach( $query['bindings'] as $binding ) :
            $prep = preg_replace("#\?#", is_numeric($binding) ? $binding : "'" . $binding . "'", $prep, 1);
        endforeach;
        $formattedQueries[] = $prep;
    endforeach;
    return $formattedQueries;
}

EDIT

versi yang diperbarui tampaknya memiliki penebangan kueri dinonaktifkan secara default (di atas mengembalikan array kosong). Untuk menghidupkan kembali, saat menginisialisasi Manajer Kapsul, ambil contoh koneksi dan panggil enableQueryLogmetode

$capsule::connection()->enableQueryLog();

Sunting LAGI

Dengan mempertimbangkan pertanyaan aktual, Anda sebenarnya dapat melakukan hal berikut untuk mengonversi kueri tunggal saat ini alih-alih semua kueri sebelumnya:

$sql = $query->toSql();
$bindings = $query->getBindings();
Luke Snowden
sumber
saya mendapatkan jenis pengembalian ini dari kueri "name = [{" name ":" rifat "}]" apa yang harus saya lakukan untuk mendapatkan "name = rifat" saja?
incorporeal
Saya akan mencetak binding Anda, sepertinya Anda memberikan array bukan string
Luke Snowden
Ini adalah awal yang bermanfaat, tetapi tampaknya lalai untuk menambahkan tanda kutip tunggal di sekitar nilai parameter, seperti ketika saya melewatkan string seperti 'US/Eastern'.
Ryan
1
@Ryan ini benar maka mengapa saya nyatakan quick function. Saya percaya kode yang mendasarinya akan menggunakan metode prep ( php.net/manual/en/mysqli.prepare.php ), itulah sebabnya hanya ?diperlukan. Anda dapat php.net/manual/en/function.is-numeric.php untuk menentukan apakah akan merangkum input dalam tanda kutip tunggal.
Luke Snowden
1
@LukeSnowden Jawaban Anda jenius! Saya akhirnya meluangkan waktu untuk mencoba versi baru Anda (yang saya edit di atas untuk memasukkan is_numericide Anda ), dan berhasil! Aku suka ini. Terima kasih.
Ryan
36

Ada metode dalam fasih untuk mendapatkan string kueri.

toSql ()

dalam kasus kami,

 DB::table('users')->toSql(); 

kembali

select * from users

adalah solusi tepat yang mengembalikan string kueri SQL .. Semoga ini bermanfaat ...

CelinVeronicca
sumber
11
bagaimana dengan binding kueri? mis. ketika Anda melakukan ->where('foo', '=', 'bar')bar tidak akan ditampilkan di sql
Toskan
28
$data = User::toSql();
echo $data; //this will retrun select * from users. //here User is model
Kuldeep Mishra
sumber
Ini jauh lebih tepat, terkontrol, dan memenuhi kebutuhan pertanyaan.
benjaminhull
Terima kasih atas komentarmu.
Kuldeep Mishra
2
Anda dapat menambahkan ->toSql()seperti yang akan Anda lakukan jika ada lebih banyak argumen setelah model. misalnyaUser::where('id', 1)->toSql()
Toby Mellor
24

Jika Anda menggunakan laravel 5.1 dan MySQL Anda dapat menggunakan fungsi ini yang dibuat oleh saya:

/*
 *  returns SQL with values in it
 */
function getSql($model)
{
    $replace = function ($sql, $bindings)
    {
        $needle = '?';
        foreach ($bindings as $replace){
            $pos = strpos($sql, $needle);
            if ($pos !== false) {
                if (gettype($replace) === "string") {
                     $replace = ' "'.addslashes($replace).'" ';
                }
                $sql = substr_replace($sql, $replace, $pos, strlen($needle));
            }
        }
        return $sql;
    };
    $sql = $replace($model->toSql(), $model->getBindings());

    return $sql;
}

Sebagai parameter input, Anda dapat menggunakan salah satu dari ini

Menerangi \ Basis Data \ Eloquent \ Builder

Menerangi \ Database \ Eloquent \ Relations \ HasMany

Menerangi \ Database \ Query \ Builder

Yevgeniy Afanasyev
sumber
Jawaban ditingkatkan untuk mencakup semua komentar yang dibuat dalam komentar. Terima kasih banyak.
Yevgeniy Afanasyev
13

Pertama, Anda harus mengaktifkan log kueri dengan menelepon:

DB::enableQueryLog();

setelah permintaan menggunakan fasad DB Anda dapat menulis:

dd(DB::getQueryLog());

output akan seperti di bawah ini:

array:1 [▼
  0 => array:3 [▼
    "query" => "select * from `users` left join `website_user` on `users`.`id` = `website_user`.`user_id` left join `region_user` on `users`.`id` = `region_user`.`user_id` left ▶"
    "bindings" => array:5 [▶]
    "time" => 3.79
  ]
]
Ravi Mane
sumber
jawaban yang sangat membantu
Anoop PS
hai saya telah menggunakan $ result = DB :: select ('select * from sqrt_user_modules mana user_id =: id', ['id' => $ user]); DB :: enableQueryLog (); tetapi tidak mendapatkan output dd (DB :: getQueryLog ());
Anoop PS
apakah kita perlu memasukkan perpustakaan apa pun
Anoop PS
1
Langkah 1: DB :: enableQueryLog (); langkah 2: $ result = DB :: select ('select * from sqrt_user_modules mana user_id =: id', ['id' => $ user]); langkah 3: dd (DB :: getQueryLog ());
Ravi Mane
12

Ini adalah solusi terbaik yang bisa saya sarankan kepada siapa pun untuk men-debug permintaan terakhir atau permintaan terakhir yang fasih meskipun ini juga telah dibahas:

// query builder
$query = DB::table('table_name')->where('id', 1);

// binding replaced
$sql = str_replace_array('?', $query->getBindings(), $query->toSql());

// for laravel 5.8^
$sql = Str::replaceArray('?', $query->getBindings(), $query->toSql());

// print
dd($sql);
justnajm
sumber
10

Cara pertama:

Cukup Anda dapat melakukan hal-hal berikut menggunakan toSql()metode,

$query = DB::table('users')->get();

echo $query->toSql();

Jika tidak berfungsi, Anda dapat mengaturnya dari dokumentasi laravel .

Cara kedua:

Cara lain untuk melakukannya adalah

DB::getQueryLog()

tetapi jika itu mengembalikan array kosong maka secara default itu dinonaktifkan kunjungi ini ,

cukup aktifkan dengan DB::enableQueryLog()dan itu akan bekerja :)

untuk info lebih lanjut kunjungi Masalah Github untuk mengetahui lebih banyak tentangnya.

Semoga bermanfaat :)

Sagar Naliyapara
sumber
10

Sebuah 'macroable' pengganti untuk mendapatkan query SQL dengan binding.

  1. Tambahkan fungsi makro di bawah ini dalam metode.AppServiceProvider boot()

    \Illuminate\Database\Query\Builder::macro('toRawSql', function(){
        return array_reduce($this->getBindings(), function($sql, $binding){
            return preg_replace('/\?/', is_numeric($binding) ? $binding : "'".$binding."'" , $sql, 1);
        }, $this->toSql());
    });
  2. Tambahkan alias untuk Eloquent Builder. ( Laravel 5.4+ )

    \Illuminate\Database\Eloquent\Builder::macro('toRawSql', function(){
        return ($this->getQuery()->toRawSql());
    });
  3. Kemudian debug seperti biasa. ( Laravel 5.4+ )

    Misalnya Pembuat Kueri

    \Log::debug(\DB::table('users')->limit(1)->toRawSql())

    Misalnya Eloquent Builder

    \Log::debug(\App\User::limit(1)->toRawSql());

Catatan: dari Laravel 5.1 hingga 5.3, Karena Eloquent Builder tidak menggunakan Macroableciri tersebut, tidak dapat menambahkan toRawSqlalias ke Eloquent Builder dengan cepat. Ikuti contoh di bawah ini untuk mencapai hal yang sama.

Misalnya Eloquent Builder ( Laravel 5.1 - 5.3 )

\Log::debug(\App\User::limit(1)->getQuery()->toRawSql());
Ijas Ameenudeen
sumber
Ups, saya datang terlambat. Hanya ingin mengirim jawaban menggunakan Makro. Ini jawaban terbaik. Seharusnya jawaban yang diterima: D
nmfzone
Anda dapat mengambil abstrak yang terakhir dalam lingkup di pangkalan Model
Ogier Schelvis
8

gunakan paket debugbar

composer require "barryvdh/laravel-debugbar": "2.3.*"

masukkan deskripsi gambar di sini

panqingqiang
sumber
7

Dari laravel 5.2dan seterusnya. Anda dapat menggunakan DB::listenuntuk mendapatkan kueri yang dieksekusi.

DB::listen(function ($query) {
    // $query->sql
    // $query->bindings
    // $query->time
});

Atau jika Anda ingin men-debug Builderinstance tunggal maka Anda dapat menggunakan toSqlmetode.

DB::table('posts')->toSql(); 
Zayn Ali
sumber
1
Hal mendengarkan bermanfaat, nyatakan sebelum menjalankan kueri, dan buang sql & binding dalam metode. Tidak sempurna tetapi bekerja lebih cepat / lebih mudah daripada jawaban lain.
Andrew
7

Cara paling mudah adalah dengan membuat kesalahan yang disengaja . Misalnya, saya ingin melihat kueri SQL lengkap dari relasi berikut:

 public function jobs()
        {
            return $this->belongsToMany(Job::class, 'eqtype_jobs')
                   ->withPivot(['created_at','updated_at','id'])
                   ->orderBy('pivot_created_at','desc');
        }

Saya hanya membuat kolom agar tidak ditemukan, di sini saya pilih created_at dan saya mengubahnya created_atsdengan menambahkan trailing smenjadi:

public function jobs()
            {
                return $this->belongsToMany(Job::class, 'eqtype_jobs')
                       ->withPivot(['created_ats','updated_at','id'])
                       ->orderBy('pivot_created_at','desc');
            }

Jadi, debuger akan mengembalikan kesalahan berikut:

(4/4) ErrorException SQLSTATE [42S22]: Kolom tidak ditemukan: 1054 diketahui kolom 'eqtype_jobs.created_ats' di 'daftar bidang' (SQL: pilih jobs*,. eqtype_jobs. set_idSebagai pivot_set_id, eqtype_jobs. job_idSeperti pivot_job_id, eqtype_jobs. created_ats Seperti pivot_created_ats, eqtype_jobs. updated_atSeperti pivot_updated_at, eqtype_jobs. idSeperti pivot_iddari jobsinner join eqtype_jobson jobs. id= eqtype_jobs. job_idwhere eqtype_jobs. set_id= 56 order dengan pivot_created_atdesc limit 20 offset 0) (Lihat: /home/said/www/factory/resources/views/set/show.blade.php)

Pesan kesalahan di atas mengembalikan permintaan SQL lengkap dengan kesalahan

SQL: select  jobs.*, eqtype_jobs.set_id as pivot_set_id,  eqtype_jobs.job_id as pivot_job_id, eqtype_jobs.created_ats as pivot_created_ats, eqtype_jobs.updated_at as  pivot_updated_at, eqtype_jobs.id as pivot_id from jobs inner join eqtype_jobs on jobs.id = eqtype_jobs.job_id where  eqtype_jobs.set_id = 56 order by pivot_created_at desc limit 20 offset 0

Sekarang, hapus saja ekstra sdari Created_at dan uji SQL ini sesuka Anda dalam editor SQL apa pun seperti editor SQL phpMyAdmin!

Memperhatikan:

Solusinya telah diuji dengan Laravel 5.4 .

SaidbakR
sumber
2
Ini adalah jawaban terbaik sejauh ini! Sangat sederhana! :)
Picard
Ini tidak akan menampilkan kueri dengan binding, yaitu binding akan tampil seperti:id
Shantha Kumara
@ ShanthaKumara Memang, saya tidak tahu apa versi atau konfigurasi Laravel yang telah Anda gunakan. Namun, setiap cuplikan atau kode dalam jawaban saya disalin dan disisipkan dari output kode nyata proyek Laravel 5.4.
SaidbakR
6

Untuk Melihat Laravel Query Eksekusi gunakan log kueri laravel

DB::enableQueryLog();

$queries = DB::getQueryLog();
Jasim Juwel
sumber
6

Pada Laravel 5.8.15 pembuat kueri sekarang memiliki dd dan dumpmetode sehingga Anda dapat melakukannya

DB::table('data')->where('a', 1)->dump();
Greg
sumber
Terima kasih. bekerja dengan sangat baik. DB :: table ('data') -> where ('a', 1) -> dd ();
Waqas
Lebih baik daripada jawaban lain yang tercantum.
Hamees A. Khan
5

Inilah fungsinya, saya ditempatkan di kelas model dasar saya. Cukup masukkan objek pembuat kueri ke dalamnya dan string SQL akan dikembalikan.

function getSQL($builder) {
  $sql = $builder->toSql();
  foreach ( $builder->getBindings() as $binding ) {
    $value = is_numeric($binding) ? $binding : "'".$binding."'";
    $sql = preg_replace('/\?/', $value, $sql, 1);
  }
  return $sql;
}
BoogieBug
sumber
4

Untuk laravel 5.5.X

Jika Anda ingin menerima setiap permintaan SQL yang dijalankan oleh aplikasi Anda, Anda dapat menggunakan metode mendengarkan. Metode ini berguna untuk mencatat kueri atau debugging. Anda dapat mendaftarkan pendengar kueri Anda di penyedia layanan:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        DB::listen(function ($query) {
            // $query->sql
            // $query->bindings
            // $query->time
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Sumber

scre_www
sumber
4

Tambahkan fungsi ini ke aplikasi Anda dan cukup panggil.

function getQuery($sql){
        $query = str_replace(array('?'), array('\'%s\''), $sql->toSql());
        $query = vsprintf($query, $sql->getBindings());     
        return $query;
}

Output : "pilih * dari usermana lang= 'en' dan status= '1' pesan dengan updated_atbatas desc 25 offset 0"

Dharmik
sumber
3

Anda dapat menggunakan paket ini untuk mendapatkan semua pertanyaan yang dieksekusi saat Anda memuat halaman Anda

https://github.com/barryvdh/laravel-debugbar
Lakhwinder Singh
sumber
Paket itu bagus ketika Anda tidak memiliki kesalahan kueri. Jika Anda memiliki kesalahan SQL, ia tidak akan menampilkan apa pun
lewis4u
3

Cetak kueri terakhir

DB::enableQueryLog();

$query        = DB::getQueryLog();
$lastQuery    = end($query);
print_r($lastQuery);
Sohomdeep Paul
sumber
2

Jika Anda tidak menggunakan Laravel tetapi menggunakan paket Eloquent maka:

use \Illuminate\Database\Capsule\Manager as Capsule;
use \Illuminate\Events\Dispatcher;
use \Illuminate\Container\Container;

$capsule = new Capsule;

$capsule->addConnection([
    // connection details
]);
// Set the event dispatcher used by Eloquent models... (optional)
$capsule->setEventDispatcher(new Dispatcher(new Container));

// Make this Capsule instance available globally via static methods... (optional)
$capsule->setAsGlobal();

// Setup the Eloquent ORM...(optional unless you've used setEventDispatcher())
$capsule->bootEloquent();

// Listen for Query Events for Debug
$events = new Dispatcher;
$events->listen('illuminate.query', function($query, $bindings, $time, $name)
{
    // Format binding data for sql insertion
    foreach ($bindings as $i => $binding) {
        if ($binding instanceof \DateTime) {
            $bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
        } else if (is_string($binding)) {
            $bindings[$i] = "'$binding'";`enter code here`
        }
    }

    // Insert bindings into query
    $query = str_replace(array('%', '?'), array('%%', '%s'), $query);
    $query = vsprintf($query, $bindings);

    // Debug SQL queries
    echo 'SQL: [' . $query . ']';
});

$capsule->setEventDispatcher($events);
Salman Ahmed
sumber
2

Anda bisa menggunakan jarum jam

Clockwork adalah ekstensi Chrome untuk pengembangan PHP, memperluas Alat Pengembang dengan panel baru yang menyediakan semua jenis informasi yang berguna untuk debugging dan profil aplikasi PHP Anda, termasuk informasi tentang permintaan, header, dapatkan dan kirim data, cookie, data sesi, kueri basis data, rute, visualisasi runtime aplikasi dan banyak lagi.

tetapi berfungsi juga di firefox

wdog
sumber
2

Saya telah membuat beberapa fungsi sederhana untuk mendapatkan SQL dan binding dari beberapa query.

/**
 * getSql
 *
 * Usage:
 * getSql( DB::table("users") )
 * 
 * Get the current SQL and bindings
 * 
 * @param  mixed  $query  Relation / Eloquent Builder / Query Builder
 * @return array          Array with sql and bindings or else false
 */
function getSql($query)
{
    if( $query instanceof Illuminate\Database\Eloquent\Relations\Relation )
    {
        $query = $query->getBaseQuery();
    }

    if( $query instanceof Illuminate\Database\Eloquent\Builder )
    {
        $query = $query->getQuery();
    }

    if( $query instanceof Illuminate\Database\Query\Builder )
    {
        return [ 'query' => $query->toSql(), 'bindings' => $query->getBindings() ];
    }

    return false;
}

/**
 * logQuery
 *
 * Get the SQL from a query in a closure
 *
 * Usage:
 * logQueries(function() {
 *     return User::first()->applications;
 * });
 * 
 * @param  closure $callback              function to call some queries in
 * @return Illuminate\Support\Collection  Collection of queries
 */
function logQueries(closure $callback) 
{
    // check if query logging is enabled
    $logging = DB::logging();

    // Get number of queries
    $numberOfQueries = count(DB::getQueryLog());

    // if logging not enabled, temporarily enable it
    if( !$logging ) DB::enableQueryLog();

    $query = $callback();

    $lastQuery = getSql($query);

    // Get querylog
    $queries = new Illuminate\Support\Collection( DB::getQueryLog() );

    // calculate the number of queries done in callback
    $queryCount = $queries->count() - $numberOfQueries;

    // Get last queries
    $lastQueries = $queries->take(-$queryCount);

    // disable query logging
    if( !$logging ) DB::disableQueryLog();

    // if callback returns a builder object, return the sql and bindings of it
    if( $lastQuery )
    {
        $lastQueries->push($lastQuery);
    }

    return $lastQueries;
}

Pemakaian:

getSql( DB::table('users') );
// returns 
// [
//     "sql" => "select * from `users`",
//     "bindings" => [],
// ]

getSql( $project->rooms() );
// returns
// [
//     "sql" => "select * from `rooms` where `rooms`.`project_id` = ? and `rooms`.`project_id` is not null",
//     "bindings" => [ 7 ],
// ]
blablabla
sumber
2

Seperti halnya saya menyukai kerangka ini, saya benci kalau itu bertindak seperti omong kosong.

DB::enableQueryLog()sama sekali tidak berguna. DB::listensama-sama tidak berguna. Itu menunjukkan bagian dari permintaan ketika saya berkata $query->count(), tetapi jika saya lakukan$query->get() , tidak ada yang bisa dikatakan.

Satu-satunya solusi yang tampaknya bekerja secara konsisten adalah dengan sengaja menempatkan beberapa sintaks atau kesalahan lain dalam parameter ORM, seperti nama kolom / tabel yang tidak ada, jalankan kode Anda pada baris perintah saat dalam mode debug, dan itu akan memuntahkan kesalahan SQL dengan permintaan penuh akhirnya. Kalau tidak, mudah-mudahan kesalahan muncul di file log jika dijalankan dari server web.

Spencer Williams
sumber
Log kueri setidaknya berfungsi dengan baik untuk saya. Anda seharusnya memiliki beberapa kesalahan lain dalam aplikasi Anda
user1415066
1

Jika Anda menggunakan tinker dan ingin mencatat permintaan SQL yang terbentuk, Anda bisa melakukannya

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.5  cli) by Justin Hileman
>>> DB::listen(function ($query) { dump($query->sql); dump($query->bindings); dump($query->time); });
=> null
>>> App\User::find(1)
"select * from `users` where `users`.`id` = ? limit 1"
array:1 [
  0 => 1
]
6.99
=> App\User {#3131
     id: 1,
     name: "admin",
     email: "[email protected]",
     created_at: "2019-01-11 19:06:23",
     updated_at: "2019-01-11 19:06:23",
   }
>>>
Prafulla Kumar Sahu
sumber
1

Coba ini:

$results = DB::table('users')->toSql();
dd($results);

Catatan: get () telah diganti dengan toSql () untuk menampilkan kueri SQL mentah.

Nikhil Gyan
sumber
1

Cara saya melakukan ini, berdasarkan tampilan log, hanya perlu memodifikasi file app/Providers/AppServiceProvider.php:

  1. Tambahkan kode ini ke dalam app/Providers/AppServiceProvider.php
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    //
    DB::listen(function ($query) {
        $querySql = str_replace(['?'], ['\'%s\''], $query->sql);
        $queryRawSql = vsprintf($querySql, $query->bindings);
        Log::debug('[SQL EXEC]', [
                "raw sql"  => $queryRawSql,
                "time" => $query->time,
            ]
        );
    });
}
  1. Kode pegangan sql saya:
$users = DB::table('users')
    ->select(DB::raw('count(*) as user_count, username '))
    ->where('uid', '>=', 10)
    ->limit(100)
    ->groupBy('username')
    ->get()
;
dd($users);
  1. Lihat log storage/logs/laravel-2019-10-27.log:
[2019-10-27 17:39:17] local.DEBUG: [SQL EXEC] {"raw sql":"select count(*) as user_count, username  from `users` where `uid` >= '10' group by `username` limit 100","time":304.21} 
lupguo
sumber