Laravel通过Storage::disk无法存储多张二维码图片问题排查
问题描述
使用simplesoftwareio/simple-qrcode库生成指定数量的二维码,每个二维码对应不同桌号参数。原本能正常生成多张不同图片,如今生成多张时仅创建1张图片,数据库虽生成对应行数,但所有条目均指向同一张图。
相关代码
public function generate(Request $request) { // dd($request->all()); $data = $request->validate([ 'table_count' => 'required' ]); Auth::check(); $user = Auth::user(); $restaurant = $user->restaurants->where('selected', 1)->first(); $qrCodes = ModelsQrcode::where('restaurant_id', $restaurant->id)->get(); foreach ($qrCodes as $qr) { File::delete($qr->path); } for ($i=1; $i <= $data['table_count']; $i++) { $image = QrCode::format('png') ->size(200) ->generate('http://192.168.8.103:8000/detectagent?table='.$i); $output_file = 'qr_images/img-' . time() . '.png'; Storage::disk('public')->put($output_file, $image); $compiledPath = '/storage/'.$output_file; $newQR = ModelsQrcode::create([ 'path' => $compiledPath, 'table' => $i ]); $newQR->restaurant()->associate($restaurant)->save(); } return redirect('/QRgenerator'); }
问题原因
核心问题出在文件名生成逻辑:$output_file = 'qr_images/img-' . time() . '.png';
time()返回秒级Unix时间戳,而for循环执行速度极快,所有迭代都会在同一秒内完成,导致生成的文件名完全重复。后续的Storage::disk('public')->put()会直接覆盖之前的同文件名图片,最终只剩最后一张二维码;同时数据库所有条目都存了这个重复路径,所以全部指向同一张图。
解决方案
修改文件名生成规则,确保每个文件唯一,可选方案:
- 加入循环变量
$i:$output_file = 'qr_images/img-' . time() . '-' . $i . '.png'; - 使用
uniqid()生成唯一ID:$output_file = 'qr_images/img-' . uniqid() . '.png'; - 直接用唯一的桌号命名:
$output_file = 'qr_images/table-' . $i . '.png';
另外原代码删除旧二维码的逻辑有隐患:$qr->path是Web路径(/storage/...),但File::delete()需要服务器绝对路径或项目根目录相对路径,建议改为用Storage类处理:
foreach ($qrCodes as $qr) { $storagePath = str_replace('/storage/', '', $qr->path); Storage::disk('public')->delete($storagePath); }
内容的提问来源于stack exchange,提问作者Laimonas Rupeika
相关产品推荐
相关产品推荐

