使用SwiftMailer添加含特殊字符的云服务附件时报错求助
SwiftMailer添加含特殊字符的远程附件报错解决方案
当使用SwiftMailer的attachFromPath方法添加含特殊字符(如%%%、¥¥¥)的远程云服务文件作为附件时,会触发如下错误:
Unable to open path "https://xxxxxx/1664960211LNW1344-88%%%¥¥¥nylon12Elastane.pdf".
问题根源是远程URL中的特殊字符未进行正确的URL编码,导致SwiftMailer无法解析并打开路径。以下是两种可行的解决方案:
方案一:对远程URL路径进行URL编码
通过编码URL中的路径部分(保留协议、域名等不变),让SwiftMailer能正确识别路径。
实现代码:
// 编码远程附件URL的工具函数 function encodeRemoteAttachmentUrl($url) { $parts = parse_url($url); if (!isset($parts['path'])) { return $url; } // 拆分路径片段并逐个编码 $pathSegments = explode('/', $parts['path']); $encodedSegments = array_map('rawurlencode', $pathSegments); $encodedPath = implode('/', $encodedSegments); // 重新组装完整URL $encodedUrl = "{$parts['scheme']}://{$parts['host']}"; if (isset($parts['port'])) { $encodedUrl .= ":{$parts['port']}"; } $encodedUrl .= $encodedPath; if (isset($parts['query'])) { $encodedUrl .= "?{$parts['query']}"; } return $encodedUrl; } // 修改附件添加逻辑 if(!empty($res['mailFile'])){ foreach($res['mailFile'] as $f){ $encodedUrl = encodeRemoteAttachmentUrl($f['sFiles']); $email->attachFromPath($encodedUrl, $f['sFilesName']); } }
注意:需确保目标云服务支持编码后的URL访问,部分服务可能要求原始路径格式,此时可改用方案二。
方案二:先下载远程文件到本地临时目录,再添加附件
绕开远程URL的编码问题,将文件下载到本地临时目录后,从本地路径添加附件。
实现代码:
if(!empty($res['mailFile'])){ foreach($res['mailFile'] as $f){ $remoteUrl = $f['sFiles']; $fileName = $f['sFilesName']; // 创建临时文件 $tempFilePath = tempnam(sys_get_temp_dir(), 'mail_att_'); if (!$tempFilePath) { // 处理临时文件创建失败,可添加日志记录 continue; } // 下载远程文件 $fileContent = file_get_contents($remoteUrl); if ($fileContent === false) { // 下载失败,清理临时文件 unlink($tempFilePath); continue; } // 写入临时文件 file_put_contents($tempFilePath, $fileContent); // 从本地路径添加附件 $email->attachFromPath($tempFilePath, $fileName); // 邮件发送完成后自动删除临时文件 $email->addCallback(function () use ($tempFilePath) { if (file_exists($tempFilePath)) { unlink($tempFilePath); } }); } }
注意:需确保服务器允许file_get_contents访问远程URL(若禁用可改用cURL实现下载),同时要处理文件下载失败的异常情况,避免残留无效临时文件。
内容的提问来源于stack exchange,提问作者Li Halten
相关产品推荐
相关产品推荐

