mail

(PHP 4, PHP 5, PHP 7, PHP 8)

mail发送邮件

说明

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

发送邮件。

参数

to

电子邮件收件人,或收件人列表。

本字符串的格式必须符合 » RFC 2822。例如:

  • user@example.com
  • user@example.com, anotheruser@example.com
  • User
  • User , Another User

subject

电子邮件的主题。

警告

本项不能包含任何换行符,否则邮件可能无法正确发送。

message

所要发送的消息。

行之间必须以一个 CRLF(\r\n)分隔。每行不能超过 70 个字符。

警告

(Windows 下)当 PHP 直接连接到 SMTP 服务器时,如果在一行开头发现一个句号,则会被删掉。要避免此问题,将单个句号替换成两个句号。

<?php
$text
= str_replace("\n.", "\n..", $text);
?>

additional_headers(可选项)

要插入到邮件 header 尾部的 Stringarray

这通常用于添加额外的 header(From、Cc 和 Bcc)。多个额外的 header 应使用 CRLF(\r\n)分隔。如果使用外部数据来组成此 header,则应对数据进行清理,避免注入不需要的 header。

如果传递 array,则 key 是 header 名称,value 对应的 header 值。

注意:

发送邮件时,邮件必须包含 From header。这可以使用 additional_headers 参数来设置,或者可以在 php.ini 中设置默认值。

如果不这样做,将导致类似于 Warning: mail(): "sendmail_from" not set in php.ini or custom "From:" header missing 的错误消息。当直接通过 SMTP(仅限 Windows)发送时,From header 还会设置 Return-Path

注意:

如果未收到消息,请尝试仅使用 LF(\n)。一些 Unix 邮件传输代理(最著名的是 » qmail)会自动用 CRLF 替换 LF(如果使用 CRLF,则会导致 CR 重复)。这应该是最后的手段,因为它不符合 » RFC 2822

additional_params(可选)

发送邮件时,additional_params 参数可用于将额外的 flag 作为命令行选项传递给通过 sendmail_path 配置项指定的邮件发送程序。例如,当使用 sendmail 并配合 -f 选项时,可通过此参数设置邮件发件人地址。

该参数在内部会经过 escapeshellcmd() 转义,以防止命令注入执行。escapeshellcmd() 虽可阻止命令执行,但仍允许添加额外的参数。出于安全考虑,建议用户自行对该参数进行过滤和清理,避免向 shell 命令中注入非预期的参数。

由于会自动应用 escapeshellcmd(),某些符合互联网 RFC 标准、允许在电子邮件地址中使用的字符将无法通过此方式使用。mail() 无法支持这些字符,因此,若程序中必须使用此类字符,建议改用其他发送邮件的方式(例如使用框架或第三方库)。

应将运行 Web 服务器的用户添加到 sendmail 配置的受信任用户列表中,以避免通过此方法设置信封发件人(-f)时,邮件自动带上 “X-Warning” 头部。对于使用 sendmail 的用户,该文件路径为 /etc/mail/trusted-users

返回值

如果邮件成功接受投递,返回 true,否则返回 false

同样重要的是要注意到,邮件仅接受了投递并不意味着邮件实际上达到预定目的地。

更新日志

版本 说明
7.2.0 现在 additional_headers 参数开始支持 array

示例

示例 #1 发送邮件

使用 mail() 发送简单的邮件:

<?php
// 消息
$message = "Line 1\r\nLine 2\r\nLine 3";

// 如果任何一行超过 70 个字符,应该使用 wordwrap()
$message = wordwrap($message, 70, "\r\n");

// 发送
mail('caffeinated@example.com', 'My Subject', $message);
?>

示例 #2 使用额外标头发送邮件

添加基本 header,告诉 MUA 发件人和回复地址:

<?php
$to
= 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
'Reply-To: webmaster@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);
?>

示例 #3 使用 array 形式的额外标头发送邮件

此示例与上面示例发送邮件相同,但将附加 header 作为数组传递(自 PHP 7.2.0 起可用)。

<?php
$to
= 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = array(
'From' => 'webmaster@example.com',
'Reply-To' => 'webmaster@example.com',
'X-Mailer' => 'PHP/' . phpversion()
);

mail($to, $subject, $message, $headers);
?>

示例 #4 使用附加命令行参数发送邮件。

additional_params 参数可用于在使用 sendmail_path 配置的程序发送邮件时,传递额外参数。

<?php
mail
('nobody@example.com', 'the subject', 'the message', null,
'-fwebmaster@example.com');
?>

示例 #5 发送 HTML 邮件

也可以使用 mail() 发送 HTML 邮件。

<?php
// 多个收件人
$to = 'johny@example.com, sally@example.com'; // note the comma

// 主题
$subject = 'Birthday Reminders for August';

// 消息
$message = '
<html>
<head>
<title>Birthday Reminders for August</title>
</head>
<body>
<p>Here are the birthdays upcoming in August!</p>
<table>
<tr>
<th>Person</th><th>Day</th><th>Month</th><th>Year</th>
</tr>
<tr>
<td>Johny</td><td>10th</td><td>August</td><td>1970</td>
</tr>
<tr>
<td>Sally</td><td>17th</td><td>August</td><td>1973</td>
</tr>
</table>
</body>
</html>
'
;

// 发送 HTML 邮件,必须设置 Content-type header
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=iso-8859-1';

// 附加 header
$headers[] = 'To: Mary <mary@example.com>, Kelly <kelly@example.com>';
$headers[] = 'From: Birthday Reminder <birthday@example.com>';
$headers[] = 'Cc: birthdayarchive@example.com';
$headers[] = 'Bcc: birthdaycheck@example.com';

// 发送
mail($to, $subject, $message, implode("\r\n", $headers));
?>

注意:

若需发送 HTML 或其他复杂格式的邮件,建议使用 PEAR 包 » PEAR::Mail

注释

注意:

mail() 的 SMTP 实现(仅限 Windows)在多个方面与 sendmail 实现不同。首先,它不使用本地二进制程序来构造邮件,而是直接通过套接字操作,这意味着需要在网络套接字上监听的邮件传输代理 MTA(可在本地主机或远程机器上)。

其次,From:Cc:Bcc:Date: 等自定义 header 并非MTA 解释,而是由 PHP 进行解析。

因此,to 参数不应采用 "Something <someone@example.com>" 这类地址格式。在与 MTA 通信时,mail 命令可能无法正确解析此类格式。

注意:

值得注意的是,mail() 不适合在循环中发送大量邮件。发送每封邮件,此函数为打开和关闭一个套接字,效率不高。

要发送大量邮件,请参阅 » PEAR::Mail» PEAR::Mail_Queue 包。

注意:

以下 RFC 可能有用: » RFC 1896» RFC 2045» RFC 2046» RFC 2047» RFC 2048» RFC 2049» RFC 2822

参见