先看效果,不是想要的可以直接劃走
直接在控制臺打印解析后的sql語句,可復制到navicat執(zhí)行,而不是帶有?的prepare sql
可打印出產(chǎn)生sql語句的文件行號,方便排查
php webman make:bootstrap SqlDebug
需要先安裝命令行插件
詳細見 http://m.wtbis.cn/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;
/**
* 在控制臺打印執(zhí)行的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目錄下產(chǎn)生的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);
}
}
}
}
});
}
}
Thanks, I change the code to this and it works well
$bindings = $queryExecuted->bindings;
$sql = $queryExecuted->connection->getQueryGrammar()->substituteBindingsIntoRawSql(
$queryExecuted->sql,
$queryExecuted->connection->prepareBindings($bindings)
);
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?
example if you want file:line
self::dumpvar("[sql] [time:{$queryExecuted->time} ms] [{$sql}]");
// print file:line, filter only app folder
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
foreach ($traces as $trace) {
if (stristr($trace['file'], app_path())) {
self::dumpvar(str_replace(app_path(), 'app', $trace['file']) . ":" . $trace['line']);
}
}
沒效果
$article=new Posts();
$article->post_author=$loginUser['userid'];
$article->post_date=date('Y-m-d H:i:s');
$article->post_date_gmt=date('Y-m-d H:i:s');
$article->save();
這種的不輸出?
在上個月 laravel 已經(jīng)支持輸出完整的 SQL 語句了
https://github.com/laravel/framework/releases/tag/v10.15.0