ฉันพยายามที่จะดูบันทึกการสืบค้น แต่DB::getQueryLog()
เพิ่งกลับอาร์เรย์ที่ว่างเปล่า:
$user = User::find(5);
print_r(DB::getQueryLog());
ผลลัพธ์
Array
(
)
ฉันจะดูบันทึกการสืบค้นนี้ได้อย่างไร
ฉันพยายามที่จะดูบันทึกการสืบค้น แต่DB::getQueryLog()
เพิ่งกลับอาร์เรย์ที่ว่างเปล่า:
$user = User::find(5);
print_r(DB::getQueryLog());
ผลลัพธ์
Array
(
)
ฉันจะดูบันทึกการสืบค้นนี้ได้อย่างไร
คำตอบ:
โดยค่าเริ่มต้นบันทึกการสืบค้นจะถูกปิดใช้งานใน 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
}
);
หากคุณมีการเชื่อมต่อฐานข้อมูลมากกว่าหนึ่งรายการคุณต้องระบุการเชื่อมต่อที่จะเข้าสู่ระบบ
วิธีเปิดใช้งานบันทึกคิวรีสำหรับ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")
วางสิ่งนี้ไว้บนไฟล์ route.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หรือการถ่ายโอนข้อมูล
Ex:
DB::table('users')->where('votes', '>', 100)->dd();
หรือ
DB::table('users')->where('votes', '>', 100)->dump();
การอ้างอิง: https://laravel.com/docs/5.8/queries#debugging
ใช้toSql()
แทนget()
อย่างเช่น:
$users = User::orderBy('name', 'asc')->toSql();
echo $users;
// Outputs the string:
'select * from `users` order by `name` asc'
(Laravel 5.2) ฉันพบวิธีที่ง่ายที่สุดคือเพียงเพิ่มโค้ดหนึ่งบรรทัดเพื่อตรวจสอบเคียวรี sql:
\DB::listen(function($sql) {var_dump($sql); });
ในการดำเนินการตามApparently กับ Laravel 5.2 การปิดใน DB :: Listen จะได้รับพารามิเตอร์เดียว ...การตอบสนองด้านบน: คุณสามารถใส่รหัสนี้ในสคริปต์ Middleware และใช้ในเส้นทาง
นอกจากนี้:
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();
}
});
หลักคือif(stripos...
สายซึ่งป้องกันการเรียกซ้ำinsert into log
คำสั่ง sql ลงในฐานข้อมูล
ฉันคิดว่าคำตอบที่อยู่ในบทความนี้: 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));
});
}
}
สมมติว่าคุณต้องการพิมพ์แบบสอบถาม SQL ของคำสั่งต่อไปนี้
$user = User::find(5);
คุณเพียงแค่ต้องทำดังนี้:
DB::enableQueryLog();//enable query logging
$user = User::find(5);
print_r(DB::getQueryLog());//print sql query
นี่จะพิมพ์คิวรี่ที่ถูกเรียกใช้ล่าสุดใน Laravel
สำหรับ laravel 5 ขึ้นไปโดยใช้เฉพาะ DB :: getQueryLog () จะไม่ทำ โดยค่าเริ่มต้นในนี้ค่าของ
protected $loggingQueries = false;
เปลี่ยนเป็น
protected $loggingQueries = true;
ในไฟล์ด้านล่างสำหรับบันทึกการสืบค้น
/vendor/laravel/framework/src/illuminate/Database/Connection.php
จากนั้นเราสามารถใช้DB::getQueryLog()
ตำแหน่งที่คุณต้องการพิมพ์แบบสอบถาม
vendor
ไฟล์ พวกเขาจะต้องเก็บไว้เป็นต้นฉบับ