web-dev-qa-db-ja.com

でクエリを実行する方法 Laravel 5?空の配列を返すDB :: getQueryLog()

クエリのログを表示しようとしていますが、DB::getQueryLog()は単に空の配列を返しています。

$user = User::find(5);
print_r(DB::getQueryLog());

結果

Array
(
)

このクエリのログを表示する方法

150
Arsen

デフォルトでは、クエリログは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接続

複数のDB接続がある場合は、どの接続をログに記録するかを指定する必要があります。

my_connectionのクエリログを有効にするには

DB::connection('my_connection')->enableQueryLog();

my_connectionのクエリログを取得するには、次の手順を実行します。

print_r(
   DB::connection('my_connection')->getQueryLog()
);

2.クエリログを有効にする場所

HTTPリクエストライフサイクルでは、いくつかのhandlemiddlewareBeforeAnyDbQueryMiddlewareメソッドでクエリログを有効にしてから、同じミドルウェアの 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()
        );
    }
}

ミドルウェアのチェーンは職人のコマンドでは実行されないので、CLIの実行ではartisan.startイベントリスナーでクエリログを有効にできます。

例えばbootstrap/app.phpファイルに入れることができます

$app['events']->listen('artisan.start', function(){
    \DB::enableQueryLog();
});

3.メモリ

Laravelはすべてのクエリをメモリに保存します。そのため、多数の行を挿入したり、多数の照会を伴う長時間実行ジョブがある場合など、場合によっては、アプリケーションが余分なメモリーを使用することがあります。

ほとんどの場合、あなたはデバッグのためだけにクエリログを必要とするでしょう、そしてそれがそうであるならば私は開発のためだけにそれを有効にすることをお勧めします。

if (App::environment('local')) {
    // The environment is local
    DB::enableQueryLog();
}

参考文献

229

あなたが本当に気にしているのが迅速なデバッグ目的のための実際の問い合わせ(最後の1つの実行)だけであるならば:

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()を実行します。 (上記の$lcWhatYouWant変数は、変数が??に置き換えられます)

メインのmysql接続以外のものを使用している場合は、代わりにこれらを使用する必要があります。

DB::connection("mysql2")->enableQueryLog();

DB::connection("mysql2")->getQueryLog();

( "mysql2"がある接続名で)

36
Skeets

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);
    }
);
10
Luís Cruz

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のためのこの修正コードを見つけるでしょう。

10
Rubén Ruíz

最初にクエリロギングを有効にする必要があります

DB::enableQueryLog();

アプリケーションの起動前にクエリロギングを有効にしておくと、BeforeMiddlewareで実行でき、実行されたクエリをAfterMiddlewareで取得できます。

9
Vineet Garg

にとって ララベル5.8 あなたは追加するだけです dd または ダンプ

例:

DB::table('users')->where('votes', '>', 100)->dd();

または

DB::table('users')->where('votes', '>', 100)->dump();

参照: https://laravel.com/docs/5.8/queries#debugging

2
larp

(Laravel 5.2)最も簡単な方法は、SQLクエリを監視するためのコード行を1行追加することです。\DB::listen(function($sql) {var_dump($sql); });

2
ChrisH

以下のようにtoSql()ではなくget()を使用してください。

$users = User::orderBy('name', 'asc')->toSql();
echo $users;
\\ Outputs the string:
'select * from `users` order by `name` asc'
1
doncadavona

このコードは、

  • 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ステートメントをデータベースに挿入する再帰を防ぎます。

1
fzyzcjy

の続きでは、明らかにLaravel 5.2で、DB :: listenのクロージャーは単一のパラメーターを受け取るだけです... response:あなたはこのコードをミドルウェアスクリプトに入れて使うことができます。ルートでそれを。

さらに:

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);
0
Saint Father