发布于2026-07-13 阅读(0)
扫一扫,手机访问
先说一个最容易被忽视的细节:导入Excel时,如果不记录日志,后来的数据回查基本靠猜,问题排查全靠脑补。所以每一批次的导入,文件名、总行数、成功数、失败数、错误详情、时间戳,一个都不能少。

那么,在ThinkPHP里实现这个功能,具体该怎么做?
第一步,在 config/log.php 中新建一个专属通道,叫 excel_import。指定独立的日志文件路径和格式,这样做的好处是:导入日志和系统日志彻底隔开,查起来一目了然。
下面是配置示例:
return [
'channels' => [
'excel_import' => [
'type' => 'single',
'path' => runtime_path('log/excel_import/'),
'level' => 'info',
'file_size' => 1024 * 1024 * 5,
'max_files' => 30,
],
],
];
这里有个潜规则:runtime_path('log/excel_import/') 会自动创建子目录,但如果你 runtime/log/ 目录不可写,日志写入会静默失败——你根本不知道它没写进去。这一点必须警惕。
通道配置好之后,接下来封装一个服务类,专门输出结构化日志。位置推荐放在 app/common/service/ExcelImportLogger.php。
namespace app\common\service;
use think\facade\Log;
class ExcelImportLogger
{
public static function record($filename, $totalRows, $successCount, $failCount, $errors = [])
{
$logData = [
'file' => $filename,
'total' => $totalRows,
'success' => $successCount,
'fail' => $failCount,
'errors' => array_slice($errors, 0, 5), // 只记前5条错误,防日志爆炸
'time' => date('Y-m-d H:i:s'),
];
Log::channel('excel_import')->info('EXCEL_IMPORT_RESULT', $logData);
}
}
注意这里只截取了前5条错误,原因很简单:如果一条Excel里有上千个错误行,全部记下来日志文件会炸掉。有限度的记录,既能反映问题,又不至于影响性能。
接下来是实战环节。基本流程分三步:
第一步:在控制器导入方法开头,捕获上传的文件名。
第二步:逐行解析Excel并写入数据库,同时同步统计成功与失败的数量。
第三步:解析完成后立即调用 ExcelImportLogger::record(),传入全部参数。
示例代码片段如下:
$file = request()->file('excel');
$filename = $file->getOriginalName();
// ……(中间解析与入库逻辑)
ExcelImportLogger::record($filename, $totalRows, $successCount, $failCount, $errorList);
这里有一个容易踩的坑:很多人习惯把日志调用放在 try-catch 的 finally 里。但这样不行。因为如果解析中途抛出未捕获异常,错误列表就收集不完整了。最终写出去的日志,就像一份缺页的报告,不完整也就失去了意义。正确的做法是:所有数据处理明确结束之后,再写日志——不多不少,刚好一步到位。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8