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

PHP简易mail()表单突然无法发送邮件求助

修复你的PHP mail()联系表单失效问题

我来帮你一步步排查并修复这个突然失效的联系表单,先从代码问题和常见服务器配置故障点说起:

一、先排查服务器层面的基础问题(代码没问题也可能发不出邮件)

  • 首先确认服务器的邮件服务是否运行:比如用SSH登录服务器,执行命令 echo "测试内容" | mail -s "测试邮件" vb@gmail.com,如果命令行都发不出邮件,那就是服务器的sendmail/postfix等邮件服务没启动或者配置错误,需要联系主机商排查。
  • 检查PHP配置:查看php.ini里的sendmail_path是否正确指向邮件服务的执行文件,同时确认disable_functions里没有把mail函数禁用。
  • 检查收件邮箱的垃圾邮件文件夹:很多时候邮件其实发出去了,但被当成垃圾邮件拦截了。

二、你的代码里的具体问题及修复

1. 邮件头格式错误,缺少有效发件人

你的$subjc变量只设置了邮件名称,没有包含有效的发件人邮箱地址,而且代码里的换行可能导致头信息损坏。服务器通常要求发件人地址是服务器域名下的有效邮箱(比如no-reply@yourdomain.com),否则会被拒收。

2. 未启用输入过滤,存在注入风险

你注释掉了filter_email_header函数的调用,用户输入的邮箱、姓名等内容可能包含特殊字符,破坏邮件头格式,导致发送失败。

3. 邮件发送状态判断逻辑错误

你用if (isset($sent))来判断发送状态,但哪怕mail()返回false(发送失败),$sent变量也是存在的,会错误显示“Successfuly sent”(还有拼写错误,应该是Successfully)。

4. HTML内容构建冗余且不规范

你把邮箱和消息分别包裹HTML标签,拼接后可能导致格式混乱,应该统一构建完整的HTML邮件内容。


修复后的完整代码示例

<div class="form">
    <form id="mail-form" action="" method="POST">
        <label for="subject">Name:</label><input type="text" name="subject" id="subject"><br>
        <label for="from">Email:</label><input type="text" name="from" id="from"><br>
        <label for="number">Phone number:</label><input type="text" name="number" id="number" /> <br>
        <label id="msg" for="message">Message:</label><br><textarea name="message" id="message" rows="5"></textarea><br>
        <input type="submit" class="button" id="send" name="sbm" value="Send" /><span class="button" id="clear">Refresh</span>

        <?php
        if(isset($_POST['sbm'])){
            // 获取并过滤用户输入
            $email_address = filter_var($_POST['from'], FILTER_VALIDATE_EMAIL);
            $subject = htmlspecialchars($_POST['subject']);
            $feedback = htmlspecialchars($_POST['message']);
            $number = htmlspecialchars($_POST['number']);

            // 过滤邮件头特殊字符,防止注入
            function filter_email_header($form_field) {
                return preg_replace('/[\r\n|\n|\r|<>^$%&*]+/','',$form_field);
            }

            $email_address = filter_email_header($email_address);
            $subject = filter_email_header($subject);

            // 构建完整的HTML邮件内容
            $email_content = '
            <html lang="bg">
            <head>
                <meta charset="UTF-8">
            </head>
            <body>
                <p><strong>Name:</strong> ' . $subject . '</p>
                <p><strong>Email of the sender:</strong> ' . $email_address . '</p>
                <p><strong>Phone Number:</strong> ' . $number . '</p>
                <p><strong>Message:</strong><br>' . nl2br($feedback) . '</p>
            </body>
            </html>';

            // 设置正确的邮件头
            $headers = "MIME-Version: 1.0\r\n";
            $headers .= "Content-Type: text/html; charset=UTF-8\r\n";
            // 使用服务器有效域名下的邮箱作为发件人
            $headers .= "From: Reservation <no-reply@yourdomain.com>\r\n";
            // 设置回复地址为用户输入的邮箱
            $headers .= "Reply-To: " . $email_address . "\r\n";

            // 发送邮件
            $sent = mail('vb@gmail.com', 'Reservation Request', $email_content, $headers);

            // 正确判断发送状态
            if ($sent) {
                echo '<div id="success">Successfully sent</div>';
            } else {
                echo '<div id="error">Failed to send message, please try again later.</div>';
            }
        }
        ?>
    </form>
</div>

修复说明

  • 改用filter_var验证邮箱格式,同时启用过滤函数防止邮件头注入。
  • 统一构建规范的HTML邮件内容,用nl2br保留消息里的换行。
  • 添加了MIME-Version头,完善了From和Reply-To,确保邮件头符合规范。
  • 修正了发送状态的判断逻辑,失败时显示错误提示。
  • 修正了“Successfuly”的拼写错误。

如果按上面的代码修改后还是发不出邮件,那大概率是服务器的邮件服务配置问题,建议联系你的主机提供商协助排查。

内容的提问来源于stack exchange,提问作者Vladimir B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:02:28