Laravel 8应用导入TXT文件时出现UploadedFile序列化错误如何解决
问题原因
这个报错的本质是Laravel需要将Session闪存数据(也就是redirect()->with()传入的内容)序列化存储时,尝试序列化了不可序列化的Illuminate\Http\UploadedFile上传文件对象,触发了禁止规则。
你代码里的核心问题有两个:
importEsitiAG方法中,文件格式不匹配时直接返回了redirect()->back()重定向实例,这个实例会被赋值给$results变量,随后你又在gestisciImport方法中将$results传入with('results', $results)闪存到Session中。重定向实例会关联当前请求的相关资源,包含上传文件对象引用,因此触发序列化报错。- 你补充的
importRaccomandate方法大概率也存在同样的内部返回重定向的逻辑:首次导入时没有走到返回重定向的分支,所以正常运行;后续导入走到返回重定向的分支,就会触发同样的报错。
解决方案
1. 统一重定向逻辑
所有importXXX业务方法仅返回可序列化的简单类型(布尔值、数组、字符串),不要在方法内部做重定向操作,重定向逻辑统一放到控制器入口方法gestisciImport中处理。
示例修改importEsitiAG方法:
// AG类型结果文件导入调用方法 public function importEsitiAG($file) { try { set_time_limit(-1); if (substr($file->getClientOriginalName(), 0, 2) != 'AG') { Log::channel('custom_log')->info('L\'utente ' . Auth::user() . ' 尝试加载的轨迹格式不正确: ' . $file->getClientOriginalName()); // 返回数组格式的结果,不要返回重定向实例 return [ 'status' => false, 'message' => '轨迹格式不正确,请检查后重新上传' ]; } $opened_file = fopen($file, 'r'); fgets($opened_file, 1024); while (!feof($opened_file)) { $line = explode(';', fgets($opened_file, 1024)); // 增加行数据校验,避免下标不存在报错 if (count($line) < 14) continue; $this->salvaEsitiAG($line); } fclose($opened_file); return [ 'status' => true, 'message' => 'AG文件导入成功' ]; } catch (\Exception $e) { Log::channel('custom_log')->info('导入AG文件出错: ' . $e->getMessage()); return [ 'status' => false, 'message' => '导入失败:' . $e->getMessage() ]; } }
其他importRaccomandate、importEsiti方法也按照同样的规则修改,统一返回数组格式的结果。
2. 调整操作顺序(可选优化)
建议先将上传的临时文件存储到磁盘,再读取存储后的文件执行导入逻辑,不要直接操作临时UploadedFile对象,避免临时文件被销毁、指针异常等问题:
// 先存文件 $path = $file->storeAs('files', $name, 'uploadedfiles'); // 再执行导入,传入存储后的文件路径 $results = $this->inizializzaImport(storage_path('uploaded_files/'.$path), $request->input('tipo_file'));
3. 排查闪存数据
检查所有redirect()->with()传入的参数,确保没有传入UploadedFile、Request、Response这类不可序列化的对象。
排查小技巧
如果修改后依然报错,可以在Laravel序列化触发报错的位置增加断点,打印待序列化的内容,即可快速定位哪个变量携带了上传文件对象的引用。
内容的提问来源于stack exchange,提问作者Ezi90
相关产品推荐
相关产品推荐

