PHP mail()函数

提示: PHP的mail()函数依赖于服务器的邮件配置。在生产环境中,建议使用PHPMailer或SwiftMailer等邮件库。

mail() 函数用于从PHP脚本发送电子邮件。这是PHP内置的邮件发送功能,但需要服务器正确配置邮件发送系统(如sendmail、SMTP等)。

函数语法

mail(
    string $to,
    string $subject,
    string $message,
    array|string $additional_headers = [],
    string $additional_parameters = ""
): bool

参数说明

参数 类型 描述 必需
$to string 收件人邮箱地址,多个用逗号分隔
$subject string 邮件主题
$message string 邮件正文内容
$additional_headers array|string 附加邮件头,如From、Cc、Bcc等
$additional_parameters string 传递给邮件程序的附加参数

返回值

发送成功返回 true,发送失败返回 false。注意:返回true只表示邮件被成功接收排队,不保证邮件最终送达。

使用示例

示例1:发送简单文本邮件

最基本的邮件发送示例:

<?php
// 收件人邮箱
$to = "recipient@example.com";

// 邮件主题
$subject = "测试邮件";

// 邮件内容
$message = "这是一封测试邮件。\r\n";
$message .= "这是第二行内容。";

// 邮件头
$headers = "From: sender@example.com\r\n";
$headers .= "Reply-To: support@example.com\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";

// 发送邮件
if (mail($to, $subject, $message, $headers)) {
    echo "邮件发送成功!";
} else {
    echo "邮件发送失败!";
}
?>

示例2:发送HTML格式邮件

发送包含HTML格式的邮件:

<?php
// 收件人邮箱
$to = "recipient@example.com";

// 邮件主题
$subject = "HTML格式测试邮件";

// HTML邮件内容
$message = '<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>测试邮件</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .header { background-color: #4CAF50; color: white; padding: 10px; text-align: center; }
        .content { padding: 20px; background-color: #f9f9f9; }
        .footer { margin-top: 20px; padding: 10px; text-align: center; color: #666; font-size: 12px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>欢迎加入我们!</h1>
        </div>
        <div class="content">
            <p>亲爱的用户,您好!</p>
            <p>这是一封<strong>HTML格式</strong>的测试邮件。</p>
            <p><a href="https://www.example.com" style="color: #4CAF50;">点击这里访问我们的网站</a></p>
        </div>
        <div class="footer">
            <p>本邮件为系统自动发送,请勿直接回复。</p>
        </div>
    </div>
</body>
</html>';

// 为了兼容性,同时提供纯文本版本
$alt_message = "这是一封HTML格式的测试邮件。请使用支持HTML的邮件客户端查看。";

// 邮件头
$headers = "From: noreply@example.com\r\n";
$headers .= "Reply-To: support@example.com\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";

// 发送邮件
if (mail($to, $subject, $message, $headers)) {
    echo "HTML邮件发送成功!";
} else {
    echo "HTML邮件发送失败!";
}
?>

示例3:发送带附件的邮件

使用MIME格式发送带附件的邮件:

<?php
function sendEmailWithAttachment($to, $subject, $message, $file_path) {
    // 生成边界字符串
    $boundary = md5(time());

    // 邮件头
    $headers = "From: sender@example.com\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";

    // 邮件正文
    $body = "--$boundary\r\n";
    $body .= "Content-Type: text/plain; charset=UTF-8\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode($message)) . "\r\n";

    // 获取文件信息
    $file_name = basename($file_path);
    $file_content = file_get_contents($file_path);
    $file_encoded = chunk_split(base64_encode($file_content));

    // 添加附件
    $body .= "--$boundary\r\n";
    $body .= "Content-Type: application/octet-stream; name=\"$file_name\"\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n";
    $body .= "Content-Disposition: attachment; filename=\"$file_name\"\r\n\r\n";
    $body .= $file_encoded . "\r\n";
    $body .= "--$boundary--";

    // 发送邮件
    return mail($to, $subject, $body, $headers);
}

// 使用示例
$to = "recipient@example.com";
$subject = "测试带附件的邮件";
$message = "请查收附件中的文件。";
$file_path = "/path/to/your/file.pdf"; // 替换为实际文件路径

if (sendEmailWithAttachment($to, $subject, $message, $file_path)) {
    echo "带附件的邮件发送成功!";
} else {
    echo "邮件发送失败!";
}
?>

示例4:发送多部分邮件(HTML + 纯文本)

发送同时包含HTML和纯文本版本的邮件:

<?php
function sendMultipartEmail($to, $subject, $text_content, $html_content) {
    // 生成随机边界字符串
    $boundary = "PHP-mixed-" . md5(time());
    $boundary_alt = "PHP-alt-" . md5(time());

    // 邮件头
    $headers = "From: sender@example.com\r\n";
    $headers .= "Reply-To: support@example.com\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: multipart/alternative; boundary=\"$boundary_alt\"\r\n";

    // 邮件正文
    $body = "--$boundary_alt\r\n";
    $body .= "Content-Type: text/plain; charset=UTF-8\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode($text_content)) . "\r\n";

    $body .= "--$boundary_alt\r\n";
    $body .= "Content-Type: text/html; charset=UTF-8\r\n";
    $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
    $body .= chunk_split(base64_encode($html_content)) . "\r\n";

    $body .= "--$boundary_alt--";

    // 发送邮件
    return mail($to, $subject, $body, $headers);
}

// 使用示例
$to = "recipient@example.com";
$subject = "多部分格式测试邮件";

// 纯文本版本
$text_content = "这是邮件的纯文本版本。
如果您的邮件客户端不支持HTML,将看到此内容。

感谢您的阅读!
- 网站团队";

// HTML版本
$html_content = '<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>多部分邮件</title>
</head>
<body>
    <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
        <h1 style="color: #4CAF50;">这是邮件的HTML版本</h1>
        <p>如果您的邮件客户端支持HTML,将看到此内容。</p>
        <p><strong>感谢您的阅读!</strong></p>
        <p><em>- 网站团队</em></p>
    </div>
</body>
</html>';

if (sendMultipartEmail($to, $subject, $text_content, $html_content)) {
    echo "多部分邮件发送成功!";
} else {
    echo "邮件发送失败!";
}
?>

服务器配置

1. PHP.ini 配置

在php.ini文件中配置邮件设置:

; 对于Unix/Linux系统
[mail function]
sendmail_path = /usr/sbin/sendmail -t -i

; 对于Windows系统
[mail function]
SMTP = smtp.example.com
smtp_port = 25
sendmail_from = you@example.com

; 通用设置
mail.add_x_header = On

2. 使用SMTP发送邮件

通过SMTP服务器发送邮件(需要服务器支持):

<?php
// 使用PHPMailer库(推荐)
// 首先通过Composer安装:composer require phpmailer/phpmailer

/*
require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);

try {
    // 服务器设置
    $mail->isSMTP();
    $mail->Host = 'smtp.example.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'your-email@example.com';
    $mail->Password = 'your-password';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
    $mail->Port = 465;

    // 收件人
    $mail->setFrom('from@example.com', 'Mailer');
    $mail->addAddress('recipient@example.com');

    // 内容
    $mail->isHTML(true);
    $mail->Subject = '使用PHPMailer发送的邮件';
    $mail->Body = '<b>这是HTML邮件内容</b>';
    $mail->AltBody = '这是纯文本内容';

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

常见问题与解决方案

  1. 检查垃圾邮件文件夹
  2. 验证收件人邮箱地址是否正确
  3. 检查服务器邮件日志:tail -f /var/log/mail.log
  4. 域名可能被列入黑名单
  5. 检查SPF、DKIM、DMARC记录

  • 使用本地邮件服务器而不是远程SMTP
  • 异步发送邮件(使用队列系统)
  • 检查DNS解析速度
  • 减少附件大小或压缩附件
  • 使用专业的邮件发送服务(如Amazon SES、SendGrid)

  • 设置正确的From地址
  • 包含退订链接
  • 避免使用垃圾邮件关键词
  • 配置SPF、DKIM、DMARC记录
  • 保持合理的发送频率
  • 验证收件人邮箱有效性

安全注意事项

安全提示
  • 验证输入:始终验证收件人邮箱地址,防止邮件头注入攻击
  • 使用预定义的邮件模板:避免直接将用户输入用作邮件内容
  • 限制发送频率:防止被用于垃圾邮件发送
  • 使用TLS/SSL加密:保护邮件传输过程
  • 记录邮件发送日志:便于追踪和审计

最佳实践

  1. 在生产环境中使用专业的邮件库(如PHPMailer、SwiftMailer)
  2. 使用队列系统处理大量邮件发送
  3. 配置邮件发送失败的重试机制
  4. 监控邮件发送成功率
  5. 定期清理邮件发送队列
  6. 遵循反垃圾邮件法规(如CAN-SPAM法案)

替代方案

方案 优点 缺点
PHPMailer 功能强大,支持SMTP、附件、HTML邮件 需要额外安装
SwiftMailer 现代化,支持多种邮件传输方式 学习曲线较陡
Amazon SES 高送达率,可扩展性好 需要付费
SendGrid/Mailgun 专业邮件服务,提供API和分析 需要付费,有发送限制