You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel邮件批量添加附件问题:选择记录发送报错排查

问题解答

可行性结论

完全可以实现选中记录的文件作为邮件附件发送的需求,你当前的报错是代码逻辑中的类型处理错误导致的,并非方案本身不可行。

错误原因分析

报错Cannot access offset of type string on string(无法对字符串类型的偏移量进行访问),本质是代码中把字符串当作数组来操作了,结合你的代码,可能的触发场景:

  1. 传入Mail类的$files不是数组,而是单个字符串,导致foreach遍历字符串的每个字符,后续附件处理逻辑出错。
  2. 数据库中record->filename存储的是序列化后的字符串(如JSON格式),你直接当作普通文件名使用,后续代码试图以数组方式访问它。

修复步骤

1. 修正Controller的参数收集与传递

确保正确获取选中的记录ID,收集有效文件名,并正确传递给Mail类:

// 更稳妥的获取选中ID方式
$formList = $request->input('selected_users', []);
if (!is_array($formList)) {
    // 处理逗号分隔的字符串格式
    $formList = array_filter(explode(',', $formList));
}

$filenames = [];
foreach ($formList as $id) {
    // 先检查记录是否存在,避免空指针
    $record = Record::find($id);
    if ($record && !empty(trim($record->filename))) {
        $filenames[] = trim($record->filename);
    }
}

// 调用Mail类时,确保传入的是数组
Mail::to('收件人邮箱')->send(new YourMailClass($filenames));

2. 修正Mail类的接收与附件处理

首先在Mail类的构造函数中正确接收数组参数:

private $files;

public function __construct(array $files)
{
    $this->files = $files;
}

然后根据文件名的存储类型,选择正确的附件添加方法(不要同时调用attach()和attachFromStorage()):

  • 如果filename存储的是服务器绝对路径:
public function build()
{
    foreach ($this->files as $file) {
        if (file_exists($file) && is_readable($file)) {
            $this->attach($file);
        } else {
            error_log("无效文件:{$file}");
        }
    }

    return $this->view('邮件视图');
}
  • 如果filename存储的是Laravel存储系统的相对路径(比如基于public磁盘的路径):
use Illuminate\Support\Facades\Storage;

public function build()
{
    foreach ($this->files as $file) {
        if (Storage::disk('public')->exists($file)) {
            $this->attachFromStorage($file);
        } else {
            error_log("存储系统中不存在文件:{$file}");
        }
    }

    return $this->view('邮件视图');
}

3. 排查数据库中filename的格式

用dd($filenames)打印Controller中收集到的文件名数组,确认每个元素都是纯字符串:

  • 如果发现某个元素是JSON/序列化字符串,需要先解码处理:
$rawFilename = $record->filename;
$decoded = json_decode($rawFilename, true);
if (is_array($decoded)) {
    // 如果是数组,合并到文件名列表(根据实际需求处理)
    $filenames = array_merge($filenames, $decoded);
} else {
    $filenames[] = trim($rawFilename);
}

内容的提问来源于stack exchange,提问作者Raj Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:42:40