- 本文地址: https://www.yangdx.com/2022/05/211.html
- 转载请注明出处
新建 app/Listeners/SqlListener.php
监听器,代码如下:
<?php
namespace App\Listeners;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\Process\PhpExecutableFinder;
use Throwable;
class SqlListener
{
/**
* @var Request
*/
private $request;
/**
* Create the event listener.
*
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Handle the event.
*
* @param QueryExecuted $event
* @return void
*/
public function handle(QueryExecuted $event)
{
if (config('app.debug') == false) {
return;
}
try {
$bindings = $event->connection->prepareBindings($event->bindings);
foreach ($bindings as $key => $value) {
if (!is_int($value)) {
if (is_null($value)) {
$value = 'null';
} else {
$value = "'".addslashes($value)."'";
$value = str_replace(["\r", "\n"], ['\r', '\n'], $value);
}
$bindings[$key] = $value;
}
}
$sql = str_replace(['%', '?'], ['%%', '%s'], $event->sql);
$sql = vsprintf($sql, $bindings);
// 不记录 admin_* 表
// if (Str::is('*`admin_*`*', $sql)) {
// return;
// }
if (app()->runningInConsole()) {
$method = 'CLI';
$uri = (new PhpExecutableFinder)->find(false);
foreach ($this->request->server('argv') as $arg) {
$uri .= ' '.escapeshellarg($arg);
}
} else {
$method = $this->request->getMethod();
$uri = $this->request->getRequestUri();
}
$now = now();
$logTime = $now->format('Y-m-d H:i:s');
$logDate = $now->format('Y-m-d');
$runTime = $event->time;
$log = "[$logTime] $method: $uri, Time: {$runTime}ms".PHP_EOL.$sql.PHP_EOL.PHP_EOL;
$file = storage_path('logs/sql-'.$logDate.'.log');
file_put_contents($file, $log, FILE_APPEND);
} catch (Throwable $e) {
Log::error($e->getMessage().PHP_EOL.$e->getTraceAsString());
}
}
}
再编辑 app/Providers/EventServiceProvider.php
文件,在 $listen 数组中添加这个 SQL 监听器:
protected $listen = [
\Illuminate\Database\Events\QueryExecuted::class => [
\App\Listeners\SqlListener::class,
],
];
这样就可以了,当我们处于 debug 模式时,SQL 语句会被记录到 storage/logs/sql-年-月-日.log
文件里。
is_int 估计得改改, 还有浮点型
博主回复:
整数型参数不做任何转换,空值 NULL 带入字面量 null,其他类型转换为字符串再带入。SQL 日志示例: