it-swarm.com.de

Wie kann ich die Abfrage in Laravel 5 ausführen lassen? DB :: getQueryLog () Leeres Array zurückgeben

Ich versuche, das Protokoll für eine Abfrage anzuzeigen, aber DB::getQueryLog() gibt nur ein leeres Array zurück:

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

Ergebnis

Array
(
)

Wie kann ich das Protokoll für diese Abfrage anzeigen?

143
Arsen

Standardmäßig ist das Abfrageprotokoll in Laravel 5 deaktiviert: https://github.com/laravel/framework/commit/e0abfe5c49d225567cb4dfd56df9ef05cc297448

Sie müssen das Abfrageprotokoll aktivieren, indem Sie Folgendes aufrufen:

DB::enableQueryLog();

oder registriere einen Event Listener:

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

Einige Hinweise

1. Mehrere DB-Verbindungen

Wenn Sie mehr als eine DB-Verbindung haben, müssen Sie angeben, welche Verbindung protokolliert werden soll

So aktivieren Sie das Abfrageprotokoll für my_connection:

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

Abfrageprotokoll für my_connection abrufen:

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

2. Wo kann das Abfrageprotokoll aktiviert werden?

Für einen HTTP-Anforderungslebenszyklus können Sie das Abfrageprotokoll in der handle-Methode einiger BeforeAnyDbQueryMiddlewareMiddleware aktivieren und dann die ausgeführten Abfragen in der terminate -Methode derselben Middleware abrufen.

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

Die Kette einer Middleware wird für handwerkliche Befehle nicht ausgeführt. Daher können Sie für die CLI-Ausführung das Abfrageprotokoll im Ereignis-Listener artisan.start aktivieren.

Beispielsweise können Sie es in die bootstrap/app.php-Datei einfügen

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

3. Speicher

Laravel speichert alle Abfragen im Speicher. In einigen Fällen, z. B. beim Einfügen einer großen Anzahl von Zeilen oder bei einem langen Job mit vielen Abfragen, kann dies dazu führen, dass die Anwendung zu viel Speicher verwendet. 

In den meisten Fällen benötigen Sie das Abfrageprotokoll nur zum Debuggen. In diesem Fall würde ich empfehlen, dass Sie es nur für die Entwicklung aktivieren.

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

Verweise

214

Wenn alles, was Sie wirklich interessiert, die eigentliche Abfrage (die letzte, die ausgeführt wird) für schnelle Debugging-Zwecke ist:

DB::enableQueryLog();

# your laravel query builder goes here

$laQuery = DB::getQueryLog();

$lcWhatYouWant = $laQuery[0]['query']; # <-------

# optionally disable the query log:
DB::disableQueryLog();

führen Sie eine print_r() für $laQuery[0] aus, um die vollständige Abfrage einschließlich der Bindungen abzurufen. (Bei der obigen Variablen $lcWhatYouWant werden die Variablen durch ?? ersetzt.)

Wenn Sie etwas anderes als die Haupt-MySQL-Verbindung verwenden, müssen Sie stattdessen diese verwenden:

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

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

(mit Ihrem Verbindungsnamen, in dem "mysql2" steht)

37
Skeets

Bei Laravel 5.2 scheint der Abschluss in DB::listen nur einen einzigen Parameter zu erhalten.

Wenn Sie DB::listen in Laravel 5.2 verwenden möchten, sollten Sie Folgendes tun:

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

Fügen Sie dies in die Datei routes.php ein:

\Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query) {
    echo'<pre>';
    var_dump($query->sql);
    var_dump($query->bindings);
    var_dump($query->time);
    echo'</pre>';
});

Übermittelt von msurguy, Quellcode in diese Seite Diesen Fixcode für Laravel 5.2 finden Sie in den Kommentaren.

9
Rubén Ruíz

Sie müssen zuerst die Abfrageprotokollierung aktivieren

DB::enableQueryLog();

Es ist besser, wenn Sie die Abfrageprotokollierung aktivieren, bevor die Anwendung gestartet wird. Dies können Sie in einer BeforeMiddleware tun und anschließend die ausgeführten Abfragen in AfterMiddleware abrufen.

9
Vineet Garg

Zum laravel 5.8 Sie fügen nur hinzu dd oder dump.

Ex:

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

oder

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

referenz: https://laravel.com/docs/5.8/queries#debugging

2
larp

(Laravel 5.2) Die einfachste Möglichkeit besteht darin, eine Codezeile zur Überwachung der SQL-Abfragen hinzuzufügen: \DB::listen(function($sql) {var_dump($sql); });

2
ChrisH

Dieser Code ist für:

  • Laravel 5.2
  • Protokollieren Sie die Anweisungen in der MySQL-Datenbank

Hier ist der Code, der auf der Antwort von @milz basiert:

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

Der Kern ist die Zeile if(stripos..., die die Rekursion des Einfügens der Anweisung insert into log sql in die Datenbank verhindert.

1
fzyzcjy

In Fortsetzung von Anscheinend mit Laravel 5.2 erhält die Schließung in DB :: listen oben nur einen einzigen Parameter ... .

Zusätzlich:

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

Verwenden Sie toSql() anstelle von get() wie folgt:

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