如何让查询生成器将其原始SQL查询作为string输出?
给出以下代码:
DB::table('users')->get();
我想获得上面的查询生成器将生成的原始SQL查询string,因此在这个示例中,它将是SELECT * FROM users
。
我如何做到这一点?
要输出到屏幕最后的查询运行你可以使用这个
dd(DB::getQueryLog());
我相信最近的查询将在数组的底部。
你会有这样的事情:
array(1) { [0]=> array(3) { ["query"]=> string(21) "select * from "users"" ["bindings"]=> array(0) { } ["time"]=> string(4) "0.92" } }
按照Joshua的评论,现在默认closures。 要使用,您需要使用以下命令手动启用它:
DB::enableQueryLog();
在QueryBuilder
实例上使用toSql()
方法。
DB::table('users')->toSql()
将返回:
从`用户'select*
这比连接一个事件监听器更容易,而且还可以让你在构build它的时候检查查询的实际外观。
你可以听“illuminate.query”事件。 在查询之前添加以下事件侦听器:
Event::listen('illuminate.query', function($query, $params, $time, $conn) { dd(array($query, $params, $time, $conn)); }); DB::table('users')->get();
这将打印出如下所示的内容:
array(4) { [0]=> string(21) "select * from "users"" [1]=> array(0) { } [2]=> string(4) "0.94" [3]=> string(6) "sqlite" }
如果你正在尝试使用没有使用Laravel的Illuminate来使用Log:
\Illuminate\Database\Capsule\Manager::getQueryLog();
你也可以像下面这样快速启动一个函数:
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; }
编辑
更新后的版本似乎默认禁用了查询日志(上面返回一个空数组)。 要重新开始,在初始化Capsule Manager时,抓取连接的一个实例并调用enableQueryLog
方法
$capsule::connection()->enableQueryLog();
再次编辑
考虑到实际问题,您可以实际执行以下操作来转换当前的单个查询而不是以前的所有查询:
$sql = $query->toSql(); $bindings = $query->getBindings();
在获取查询string方面有一个很好的方法。
toSql()
在我们的情况下,
DB::table('users')->toSql();
返回
select * from users
是确切的解决scheme,返回SQL查询string..希望这有帮助…
如果你使用laravel 5.1和MySQL,你可以使用我所做的这个function:
/* * 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; }
作为input参数,您可以使用其中之一
照亮\数据库\雄辩\生成器
照亮\数据库\雄辩\关系\的hasMany
照亮\数据库\查询\生成器
DB::QueryLog()
仅在执行查询$builder->get()
后才起作用。 如果您愿意在执行查询之前获取查询,则可以使用$builder->toSql()
方法。 这是如何获得SQL并绑定它的例子:
$query = str_replace(array('?'), array('\'%s\''), $builder->toSql()); $query = vsprintf($query, $builder->getBindings()); dump($query); $result = $builder->get();
第一种方法:
简单地说,你可以使用toSql()
方法做以下的事情,
$query = DB::table('users')->get(); echo $query->toSql();
如果它不工作,你可以从laravel文档中设置 。
第二种方式:
另一种方法是
DB::getQueryLog()
但如果它是返回一个空数组,那么默认情况下禁用访问这个 ,
只需启用DB::enableQueryLog()
,它将工作:)
欲了解更多信息,请访问Github 问题了解更多。
希望它有助于:)
$data = User::toSql(); echo $data; //this will retrun select * from users. //here User is model
这是我放在我的基础模型类中的函数。 只需将查询生成器对象传递给它,SQLstring就会返回。
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; }
如果你不使用Laravel,但使用Eloquent包,那么:
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('\'Ymd 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);
你可以使用发条
Clockwork是PHP开发的Chrome扩展,扩展了开发工具,提供了一个新的面板,提供各种有用的debugging和分析PHP应用程序的信息,包括请求,标题,获取和发布数据,cookies,会话数据,数据库查询,路线,应用程序运行时间的可视化等等。
但也适用于Firefox
你可以使用这个包来获得加载页面时正在执行的所有查询
https://github.com/barryvdh/laravel-debugbar
我创build了一些简单的函数来从一些查询中获取SQL和绑定。
/** * 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; }
用法:
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 ], // ]
这是我使用的解决scheme:
DB::listen(function ($sql, $bindings, $time) { $bound = preg_replace_callback("/\?/", function($matches) use ($bindings) { static $localBindings; if (!isset($localBindings)) { $localBindings = $bindings; } $val = array_shift($localBindings); switch (gettype($val)) { case "boolean": $val = ($val === TRUE) ? 1 : 0; // mysql doesn't support BOOL data types, ints are widely used // $val = ($val === TRUE) ? "'t'" : "'f'"; // todo: use this line instead of the above for postgres and others break; case "NULL": $val = "NULL"; break; case "string": case "object": $val = "'". addslashes($val). "'"; // correct escaping would depend on the RDBMS break; } return $val; }, $sql); array_map(function($x) { (new \Illuminate\Support\Debug\Dumper)->dump($x); }, [$sql, $bindings, $bound]); });
请阅读代码中的注释。 我知道,这不是完美的,但对于我的日常debugging是可以的。 它试图build立具有或多或less可靠性的绑定查询。 但是,不要完全信任它,数据库引擎会以不同的方式转义这个简短的函数不能实现的值。 所以,仔细看看结果。
composer php需要“barryvdh / laravel-debugbar”:“2.3。*”
你会看到的
从laravel 5.2
开始。 你可以使用DB::listen
来获得执行的查询。
DB::listen(function ($query) { // $query->sql // $query->bindings // $query->time });
或者如果你想debugging一个Builder
实例,那么你可以使用toSql
方法。
DB::table('posts')->toSql();
对于laravel 5.5.X
如果您想要接收由您的应用程序执行的每个SQL查询,您可以使用listen方法。 此方法对logging查询或debugging很有用。 您可以在服务提供者中注册您的查询侦听器:
<?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() { // } }
资源