PHP mail() 函数允许我们直接从脚本发送电子邮件。此函数的行为受 php.ini 中的设置影响。因此,php.ini 文件必须正确配置系统如何发送电子邮件的详细信息。

PHP mail() 函数

PHP mail() 函数用于直接从脚本发送邮件。

语法

mail(to, subject, message, additional_headers, additional_params) 

参数

to必填。 指定邮件的一个或多个收件人。
subject必填。 指定要发送的电子邮件的主题。该参数不能包含任何换行符。
message

必填。 指定要发送的消息。每行应该用 CRLF (\r\n) 分隔。行不应超过 70 个字符。

仅限 Windows:如果在行的开头找到句号,则会将其删除。为了解决这个问题,请将这些事件替换为双点。
additional_headers

可选。 指定要插入到电子邮件标头末尾的字符串或数组。这通常用于添加额外的标头(From、Cc 和 Bcc)。多个额外标头应使用 CRLF (\r\n) 分隔。如果传递数组,则其键是标头名称,其值是相应的标头值。

发送邮件时,邮件必须包含 From 标头。可以使用additional_headers 参数进行设置,或者可以在php.ini中设置默认值。
additional_params可选。 指定附加标志作为命令行选项传递给配置为发送邮件时使用的程序,如 sendmail_path 配置设置所定义。例如,当使用带 -f sendmail 选项的 sendmail 时,这可用于设置信封发件人地址。

返回值

如果邮件被成功接受投递则返回 true,否则返回 false。请注意,即使邮件被接受投递,也不意味着邮件实际上会到达预期目的地。

示例:发送邮件

在下面的示例中,mail() 函数用于发送简单的邮件。

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

//如果行超过 70 个字符
//可以使用wordwrap()函数
$message = wordwrap($message, 70, "\r\n");

//主题
$subject = "My Subject";

//发送邮件
$retval = mail('user@example.com', $subject, $message);
         
if($retval == true) {
  echo "Message sent successfully!";
} else {
  echo "Message could not be sent!";
}
?> 

示例:发送带有额外标头的邮件

在下面的示例中,额外标头添加诸如 From、Reply-To 和 X-Mailer 之类的标头。

<?php
$to      = "user@example.com";
$subject = "My Subject";
$message = "Hello World!";
$headers = 'From: webmaster@example.com'."\r\n".
    'Reply-To: webmaster@example.com'."\r\n".
    'X-Mailer: PHP/'.phpversion();

//发送邮件
$retval = mail($to, $subject, $message, $headers);

if($retval == true) {
  echo "Message sent successfully!";
} else {
  echo "Message could not be sent!";
}
?> 

示例:发送带有额外标头作为数组的邮件

考虑下面的示例,其中额外标头作为数组添加。

<?php
$to      = "user@example.com";
$subject = "My Subject";
$message = "Hello World!";
$headers = array('From' => 'webmaster@example.com',
                 'Reply-To' => 'webmaster@example.com',
                 'X-Mailer' => 'PHP/' . phpversion()
                );

//发送邮件
$retval = mail($to, $subject, $message, $headers);

if($retval == true) {
  echo "Message sent successfully!";
} else {
  echo "Message could not be sent!";
}
?> 

示例:使用附加命令行参数发送邮件

考虑下面的示例,其中显示了如何使用此函数添加附加命令行参数。

<?php
$to      = "user@example.com";
$subject = "My Subject";
$message = "Hello World!";

//发送邮件
$retval = mail($to, $subject, $message, null,
             '-fwebmaster@example.com');

if($retval == true) {
  echo "Message sent successfully!";
} else {
  echo "Message could not be sent!";
}
?> 

发送 HTML 电子邮件

要发送 HTML 消息,必须设置 Content-type 标头。

<?php
//指定多个收件人
$to = 'john@example.com, marry@example.com';

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

//消息
$message = '
<html>
<head>
  <title>Birthday Reminders for July</title>
</head>
<body>
  <p>Here are the birthdays upcoming in July!</p>
  <table>
    <tr>
      <th>Person</th><th>Day</th><th>Month</th><th>Year</th>
    </tr>
    <tr>
      <td>John</td><td>15th</td><td>July</td><td>1970</td>
    </tr>
    <tr>
      <td>Marry</td><td>25th</td><td>July</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';

//附加标头
$headers[] = 'From: Birthday Reminder <me@example.com>';
$headers[] = 'Cc: user3@example.com';
$headers[] = 'Bcc: user4@example.com';

//发送邮件
$retval = mail($to, $subject, $message, implode("\r\n", $headers));

if($retval == true) {
  echo "Message sent successfully!";
} else {
  echo "Message could not be sent!";
}
?> 

发送带附件的电子邮件

要发送包含混合内容的电子邮件,需要设置Content-type 标头到 multipart/mixed。然后可以在边界内指定文本和附件部分。

边界以两个连字符开头,后跟一个唯一的数字,该数字不能出现在电子邮件的消息部分中。 PHP 函数 md5() 用于创建 32 位十六进制数字以创建唯一编号。表示电子邮件最后部分的最终边界也必须以两个连字符结尾。

<?php
//指定多个收件人
$to = 'john@example.com, marry@example.com';
$message = "Hello World!";
$subject = "My Subject";

$LE  = "\r\n";
$uid = md5(uniqid(time()));
$filePath = "path to the file";

//检查邮件是否包含附件
$withAttachment = ($filePath !== NULL && file_exists($filePath));

//获取文件信息
//读取文件&base64_encode内容
if($withAttachment){
  $fileName   = basename($filePath);
  $fileSize   = filesize($filePath);
  $handle     = fopen($filePath, "r");
  $content    = fread($handle, $fileSize);
  fclose($handle);
  $content = chunk_split(base64_encode($content));
}

//设置标题
$header  = "From: My Name <me@example.com>$LE";
$header .= "Reply-To: webmaster@example.com $LE";
$header .= "MIME-Version: 1.0$LE";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"$LE";
$header .= "This is a multi-part message in MIME format.$LE";
$header .= "--".$uid."$LE";
$header .= "Content-type:text/html; charset=UTF-8$LE";
$header .= "Content-Transfer-Encoding: 7bit$LE";
$header .= $message."$LE";

//如果有附件则附加标头
if($withAttachment){
  $header .= "--".$uid."$LE";
  $header .= "Content-Type: application/octet-stream; name=\"".$fileName."\"$LE";
  $header .= "Content-Transfer-Encoding: base64$LE";
  $header .= "Content-Disposition: attachment; filename=\"".$fileName."\"$LE";
  $header .= $content."$LE";
  $header .= "--".$uid."--";
}

//发送邮件
$retval = mail($to, $subject, $message, $header);

if($retval == true) {
  echo "Message sent successfully!";
} else {
  echo "Message could not be sent!";
}
?>