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.
相关产品推荐
相关产品推荐

