Laravel数组转CSV后上传Amazon S3报mb_strlen参数错误如何解决
错误根因
你在调用fclose($file)之后才将$file传给S3上传方法,此时$file对应的文件资源句柄已经被释放,属于无效资源。Laravel底层识别不到有效流资源时,会尝试将传入值转换为字符串处理,因此触发了mb_strlen()参数类型不匹配的报错。
解决方法
Laravel的put方法确实支持传入PHP资源,只需保证资源未关闭、处于可读取状态即可,你可以选择以下任意一种方案修改代码:
方案1:调整资源关闭顺序,写入完成后直接上传
$output = [...] // 待转换为CSV的数组 $file = fopen("C:\Users\User\Desktop\myFile.csv", "w"); foreach ($output as $row) { fputcsv($file, $row); } // 重置文件指针到开头,否则上传的文件内容为空 rewind($file); // 资源未关闭时上传 $path = Storage::disk('s3')->put("/hello.csv", $file, [ 'visibility' => 'public', 'mimetype' => 'text/csv' ]); // 上传完成后再关闭资源 fclose($file);
方案2:使用内存流生成CSV,无需生成本地临时文件
适合文件体积不大的场景,省去本地文件读写的IO开销:
$output = [...] // 待转换为CSV的数组 // 直接在内存中创建读写流 $file = fopen('php://temp', 'r+'); foreach ($output as $row) { fputcsv($file, $row); } rewind($file); $path = Storage::disk('s3')->put("/hello.csv", $file, [ 'visibility' => 'public', 'mimetype' => 'text/csv' ]); fclose($file);
方案3:直接使用本地已生成的文件上传
如果已经提前生成了本地CSV文件,可以直接用putFileAs方法传入文件路径,不需要手动处理资源:
$path = Storage::disk('s3')->putFileAs('/', "C:\Users\User\Desktop\myFile.csv", 'hello.csv', [ 'visibility' => 'public', 'mimetype' => 'text/csv' ]);
内容的提问来源于stack exchange,提问作者jove0610
相关产品推荐
相关产品推荐

