先看效果,不是想要的可以直接划走
直接在控制台打印解析后的sql语句,可复制到navicat执行,而不是带有?的prepare sql
可打印出产生sql语句的文件行号,方便排查
php webman make:bootstrap SqlDebug
需要先安装命令行插件
详细见 https://www.workerman.net/doc/webman/others/bootstrap.html
composer require symfony/var-dumper ^6.0.*
<?php
namespace app\bootstrap;
use Illuminate\Database\Events\QueryExecuted;
use support\Db;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Webman\Bootstrap;
/**
* 在控制台打印执行的SQL语句
*/
class SqlDebug implements Bootstrap
{
/**
* 自定义输出格式,否则输出前面会带有当前文件,无用信息
* @param $var
* @return void
*/
public static function dumpvar($var): void
{
$cloner = new VarCloner();
$dumper = new CliDumper();
$dumper->dump($cloner->cloneVar($var));
}
public static function start($worker)
{
// Is it console environment ?
$is_console = !$worker;
if ($is_console) {
// If you do not want to execute this in console, just return.
return;
}
if (!config("app.debug") || config("app.debug") === 'false') return;
$appPath = app_path();
Db::connection()->listen(function (QueryExecuted $queryExecuted) use ($appPath) {
if (isset($queryExecuted->sql) and $queryExecuted->sql !== "select 1") {
$bindings = $queryExecuted->bindings;
$sql = array_reduce(
$bindings,
function ($sql, $binding) {
return preg_replace('/\?/', is_numeric($binding) ? $binding : "'" . $binding . "'", $sql, 1);
},
$queryExecuted->sql
);
// self::dumpvar("[sql] [time:{$queryExecuted->time} ms] [{$sql}]"); // 这句话是打印所有的sql
// 下面是只打印app目录下产生的sql语句
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
foreach ($traces as $trace) {
if (isset($trace['file']) && isset($trace["function"])) {
if (str_contains($trace['file'], $appPath)) {
$file = str_replace(base_path(), '', $trace['file']);
$str = "[file] {$file}:{$trace['line']} [function]:{$trace["function"]}";
self::dumpvar("[sql] [time:{$queryExecuted->time} ms] [{$sql}]");
self::dumpvar($str);
}
}
}
}
});
}
}
在上个月 laravel 已经支持输出完整的 SQL 语句了
https://github.com/laravel/framework/releases/tag/v10.15.0
可这是webman,不是laravel
Thanks, I change the code to this and it works well
Thanks,and are you Chinese?
But unfortunately, I run an error here, prompting:BadMethodCallException: Method Illuminate\Database\Query\Grammars\MySqlGrammar::substituteBindingsIntoRawSql does not exist
I am using Laravel DB 10.15, maybe you should upgrade
"illuminate/database": "^10.15",
Thank you,now,i want to record the sql exec file line,but,the script not ,can you have the method?
you can find caller file/function by debug_backtrace below
example if you want file:line
thank you very much,it work well
太棒了~~👍🏻
没效果
这种的不输出?