PHP怎么发送邮件?SMTP邮件发送功能实现教程

来源:站长联盟作者:澳门程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《PHP怎么发送邮件?SMTP邮件发送功能实现教程》,敬请观看详情。直接调用PHP内置的mail函数常常在云主机上失败,因为多数环境未配置本地邮件代理。更稳妥的做法是通过SMTP协议连接专业邮件服务。本文讲清楚如何用PHP使用SMTP账号发送邮件,包括使用PHPMailer库与原生socket两种方式。我们会对比二者在鉴权、TLS加密和错误处理上的差异,并给出可运行代码。理解SMTP的握手流程和邮件头构造,能帮你避开乱码、被拒收等常见坑,快速在网站中实现找回密码、通知推送等邮件能力。

在Web开发中,使用PHP实现邮件发送是一项基础但容易出问题的功能。很多服务器默认没有安装sendmail,直接调用mail函数往往无声无息地失败。通过SMTP协议连接邮件服务商,不仅能提高送达率,还能支持鉴权和加密传输。

PHP怎么发送邮件?SMTP邮件发送功能实现教程

为什么不用PHP自带的mail函数

PHP提供了mail函数,表面上看只需传入收件人、主题和正文即可。但在实际生产环境中,该函数依赖操作系统层面的邮件传输代理(MTA),例如sendmail或postfix。当你在云服务器或共享主机上未正确配置MTA时,邮件既不会报错也可能根本没发出去。

另外,mail函数难以支持SMTP鉴权、SSL或TLS加密,也无法方便地设置HTML格式和附件。现代邮件服务商如网易、腾讯、Gmail都要求发信方使用合法账号经过SMTP认证,否则极大概率被归入垃圾邮件。因此,基于SMTP的实现才是可靠方案。

使用PHPMailer实现SMTP发送

PHPMailer是PHP社区最流行的邮件发送库,它封装了SMTP协议细节,支持TLS、OAuth以及多种内容类型。通过Composer安装后,只需少量代码即可完成发送。

下面示例演示如何用PHPMailer通过网易邮箱的SMTP服务发送一封HTML邮件。注意将邮箱账号和授权码替换为你自己的信息,授权码通常在邮箱设置中开启SMTP后生成,不是登录密码。

<?php
require 'vendor/autoload.php';
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;

$mail = new PHPMailer(true);
try {
    // 服务器设置
    $mail->isSMTP();
    $mail->Host = 'smtp.163.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'yourname@163.com';
    $mail->Password = 'your_auth_code';
    $mail->SMTPSecure = 'tls';
    $mail->Port = 587;

    // 收件人与发件人
    $mail->setFrom('yourname@163.com', '站点管理员');
    $mail->addAddress('user@ippipp.com', '测试用户');

    // 邮件内容
    $mail->isHTML(true);
    $mail->Subject = 'PHP SMTP测试邮件';
    $mail->Body = '<h3>你好</h3><p>这是一封通过PHPMailer发送的邮件。</p>';
    $mail->AltBody = '你好,这是一封通过PHPMailer发送的邮件。';

    $mail->send();
    echo '邮件已发送';
} catch (Exception $e) {
    echo '发送失败: ' . $mail->ErrorInfo;
}
?>

上述代码中,SMTPSecure设为tls表示使用STARTTLS加密,端口对应587;若使用ssl则端口通常为465。AltBody为纯文本备用内容,当收件客户端不支持HTML时显示。异常处理能帮助你快速定位是鉴权失败还是网络问题。

PHPMailer的优点是接口清晰、文档完善,且持续维护。缺点是引入额外依赖,对极度轻量环境不够友好。如果项目已使用Composer,几乎总是首选它。

用原生socket模拟SMTP发送

若运行环境无法安装第三方库,也可以用PHP的fsockopen函数直接建立TCP连接,手动完成SMTP对话。这种方式要求你理解SMTP命令:EHLO、AUTH LOGIN、MAIL FROM、RCPT TO、DATA等。

以下代码展示一个简化版的SMTP发送过程,未处理所有异常,仅用于理解协议。真实场景应增加错误读取与重试机制。

<?php
$host = 'smtp.163.com';
$port = 587;
$socket = fsockopen($host, $port, $errno, $errstr, 10);
if (!$socket) {
    die("连接失败: $errstr");
}

function smtp_read($socket) {
    $data = '';
    while ($line = fgets($socket, 512)) {
        $data .= $line;
        if (substr($line, 3, 1) == ' ') break;
    }
    return $data;
}

fwrite($socket, "EHLO localhostrn");
smtp_read($socket);

fwrite($socket, "AUTH LOGINrn");
smtp_read($socket);
fwrite($socket, base64_encode('yourname@163.com') . "rn");
smtp_read($socket);
fwrite($socket, base64_encode('your_auth_code') . "rn");
smtp_read($socket);

fwrite($socket, "MAIL FROM: <yourname@163.com>rn");
smtp_read($socket);
fwrite($socket, "RCPT TO: <user@ipipp.com>rn");
smtp_read($socket);
fwrite($socket, "DATArn");
smtp_read($socket);
fwrite($socket, "From: yourname@163.comrn");
fwrite($socket, "To: user@ipipp.comrn");
fwrite($socket, "Subject: 原生socket SMTPrn");
fwrite($socket, "rn");
fwrite($socket, "这是一封通过socket发送的测试邮件。rn");
fwrite($socket, ".rn");
smtp_read($socket);

fwrite($socket, "QUITrn");
fclose($socket);
echo '完成';
?>

原生方式让你完全掌控交互,不依赖外部包,但必须自己处理TLS升级(使用stream_socket_enable_crypto)、Base64编码及多行响应解析。任何命令返回码不是2xx或3xx都代表出错,需要终止流程。

对比来看,原生socket适合受限环境学习协议,PHPMailer适合业务系统。二者核心都是遵循SMTP标准,理解后者有助于排查前者的问题。

常见错误与排查要点

第一,授权码与密码混淆。多数邮箱SMTP要求单独授权码,用登录密码会返回535鉴权失败。第二,端口与加密不匹配,例如tls配465会握手超时。第三,邮件头换行必须使用rn,仅用n在某些服务器会被拒绝。

当邮件进入垃圾箱时,检查发件域名是否配置SPF、DKIM记录。虽不属于PHP代码范畴,但直接影响送达率。在开发阶段可先向自己邮箱发信,观察原始头信息中的Authentication-Results字段。

方式依赖加密支持维护成本
mail函数系统MTA低但易失效
PHPMailerComposer包TLS/SSL
原生socket需手动

综合而言,PHP发送邮件不应再依赖默认配置。采用SMTP并选对工具,才能让通知、验证码等功能稳定运行。

PHPSMTPmail_function修改时间:2026-07-31 15:12:51

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。