How can i get mysql
query of a laravel
query
Convert:
App\\User::where(\'balance\',\'>\',0)->where(...)-
In Laravel 5.4 (I didn't check this in other versions), add this function into the "App"=>"Providers"=>"AppServiceProvider.php" .
public function boot()
{
if (App::isLocal()) {
DB::listen(
function ($sql) {
// $sql is an object with the properties:
// sql: The query
// bindings: the sql query variables
// time: The execution time for the query
// connectionName: The name of the connection
// To save the executed queries to file:
// Process the sql and the bindings:
foreach ($sql->bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
} else {
if (is_string($binding)) {
$sql->bindings[$i] = "'$binding'";
}
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
$query = vsprintf($query, $sql->bindings);
// Save the query to file
/*$logFile = fopen(
storage_path('logs' . DIRECTORY_SEPARATOR . date('Y-m-d') . '_query.log'),
'a+'
);*/
Log::notice("[USER] $query");
}
);
}
}
After that install, https://github.com/ARCANEDEV/LogViewer and then you can see every executed SQL queries without editing the code.
Here is a helper function who tells you the last SQL executed.
use DB;
public static function getLastSQL()
{
$queries = DB::getQueryLog();
$last_query = end($queries);
// last_query is the SQL with with data binding like
// {
// select ? from sometable where field = ? and field2 = ? ;
// param1,
// param2,
// param3,
// }
// which is hard to read.
$last_query = bindDataToQuery($last_query);
// here, last_query is the last SQL you have executed as normal SQL
// select param1 from sometable where field=param2 and field2 = param3;
return $last_query
}
Here is the bindDataToQuery function, who fill the '?' blanks with real params.
protected static function bindDataToQuery($queryItem){
$query = $queryItem['query'];
$bindings = $queryItem['bindings'];
$arr = explode('?',$query);
$res = '';
foreach($arr as $idx => $ele){
if($idx < count($arr) - 1){
$res = $res.$ele."'".$bindings[$idx]."'";
}
}
$res = $res.$arr[count($arr) -1];
return $res;
}
To print the raw sql query, try:
DB::enableQueryLog();
// Your query here
$queries = DB::getQueryLog();
print_r($queries);
Reference
use toSql()
method of laravel to get the query to be executed like
App\User::where('balance','>',0)->where(...)->toSql();
But Laravel will not show you parameters in your query, because they are bound after preparation of the query. To get the bind parameters, use this
$query=App\User::where('balance','>',0)->where(...);
print_r($query->getBindings() );
enable the query log as DB::enableQueryLog()
and then output to the screen the last queries ran you can use this,
dd(DB::getQueryLog());
It is so strange that the laravel haven't support any way to get the raw sql easily, it is now version 6 after all...
Here's a workaround I used by myself to quickly get the raw sql with parameters without installing any extension...
Just deliberately make your original sql WRONG
Like change
DB::table('user')
to
DB::table('user1')
where the table "user1" does not exist at all!
Then run it again.
Sure there will be an exception reported by laravel.
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'user1' doesn't exist (SQL: ...)
And now you can see the raw sql with parameters is right after the string "(SQL:"
Change back from the wrong table name to the right one and there you go!
Instead of interfering with the application with print statements or "dd
s", I do the following when I want to see the generated SQL:
DB::listen(function ($query) {
Log::info($query->sql, $query->bindings);
});
// (DB and Log are the facades in Illuminate\Support\Facades namespace)
This will output the sql to the Laravel log (located at storage/logs/laravel.log
). A useful command for following writes to this file is
tail -n0 -f storage/logs/laravel.log