thinkphp 6.x 支持通过 db 类执行 sql 并自动记录日志(需开启 debug 模式),也可手动分段执行 sql 文件并用 log::info/error 记录详情,或通过 shell 命令导入并重定向日志,还可配置独立日志通道专用于 sql 导入。

ThinkPHP 7.0 并未正式发布(目前最新稳定版为 ThinkPHP 6.x,TP7 尚处于开发/预览阶段),因此“ThinkPHP 7.0”很可能是误写。以下按 ThinkPHP 6.x(主流且广泛使用的版本)来解答:如何在执行 SQL 文件(如通过命令行导入或运行 SQL 脚本)时记录日志。
使用 Db 类执行 SQL 并自动记录日志
ThinkPHP 6 默认开启数据库日志(DEBUG 模式下),只要用 Db::execute() 或 Db::query() 执行 SQL,就会被记录到日志中:
- 确保
app_debug = true(env文件或配置中) - SQL 文件需先读取为字符串,再分段执行(避免单条过长或含多语句导致解析失败)
- 示例代码:
$sqlContent = file_get_contents('/path/to/data.sql');
$sqls = array_filter(array_map('trim', explode(';', $sqlContent)));
foreach ($sqls as $sql) {
if (!empty($sql)) {
try {
Db::execute($sql); // 自动记录到日志(含 SQL、耗时、影响行数)
} catch (\Exception $e) {
Log::error('SQL 执行失败:' . $sql . ' | 错误:' . $e->getMessage());
}
}
}日志默认写入 runtime/log/年月/日.log,包含完整 SQL 和执行上下文。
手动记录 SQL 文件执行过程
若需更细粒度控制(如记录文件名、总行数、成功/失败数量),可补充自定义日志:
- 用
Log::info()记录开始、结束、跳过空行等关键节点 - 对每条 SQL 单独计时并记录结果
- 示例片段:
Log::info('开始执行 SQL 文件:data.sql,共 ' . count($sqls) . ' 条语句');
$success = $fail = 0;
foreach ($sqls as $index => $sql) {
$start = microtime(true);
try {
Db::execute($sql);
$cost = round((microtime(true) - $start) * 1000, 2);
Log::info("[SQL #{$index}] 执行成功({$cost}ms):". substr($sql, 0, 100) . '...');
$success++;
} catch (\Exception $e) {
$fail++;
Log::error("[SQL #{$index}] 执行失败:{$e->getMessage()} | SQL:" . substr($sql, 0, 80));
}
}
Log::info("SQL 文件执行完成,成功 {$success} 条,失败 {$fail} 条");通过命令行指令执行 SQL 文件并重定向日志
若使用系统命令(如 mysql -u root -p database ),ThinkPHP 不会捕获该过程。此时需:
- 在 PHP 中用
shell_exec()或proc_open()调用,并捕获输出 - 将命令执行的标准输出和错误重定向到日志文件
- 示例(Linux 环境):
$cmd = "mysql -h127.0.0.1 -uroot -p'123456' myapp_db &1";
$result = shell_exec($cmd);
Log::info('MySQL 命令执行结果:' . $result);⚠️ 注意:生产环境慎用明文密码;建议改用配置文件或 MySQL 配置文件(~/.my.cnf)授权。
配置日志通道单独记录 SQL 执行
可在 config/log.php 中新增一个日志通道,专用于 SQL 导入操作:
- 定义 channel
'sql_import',指定单独的日志文件(如sql_import.log) - 调用时使用
Log::channel('sql_import')->info(...) - 便于排查问题,不与常规业务日志混杂
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











