init
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace app\bootstrap;
|
||||
|
||||
use app\config\Config;
|
||||
use Illuminate\Database\Events\QueryExecuted;
|
||||
use support\Db;
|
||||
use support\Log;
|
||||
|
||||
// 引入webman内置日志类
|
||||
use Webman\Bootstrap;
|
||||
|
||||
/**
|
||||
* 在控制台/日志文件打印执行的SQL语句
|
||||
*/
|
||||
class SqlDebug implements Bootstrap
|
||||
{
|
||||
public static function start($worker)
|
||||
{
|
||||
// 判断是否为控制台环境
|
||||
$is_console = !$worker;
|
||||
if ($is_console) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 仅在调试模式下开启
|
||||
$debug = config("app.debug");
|
||||
if (!$debug || $debug === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
$appPath = app_path();
|
||||
|
||||
if (Config::getInstance()->dbDebug) Db::connection()->listen(function (QueryExecuted $queryExecuted) use ($appPath) {
|
||||
// 过滤掉 "select 1" 这类心跳检测SQL
|
||||
if (isset($queryExecuted->sql) && $queryExecuted->sql !== "select 1") {
|
||||
$bindings = $queryExecuted->bindings;
|
||||
// 替换SQL中的?为实际绑定参数
|
||||
$sql = array_reduce(
|
||||
$bindings,
|
||||
function ($sql, $binding) {
|
||||
// 处理参数类型:字符串加引号,数值/布尔直接使用,null显示为NULL
|
||||
$value = match (true) {
|
||||
is_string($binding) => "'{$binding}'",
|
||||
is_null($binding) => 'NULL',
|
||||
is_bool($binding) => $binding ? 1 : 0,
|
||||
default => $binding
|
||||
};
|
||||
return preg_replace('/\?/', $value, $sql, 1);
|
||||
},
|
||||
$queryExecuted->sql
|
||||
);
|
||||
|
||||
// 构造基础SQL日志信息
|
||||
$sqlLog = sprintf(
|
||||
"%s",
|
||||
$sql
|
||||
);
|
||||
|
||||
// 定位产生SQL的业务文件/行号/方法
|
||||
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
foreach ($traces as $trace) {
|
||||
if (isset($trace['file'], $trace['function']) && str_contains($trace['file'], $appPath)) {
|
||||
// 格式化文件路径(去掉项目根目录,只保留相对路径)
|
||||
$file = str_replace(base_path(), '', $trace['file']);
|
||||
$file = ltrim($file, '/\\');
|
||||
$file = str_replace(".php", '', $file);
|
||||
$file = str_replace("\\", '.', $file);
|
||||
$file = str_replace("/", '.', $file);
|
||||
// $file = basename($file);
|
||||
|
||||
// 使用Logger::debug输出日志(会同时输出到控制台和日志文件)
|
||||
Log::debug(
|
||||
'<SQL_LOG_F>' . $file . "</SQL_LOG_F><SQL_LOG_L>{$trace['line']}</SQL_LOG_L><SQL_LOG_M>{$trace['function']}</SQL_LOG_M>[$queryExecuted->time ms] " . $sqlLog
|
||||
);
|
||||
break; // 只打印第一个匹配的业务文件信息,避免重复输出
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user