Tôi đang cố gắng xem nhật ký cho một truy vấn, nhưng DB::getQueryLog()
chỉ trả về một mảng trống:
$user = User::find(5);
print_r(DB::getQueryLog());
Kết quả
Array
(
)
Làm thế nào tôi có thể xem nhật ký cho truy vấn này?
Tôi đang cố gắng xem nhật ký cho một truy vấn, nhưng DB::getQueryLog()
chỉ trả về một mảng trống:
$user = User::find(5);
print_r(DB::getQueryLog());
Kết quả
Array
(
)
Làm thế nào tôi có thể xem nhật ký cho truy vấn này?
Câu trả lời:
Theo mặc định, nhật ký truy vấn bị vô hiệu hóa trong Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448
Bạn sẽ cần phải kích hoạt nhật ký truy vấn bằng cách gọi:
DB::enableQueryLog();
hoặc đăng ký một người nghe sự kiện:
DB::listen(
function ($sql, $bindings, $time) {
// $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
// $bindings - [5]
// $time(in milliseconds) - 0.38
}
);
Nếu bạn có nhiều kết nối DB, bạn phải chỉ định kết nối nào sẽ đăng nhập
Để bật nhật ký truy vấn cho my_connection
:
DB::connection('my_connection')->enableQueryLog();
Để có được nhật ký truy vấn cho my_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
Đối với vòng đời yêu cầu HTTP, bạn có thể kích hoạt nhật ký truy vấn theo handle
phương thức của một số BeforeAnyDbQueryMiddleware
phần mềm trung gian và sau đó truy xuất các truy vấn đã thực hiện trong terminate
phương thức của cùng một phần mềm trung gian.
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()
);
}
}
Chuỗi của phần mềm trung gian sẽ không chạy cho các lệnh thủ công, vì vậy để thực thi CLI, bạn có thể bật nhật ký truy vấn trong trình artisan.start
nghe sự kiện.
Ví dụ, bạn có thể đặt nó trong bootstrap/app.php
tập tin
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
Laravel giữ tất cả các truy vấn trong bộ nhớ. Vì vậy, trong một số trường hợp, chẳng hạn như khi chèn một số lượng lớn hàng hoặc có một công việc chạy dài với nhiều truy vấn, điều này có thể khiến ứng dụng sử dụng bộ nhớ dư thừa.
Trong hầu hết các trường hợp, bạn sẽ chỉ cần nhật ký truy vấn để gỡ lỗi và nếu đó là trường hợp tôi khuyên bạn chỉ nên kích hoạt nó để phát triển.
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
Người giới thiệu
\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
chức năng gọi lại có chữ ký khác. Nó giống như thế này: DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
Nếu tất cả những gì bạn thực sự quan tâm là truy vấn thực tế (lần chạy cuối cùng) cho mục đích gỡ lỗi nhanh:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
làm một print_r()
trên $laQuery[0]
để có được những truy vấn đầy đủ, bao gồm các ràng buộc. ( $lcWhatYouWant
biến ở trên sẽ có các biến được thay thế bằng ??
)
Nếu bạn đang sử dụng một cái gì đó không phải là kết nối mysql chính, bạn sẽ cần sử dụng những thứ này thay thế:
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(với tên kết nối của bạn là "mysql2")
Đặt cái này vào tập tin records.php:
\Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) {
echo'<pre>';
var_dump($query->sql);
var_dump($query->bindings);
var_dump($query->time);
echo'</pre>';
});
Gửi bởi msurguy, mã nguồn trong trang này . Bạn sẽ tìm thấy mã sửa lỗi này cho laravel 5.2 trong các bình luận.
Trước tiên bạn cần bật ghi nhật ký truy vấn
DB::enableQueryLog();
Sau đó, bạn có thể nhận được các bản ghi truy vấn bằng cách đơn giản:
dd(DB::getQueryLog());
Sẽ tốt hơn nếu bạn kích hoạt ghi nhật ký truy vấn trước khi ứng dụng bắt đầu, điều bạn có thể làm trong BeforeMiddleware và sau đó truy xuất các truy vấn đã thực hiện trong AfterMiddleware.
Rõ ràng với Laravel 5.2, việc đóng DB::listen
chỉ nhận được một tham số duy nhất.
Vì vậy, nếu bạn muốn sử dụng DB::listen
trong Laravel 5.2, bạn nên làm một cái gì đó như:
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);
}
);
Đối với laravel 5,8 bạn chỉ cần thêm dd hoặc dump .
Ví dụ:
DB::table('users')->where('votes', '>', 100)->dd();
hoặc là
DB::table('users')->where('votes', '>', 100)->dump();
Sử dụng toSql()
thay vì get()
như vậy:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'
Tiếp tục với Rõ ràng với Laravel 5.2, việc đóng trong DB :: nghe chỉ nhận được một tham số duy nhất ... phản hồi ở trên: bạn có thể đặt mã này vào tập lệnh Middleware và sử dụng nó trong các tuyến.
Ngoài ra:
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);
Mã này là dành cho:
Đây là đoạn mã dựa trên câu trả lời của @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();
}
});
Cốt lõi là if(stripos...
dòng, ngăn chặn sự đệ quy của việc chèn insert into log
câu lệnh sql vào cơ sở dữ liệu.
Tôi nghĩ rằng câu trả lời nằm trong bài viết này: https://arjunphp.com/laravel-5-5-log-eloquent-queries/
là nhanh chóng và đơn giản để đạt được đăng nhập truy vấn.
Bạn chỉ cần thêm AppServiceProvider
vào boot
phương thức một cuộc gọi lại để nghe các truy vấn DB:
namespace App\Providers;
use DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
DB::listen(function($query) {
logger()->info($query->sql . print_r($query->bindings, true));
});
}
}
Giả sử bạn muốn in truy vấn SQL của các câu lệnh sau.
$user = User::find(5);
Bạn chỉ cần làm như sau:
DB::enableQueryLog();//enable query logging
$user = User::find(5);
print_r(DB::getQueryLog());//print sql query
Điều này sẽ in truy vấn được thực hiện cuối cùng trong Laravel.
Đối với laravel 5 trở đi chỉ sử dụng DB :: getQueryLog (), sẽ không làm được. Theo mặc định trong giá trị này của
protected $loggingQueries = false;
thay đổi nó thành
protected $loggingQueries = true;
trong tập tin dưới đây để đăng nhập truy vấn.
/vendor/laravel/framework/src/illuminate/Database/Connection.php
Và sau đó chúng ta có thể sử dụng DB::getQueryLog()
nơi bạn muốn in truy vấn.
vendor
các tập tin. Chúng phải được giữ nguyên bản.