php - 如何在Laravel 5中执行查询? DB :: getQueryLog返回空数组
我正在尝试查看查询的日志,但DB::getQueryLog()只是返回一个空数组:
$user = User::find(5);
print_r(DB::getQueryLog());
结果:
Array
(
)
如何查看此查询的日志?
9个解决方案
209 votes
默认情况下,Laravel 5中禁用查询日志:[https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448]
您需要通过调用以下命令启用查询日志:
DB::enableQueryLog();
或注册事件监听器:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
一些技巧
1.多个DB连接
如果您有多个数据库连接,则必须指定要记录的连接
要启用bootstrap/app.php的查询日志:
DB::connection('my_connection')->enableQueryLog();
要获取bootstrap/app.php的查询日志:
print_r(
DB::connection('my_connection')->getQueryLog()
);
2.在哪里启用查询日志?
对于HTTP请求生命周期,您可以在某些BeforeAnyDbQueryMiddleware中间件的bootstrap/app.php方法中启用查询日志,然后在相同中间件的bootstrap/app.php方法中检索已执行的查询。
class BeforeAnyDbQueryMiddleware
{
public function handle($request, Closure $next)
{
DB::enableQueryLog();
return $next($request);
}
public function terminate($request, $response)
{
// Store or dump the log data...
dd(
DB::getQueryLog()
);
}
}
中间件的链不会针对工匠命令运行,因此对于CLI执行,您可以在bootstrap/app.php事件侦听器中启用查询日志。
例如,您可以将其放在bootstrap/app.php文件中
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
记忆
Laravel将所有查询保存在内存中。 因此,在某些情况下,例如插入大量行或具有大量查询的长时间运行作业时,这可能会导致应用程序使用过多的内存。
在大多数情况下,您只需要查询日志进行调试,如果是这种情况,我建议您仅为开发启用它。
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
参考
[https://laravel.com/docs/5.0/database#query-logging]
Marty Aghajanyan answered 2019-05-21T08:28:43Z
31 votes
如果您真正关心的是实际查询(最后一次运行)以进行快速调试:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; #
# optionally disable the query log:
DB::disableQueryLog();
在$laQuery[0]上执行print_r()以获取完整查询,包括绑定。 (上面的DB::connection("mysql2")->getQueryLog();变量将变量替换为??)
如果你使用的不是主mysql连接,你需要使用它们:
DB::connection("mysql2")->getQueryLog();
DB::connection("mysql2")->getQueryLog();
(你的连接名称是“mysql2”)
Skeets answered 2019-05-21T08:29:40Z
10 votes
显然,对于Laravel 5.2,DB::listen中的闭包只接收一个参数。
因此,如果您想在Laravel 5.2中使用DB::listen,您应该执行以下操作:
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+'
);
fwrite($logFile, date('Y-m-d H:i:s') . ': ' . $query . PHP_EOL);
fclose($logFile);
}
);
Luís Cruz answered 2019-05-21T08:30:14Z
9 votes
把它放在routes.php文件中:
\Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) {
echo'
';
var_dump($query->sql);
var_dump($query->bindings);
var_dump($query->time);
echo'
';});
由msurguy提交,此页面中的源代码。 您将在评论中找到laravel 5.2的此修订代码。
Rubén Ruíz answered 2019-05-21T08:30:47Z
8 votes
您需要先启用查询日志记录
DB::enableQueryLog();
如果在应用程序启动之前启用查询日志记录会更好,您可以在BeforeMiddleware中执行,然后在AfterMiddleware中检索已执行的查询。
Vineet Garg answered 2019-05-21T08:31:26Z
2 votes
(Laravel 5.2)我发现最简单的方法就是添加一个代码行来监视sql查询:\DB::listen(function($sql) {var_dump($sql); });
ChrisH answered 2019-05-21T08:31:52Z
1 votes
此代码适用于:
Laravel 5.2
将语句记录到mysql数据库中
这是代码,它基于@milz的答案:
DB::listen(function($sql) {
$LOG_TABLE_NAME = 'log';
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);
if(stripos($query, 'insert into `'.$LOG_TABLE_NAME.'`')===false){
$toLog = new LogModel();
$toLog->uId = 100;
$toLog->sql = $query;
$toLog->save();
}
});
核心是if(stripos...行,它阻止了将insert into log sql语句插入数据库的递归。
fzyzcjy answered 2019-05-21T08:32:45Z
0 votes
在继续使用Laravel 5.2时,DB :: listen中的闭包仅接收一个参数...上面的响应:您可以将此代码放入Middleware脚本并在路由中使用它。
另外:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('sql');
$log->pushHandler(new StreamHandler(storage_path().'/logs/sql-' . date('Y-m-d') . '.log', Logger::INFO));
// add records to the log
$log->addInfo($query, $data);
Saint Father answered 2019-05-21T08:33:14Z
-3 votes
对于laravel 5及以后仅使用DB :: getQueryLog(),不会这样做。默认情况下,此值为
protected $loggingQueries = false;
改为
protected $loggingQueries = true;
在下面的文件中用于记录查询。/vendor/laravel/framework/src/illuminate/Database/Connection.php然后我们可以使用DB :: getQueryLog()来打印查询。
Rupali Pemare answered 2019-05-21T08:33:49Z