PHPMailer仅发送单个附件问题及Bootstrap邮件正文格式化求助
解决PHPMailer多附件发送及邮件正文格式化问题
我来帮你搞定这两个问题,先拆解代码里的核心问题,再给你完整的修复方案:
一、多附件只发送单个的问题
你代码里的关键bug是**$name变量在循环中被反复覆盖**,循环结束后它只保留了最后一个上传文件的路径,所以$mail->addAttachment($name)最终只添加了这一个附件。
解决思路很直接:在处理每个上传文件的循环里,每成功移动一个文件就立刻调用addAttachment(),或者把所有文件路径存进数组后批量添加。另外我还加了上传错误判断和目录存在检查,避免无效文件或目录缺失导致的问题。
修改后的上传+附件逻辑:
// 处理上传文件并添加附件 if (isset($_FILES['images']['name']) && !empty($_FILES['images']['name'][0])) { $destination = "attachment/"; // 确保目标目录存在,不存在则创建 if (!file_exists($destination)) { mkdir($destination, 0755, true); } foreach ($_FILES["images"]["tmp_name"] as $key => $tmp_name) { // 跳过空文件项或上传失败的文件 if (empty($_FILES["images"]["name"][$key]) || $_FILES["images"]["error"][$key] !== UPLOAD_ERR_OK) { continue; } $fileName = basename($_FILES["images"]["name"][$key]); $filePath = $destination . $fileName; if (move_uploaded_file($tmp_name, $filePath)) { // 每成功上传一个文件就添加为附件 $mail->addAttachment($filePath); } } }
二、用Bootstrap风格格式化邮件正文
要注意:普通Bootstrap的CSS类在邮件客户端里基本不生效,因为Gmail、Outlook这类主流客户端对外部样式表、<style>标签的支持非常有限,只认内联CSS。
所以我们需要用邮件兼容的HTML结构(优先用表格布局,邮件客户端对表格的兼容性远好于div),把样式直接写在标签里,模拟Bootstrap的视觉效果(比如卡片、栅格、间距等)。
举个适配后的邮件正文示例:
$mail->Body = ' <table width="100%" cellpadding="0" cellspacing="0" style="font-family: Arial, sans-serif; background-color: #f8f9fa;"> <tr> <td align="center" style="padding: 20px;"> <table width="600" cellpadding="0" cellspacing="0" style="background-color: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <!-- 头部区域 --> <tr> <td style="padding: 20px; border-bottom: 1px solid #dee2e6;"> <h2 style="margin: 0; color: #007bff;">服务预订详情</h2> </td> </tr> <!-- 内容区域 --> <tr> <td style="padding: 20px;"> <p style="margin: 0 0 15px;"><strong>姓名:</strong> ' . htmlspecialchars($inputName) . '</p> <p style="margin: 0 0 15px;"><strong>邮箱:</strong> ' . htmlspecialchars($inputEmail) . '</p> <p style="margin: 0 0 15px;"><strong>电话:</strong> ' . htmlspecialchars($inputPhone) . '</p> <p style="margin: 0 0 15px;"><strong>邮编:</strong> ' . htmlspecialchars($inputZip) . '</p> <p style="margin: 0 0 15px;"><strong>选择的服务:</strong> ' . htmlspecialchars($selectService) . '</p> <h4 style="margin: 15px 0; color: #495057;">留言内容:</h4> <p style="margin: 0; line-height: 1.5;">' . nl2br(htmlspecialchars($inputMessage)) . '</p> </td> </tr> <!-- 底部区域 --> <tr> <td style="padding: 15px; text-align: center; background-color: #f8f9fa; border-radius: 0 0 8px 8px;"> <p style="margin: 0; color: #6c757d;">这是来自网站的自动发送邮件</p> </td> </tr> </table> </td> </tr> </table>';
这个结构模拟了Bootstrap的卡片样式,所有样式都是内联的,能在绝大多数邮件客户端正常显示。
修改后的完整代码
把上面的修复整合到你的代码里,最终版本还加了异常处理、输入转义等优化:
<?php $msg = ''; use PHPMailer\PHPMailer\PHPMailer; include_once 'PHPMailer/PHPMailer.php'; include_once 'PHPMailer/Exception.php'; // include_once 'PHPMailer/SMTP.php'; if (isset($_POST['submit'])) { $inputZip = $_POST['inputZip']; $selectService = $_POST['selectService']; $lawnMovingService = $_POST['lawnMovingService']; $leafRemovalService = $_POST['leafRemovalService']; $snowPlowingService = $_POST['snowPlowingService']; $handymanService = $_POST['handymanService']; $inputName = $_POST['inputName']; $inputEmail = $_POST['inputEmail']; $inputPhone = $_POST['inputPhone']; $inputMessage = $_POST['inputMessage']; // 启用异常处理,方便调试邮件发送问题 $mail = new PHPMailer(true); try { // SMTP配置(需要时取消注释并填写信息) // $mail->isSMTP(); // $mail->Host = "smtp.gmail.com"; // $mail->SMTPAuth = true; // $mail->Username = "example@gmail.com"; // $mail->Password = "examplePassword"; // $mail->SMTPSecure = "ssl"; // $mail->Port = 465; $mail->addAddress('milan.uptech@gmail.com'); $mail->setFrom($inputEmail); $mail->Subject = 'Service Booking from Website'; $mail->isHTML(true); // 处理上传文件并添加附件 if (isset($_FILES['images']['name']) && !empty($_FILES['images']['name'][0])) { $destination = "attachment/"; if (!file_exists($destination)) { mkdir($destination, 0755, true); } foreach ($_FILES["images"]["tmp_name"] as $key => $tmp_name) { if (empty($_FILES["images"]["name"][$key]) || $_FILES["images"]["error"][$key] !== UPLOAD_ERR_OK) { continue; } $fileName = basename($_FILES["images"]["name"][$key]); $filePath = $destination . $fileName; if (move_uploaded_file($tmp_name, $filePath)) { $mail->addAttachment($filePath); } } } // 构建Bootstrap风格的邮件正文 $mail->Body = ' <table width="100%" cellpadding="0" cellspacing="0" style="font-family: Arial, sans-serif; background-color: #f8f9fa;"> <tr> <td align="center" style="padding: 20px;"> <table width="600" cellpadding="0" cellspacing="0" style="background-color: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"> <tr> <td style="padding: 20px; border-bottom: 1px solid #dee2e6;"> <h2 style="margin: 0; color: #007bff;">服务预订详情</h2> </td> </tr> <tr> <td style="padding: 20px;"> <p style="margin: 0 0 15px;"><strong>姓名:</strong> ' . htmlspecialchars($inputName) . '</p> <p style="margin: 0 0 15px;"><strong>邮箱:</strong> ' . htmlspecialchars($inputEmail) . '</p> <p style="margin: 0 0 15px;"><strong>电话:</strong> ' . htmlspecialchars($inputPhone) . '</p> <p style="margin: 0 0 15px;"><strong>邮编:</strong> ' . htmlspecialchars($inputZip) . '</p> <p style="margin: 0 0 15px;"><strong>选择的服务:</strong> ' . htmlspecialchars($selectService) . '</p> <h4 style="margin: 15px 0; color: #495057;">留言内容:</h4> <p style="margin: 0; line-height: 1.5;">' . nl2br(htmlspecialchars($inputMessage)) . '</p> </td> </tr> <tr> <td style="padding: 15px; text-align: center; background-color: #f8f9fa; border-radius: 0 0 8px 8px;"> <p style="margin: 0; color: #6c757d;">这是来自网站的自动发送邮件</p> </td> </tr> </table> </td> </tr> </table>'; $mail->send(); header('Location: index.php'); exit; } catch (Exception $e) { // 可选:记录错误日志用于调试 // error_log('邮件发送失败: ' . $mail->ErrorInfo); header('Location: contact.php'); exit; } } ?>
额外优化说明:
- 启用PHPMailer异常处理,方便捕获发送失败的具体原因
- 用
htmlspecialchars()转义用户输入,防止XSS攻击和HTML格式混乱 - 用
nl2br()把用户留言的换行转成HTML换行,保证阅读体验 - 增加目录存在检查,避免上传失败
内容的提问来源于stack exchange,提问作者Milan Bastola
相关产品推荐
相关产品推荐

