回答:
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
}
);
複数のDB接続がある場合、ログに記録する接続を指定する必要があります
のクエリログを有効にするにはmy_connection
:
DB::connection('my_connection')->enableQueryLog();
のクエリログを取得するにはmy_connection
:
print_r(
DB::connection('my_connection')->getQueryLog()
);
HTTPリクエストのライフサイクルでhandle
は、一部のBeforeAnyDbQueryMiddleware
ミドルウェアのメソッドでクエリログを有効にしてterminate
から、同じミドルウェアのメソッドで実行されたクエリを取得できます。
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()
);
}
}
ミドルウェアのチェーンは、artisanコマンドでは実行されないため、CLIの実行では、artisan.start
イベントリスナーでクエリログを有効にできます。
たとえば、bootstrap/app.php
ファイルに入れることができます
$app['events']->listen('artisan.start', function(){
\DB::enableQueryLog();
});
Laravelはすべてのクエリをメモリに保持します。そのため、多数の行を挿入する場合や、多数のクエリを使用して長時間実行ジョブを実行する場合など、場合によっては、アプリケーションが過剰なメモリを使用する可能性があります。
ほとんどの場合、クエリログはデバッグにのみ必要です。その場合は、開発にのみ有効にすることをお勧めします。
if (App::environment('local')) {
// The environment is local
DB::enableQueryLog();
}
参考文献
\DB::connection('myconnection')->enableQueryLog(); print_r(\DB::connection('myconnection')->getQueryLog());
DB::listen
コールバック関数の署名が異なります。これは次のようになります DB::listen(function($query) { $sql = $query->sql; $bindings = $query->bindings; $time = $query->time; ... });
あなたが本当に気にするのは、迅速なデバッグのための実際のクエリ(最後の実行)だけです:
DB::enableQueryLog();
# your laravel query builder goes here
$laQuery = DB::getQueryLog();
$lcWhatYouWant = $laQuery[0]['query']; # <-------
# optionally disable the query log:
DB::disableQueryLog();
行うprint_r()
上での$laQuery[0]
バインディングを含む、完全なクエリを取得します。(上の$lcWhatYouWant
変数は、変数がに置き換えられます??
)
メインのmysql接続以外のものを使用している場合は、代わりにこれらを使用する必要があります。
DB::connection("mysql2")->enableQueryLog();
DB::connection("mysql2")->getQueryLog();
(「mysql2」が接続名にある場合)
これをroutes.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>';
});
msurguyによって送信された、このページのソースコード。コメントには、laravel 5.2のこの修正コードが記載されています。
最初にクエリログを有効にする必要があります
DB::enableQueryLog();
次に、単純にクエリログを取得できます。
dd(DB::getQueryLog());
アプリケーションを開始する前にクエリログを有効にすると、BeforeMiddlewareで実行でき、実行したクエリをAfterMiddlewareで取得できます。
どうやらLaravel 5.2では、クロージャーはDB::listen
単一のパラメーターのみを受け取ります。
したがって、DB::listen
Laravel 5.2で使用する場合は、次のようにする必要があります。
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);
}
);
laravel 5.8あなただけの追加DDまたはダンプを。
例:
DB::table('users')->where('votes', '>', 100)->dd();
または
DB::table('users')->where('votes', '>', 100)->dump();
どうやらLaravel 5.2で続行すると、DB :: listenのクロージャーは単一のパラメーターのみを受け取ります...上記の応答:このコードをミドルウェアスクリプトに入れ、ルートで使用できます。
さらに:
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);
このコードは:
@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();
}
});
コアは、SQLステートメントをデータベースif(stripos...
に挿入する再帰を防ぐ行insert into log
です。
私はこの記事にある答えを考えています:https : //arjunphp.com/laravel-5-5-log-eloquent-queries/
クエリロギングを実現するのは高速で簡単です。
メソッドにコールバックを追加してAppServiceProvider
、boot
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));
});
}
}
laravel 5以降では、DB :: getQueryLog()のみを使用すると、機能しません。これによりデフォルトでの値
protected $loggingQueries = false;
に変更
protected $loggingQueries = true;
クエリを記録するために以下のファイルにあります。
/vendor/laravel/framework/src/illuminate/Database/Connection.php
そしてDB::getQueryLog()
、クエリを印刷する場所を使用できます。
vendor
ファイルを編集するのは悪い考えです。彼らはオリジナルのままにしておく必要があります。