web-dev-qa-db-fra.com

Comment obtenir la requête exécutée dans Laravel 5? DB :: getQueryLog () Renvoyer un tableau vide

J'essaie d'afficher le journal d'une requête, mais DB::getQueryLog() renvoie simplement un tableau vide:

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

Résultat

Array
(
)

Comment afficher le journal de cette requête?

143
Arsen

Par défaut, le journal de requête est désactivé dans Laravel 5: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448

Vous devrez activer le journal des requêtes en appelant:

DB::enableQueryLog();

ou enregistrer un auditeur d'événement:

DB::listen(
    function ($sql, $bindings, $time) {
        //  $sql - select * from `ncv_users` where `ncv_users`.`id` = ? limit 1
        //  $bindings - [5]
        //  $time(in milliseconds) - 0.38 
    }
);  

Quelques conseils

1. Plusieurs connexions à la base de données

Si vous avez plusieurs connexions à la base de données, vous devez spécifier la connexion à enregistrer.

Pour activer le journal de requête pour my_connection:

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

Pour obtenir le journal de requête pour my_connection:

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

2. Où activer le journal de requête?

Pour un cycle de vie de requête HTTP, vous pouvez activer le journal des requêtes dans la méthode handle de certains BeforeAnyDbQueryMiddlewaremiddleware , puis récupérer les requêtes exécutées dans la méthode terminate du même middleware.

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()
        );
    }
}

La chaîne d'un middleware ne s'exécutera pas pour les commandes artisanales. Par conséquent, pour l'exécution de la CLI, vous pouvez activer le journal des requêtes dans l'écouteur d'événements artisan.start.

Par exemple, vous pouvez le mettre dans le fichier bootstrap/app.php

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

3. mémoire

Laravel garde toutes les requêtes en mémoire. Ainsi, dans certains cas, par exemple lors de l'insertion d'un grand nombre de lignes ou d'un travail long avec beaucoup de requêtes, l'application peut utiliser trop de mémoire. 

Dans la plupart des cas, vous aurez besoin du journal de requête uniquement pour le débogage. Si tel est le cas, je vous recommanderais de l'activer uniquement pour le développement.

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

Références

214
Marty Aghajanyan

Apparemment avec Laravel 5.2, la fermeture dans DB::listen ne reçoit qu'un seul paramètre.

Donc, si vous voulez utiliser DB::listen dans Laravel 5.2, vous devriez faire quelque chose comme:

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

Mettez ceci sur le fichier 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>';
});

Soumis par msurguy, code source dans cette page . Vous trouverez ce code de correction pour laravel 5.2 dans les commentaires.

9
Rubén Ruíz

Pour laravel 5.8 vous venez d'ajouter jj ou déverser.

Ex:

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

ou

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

référence: https://laravel.com/docs/5.8/queries#debugging

2
larp

(Laravel 5.2) Le moyen le plus simple consiste à ajouter une ligne de code pour surveiller les requêtes SQL: \DB::listen(function($sql) {var_dump($sql); });

2
ChrisH

Ce code est pour:

  • Laravel 5.2
  • Connectez les déclarations dans la base de données mysql

Voici le code, basé sur la réponse de @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();
        }
    });

Le noyau est la ligne if(stripos..., ce qui empêche la récursivité d'insérer l'instruction insert into log sql dans la base de données.

1
fzyzcjy

En continuant le Apparemment avec Laravel 5.2, la fermeture dans DB :: listen ne reçoit qu'un seul paramètre ... réponse ci-dessus: vous pouvez mettre ce code dans le script Middleware et l'utiliser dans les routes.

Aditionellement:

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

Utilisez toSql() au lieu de get() comme suit:

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