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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:20:03