附件发送失败主因是路径错误、mime类型缺失或缓存未清除;必须用storage_path()或public_path()传绝对路径,attachfromstorage()需文件在默认磁盘,重命名和mime须显式指定,且务必执行config:clear和cache:clear。

能发,但附件路径错、MIME类型漏、缓存没清这三件事不处理,90%会失败。
附件路径必须是绝对路径,attach() 不接受相对路径或 URL
很多人直接传 storage/app/invoices/2026-06.pdf 或 ./public/files/report.xlsx,结果报错 file not found。Laravel 的 attach() 底层调用 SwiftMailer,只认真实文件系统路径。
- 正确写法:用
storage_path('app/invoices/2026-06.pdf')或public_path('files/report.xlsx') - 别用
base_path('storage/app/...')—— 它指向项目根目录下的storage,而 Laravel 的storage/app是软链接,实际在storage/framework/storage/app(取决于配置) - 如果文件来自请求上传,务必先
$request->file('attachment')->store('temp')再传绝对路径,别直接传$request->file('attachment')
attachFromStorage() 更安全,但要求文件在 default 存储盘里
它自动拼接 storage 配置路径,省去手动调 storage_path(),但前提是文件已存在 storage/app/ 下(或你配置的 default 盘)。
- 可用:
$this->attachFromStorage('invoices/2026-06.pdf', 'invoice.pdf') - 不可用:
$this->attachFromStorage('s3/invoices/2026-06.pdf')—— 除非你把 S3 设为 default 盘,且flysystem驱动支持本地读取(通常不支持) - 注意:
attachFromStorage()默认 MIME 类型靠扩展名推断,若文件无后缀(如临时生成的 PDF 流),必须显式传['mime' => 'application/pdf']
多个附件、重命名、MIME 类型不能靠猜
传两个同名附件(比如都叫 file.pdf)会导致后者覆盖前者;没设 mime 时,SwiftMailer 可能误判为 text/plain,收件方打不开。
- 每个
attach()调用独立:可连续写两次$this->attach(...),顺序即邮件中显示顺序 - 重命名用
'as'键:$this->attach($path, ['as' => '报价单_20260625.pdf', 'mime' => 'application/pdf']) - 常见 MIME 类型别硬记:
application/pdf、image/jpeg、application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(xlsx) - 不确定时,用 PHP 原生函数:
mime_content_type($path)或finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path)
发不出?先跑这三行命令
配置改了不生效,90%是因为缓存没清,或者 .env 里 MAIL_PASSWORD 有特殊字符没转义(比如 $、#)。
-
php artisan config:clear—— 强制重读 .env -
php artisan cache:clear—— 清掉 view 和 route 缓存(有时干扰 Mailable 加载) -
php -r "echo ini_get('memory_limit').PHP_EOL;"—— 大附件(>2MB)可能触发内存限制,需调高memory_limit
附件本身没问题,但收件方看到空白邮件?检查 Blade 模板里有没有 @yield('content') 漏写,或者 view() 指向的文件根本不存在 —— 这类错误不会报异常,只会静默失败。











