PHP 5.6下FPDF1.82生成动态PDF经PHPMailer6.3.0发送附件命名异常及报错咨询
异常原因拆解
- 问题触发的核心是对FPDF
Output方法返回值的认知偏差,加上PHPMailer两类附件添加方法的调用混同:- FPDF不同输出模式的返回值存在本质差异
- 当使用
Output('pdf_doc.pdf', 'S')模式时,方法会将生成的PDF二进制内容直接以字符串形式返回,赋值给$pdfdoc的结果是完整的PDF内容,和addStringAttachment的入参要求完全匹配。 - 当使用
Output('pdf_doc.pdf', 'F')模式时,方法的作用是将PDF内容直接写入指定路径的本地磁盘文件,执行完成后不会返回任何有效内容,$doc = $pdf->Output('pdf_doc.pdf', 'F');执行后$doc是空字符串。
- 当使用
- 运行报错的直接来源
日志中显示的addAttachment('', 'pdf_doc.pdf')调用,本质是后续代码里把空值的$doc传给了addAttachment方法——这个方法的设计用途是加载本地磁盘文件作为附件,要求传入有效文件路径;传入空字符串时,PHPMailer会因为找不到有效访问路径抛出"Could not access file: "的异常。 - 附件名被重命名为
.$path的触发逻辑
同一段发件代码里同时存在两次附件添加操作:- 第一次是正确调用
addStringAttachment传入内存中的PDF字符串,本来应该生成命名为pdf_doc.pdf的正常附件 - 第二次是错误调用
addAttachment传入空的$doc值,PHPMailer解析这个无效空路径的附件时,内部命名逻辑因为无法获取有效文件信息,生成了异常的临时文件名.$path;由于这个无效附件条目没有有效文件内容,邮件组装时会复用之前正确传入的PDF二进制内容,但附件命名以后添加的异常条目为准,因此最终收到的PDF文件本身可正常读取,只是文件名被覆盖成了.$path。
- 第一次是正确调用
- FPDF不同输出模式的返回值存在本质差异
修复方式
- 如果不需要在服务器本地留存生成的PDF文件:删除所有
F模式输出、addAttachment调用的冗余代码,仅保留S模式输出获取PDF字符串、通过addStringAttachment添加附件的逻辑即可。 - 如果需要先把PDF落地存储再作为附件:明确将文件存储路径作为入参传给FPDF的
F模式方法,再把这个固定路径传给addAttachment,不要将Output方法的返回值当作路径或内容传入附件方法。
内容的提问来源于stack exchange,提问作者E_cook
相关产品推荐
相关产品推荐

