使用 PHPMailer 在 PHP 中发送电子邮件

PHPMailer 可能是最流行的用于发送电子邮件的开源 PHP 库。 它于 2001 年首次发布,从那时起,它已成为 PHP 开发人员最喜欢的以编程方式发送电子邮件的方式,除了 Swiftmailer 等其他一些粉丝最喜欢的方式之外。

在本文中,我们将讨论为什么您应该使用 PHPMailer 而不是 PHP 的 mail() 函数,我们将展示一些关于如何使用这个库的代码示例。

它是 PHP 的替代品吗 mail() 功能?

在大多数情况下,它是 PHP 的替代品 mail() 功能,但还有许多其他情况下 mail() 功能不够灵活,无法实现您的需求。

首先,PHPMailer 提供了一个面向对象的接口,而 mail() 不是面向对象的。 PHP 开发人员通常讨厌创建 $headers 使用发送电子邮件时的字符串 mail() 功能,因为它们需要大量转义。 PHPMailer 使这变得轻而易举。 开发人员在使用 mail() 功能,而 PHPMailer 使这变得轻松。

此外, mail() 功能需要一个本地邮件服务器来发送电子邮件,这并不总是很容易设置。 如果您有身份验证,PHPMailer 可以使用非本地邮件服务器 (SMTP)。

其他优势包括:

    发送邮件失败时,可以打印40多种语言的各种错误信息。 它通过 SSL 和 TLS 集成了 SMTP 协议支持和身份验证。 它可以为非 HTML 电子邮件客户端发送电子邮件的替代纯文本版本。 它有一个非常活跃的开发人员社区,可以保证它的安全和最新。

PHPMailer 也被流行的 PHP 内容管理系统使用,如 WordPress、Drupal 和 Joomla。

安装 PHPMailer

您可以使用 Composer 安装 PHPMailer:

composer require phpmailer/phpmailer

使用 PHPMailer 从本地 Web 服务器发送电子邮件

下面是使用 PHPMailer 从本地 Web 服务器发送电子邮件的最简单示例:

<?php
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;

require_once "vendor/autoload.php";

//PHPMailer Object
$mail = new PHPMailer(true); //Argument true in constructor enables exceptions

//From email address and name
$mail->From = "[email protected]";
$mail->FromName = "Full Name";

//To address and name
$mail->addAddress("[email protected]", "Recepient Name");
$mail->addAddress("[email protected]"); //Recipient name is optional

//Address to which recipient will reply
$mail->addReplyTo("[email protected]", "Reply");

//CC and BCC
$mail->addCC("[email protected]");
$mail->addBCC("[email protected]");

//Send HTML or Plain Text email
$mail->isHTML(true);

$mail->Subject = "Subject Text";
$mail->Body = "<i>Mail body in HTML</i>";
$mail->AltBody = "This is the plain text version of the email content";

try {
    $mail->send();
    echo "Message has been sent successfully";
} catch (Exception $e) {
    echo "Mailer Error: " . $mail->ErrorInfo;
}

代码和注释应该足够清晰以解释正在发生的一切。

发送带附件的电子邮件

以下是如何使用 PHPMailer 发送带附件的电子邮件的示例:

<?php
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;

require_once "vendor/autoload.php";

$mail = new PHPMailer;

$mail->From = "[email protected]";
$mail->FromName = "Full Name";

$mail->addAddress("[email protected]", "Recipient Name");

//Provide file path and name of the attachments
$mail->addAttachment("file.txt", "File.txt");        
$mail->addAttachment("images/profile.png"); //Filename is optional

$mail->isHTML(true);

$mail->Subject = "Subject Text";
$mail->Body = "<i>Mail body in HTML</i>";
$mail->AltBody = "This is the plain text version of the email content";

try {
    $mail->send();
    echo "Message has been sent successfully";
} catch (Exception $e) {
    echo "Mailer Error: " . $mail->ErrorInfo;
}

在这里,我们附加了两个文件—— file.txt,它与脚本位于同一目录中,并且 images/profile.png,它位于 images 脚本目录的目录。

要向电子邮件添加附件,我们只需要调用该函数 addAttachment 通过将文件路径作为参数传递给 PHPMailer 对象。 对于附加多个文件,我们需要多次调用它。

故障排除

在我们的两个示例中,我们使用 PHPMailer 的 Exception 类进行调试,因此抛出的任何错误都将帮助我们调试可能发生的任何问题。 我们还添加了参数 true 到 PHPMailer 构造函数,以输出更高级别、更具描述性的异常。

根据我们使用的系统,我们看到的最常见的错误可能与运行 mail() 后台功能:

邮件程序错误:无法实例化邮件功能。

如果我们需要有关错误的更多详细信息,我们还可以在 catch 子句中添加如下内容:

print_r(error_get_last());

通常,邮件功能的问题与缺少邮件服务器设置有关,在这种情况下 error_get_last 函数将返回如下内容:

Array (
    [type] => 2
    [message] => mail(): Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set()
    [file] => OUR_PATH vendorphpmailerphpmailersrcPHPMailer.php
    [line] => 863
)

这是我们可能最常遇到的问题,我们可以使用 SMTP 轻松解决。

显示本地化错误消息

$mail->ErrorInfo 可以用 43 种不同的语言返回错误消息。

要以不同的语言显示错误消息,请复制 language 从 PHPMailer 的源代码目录到项目目录。

例如,要以俄语返回错误消息,请使用以下方法调用将 PHPMailer 对象设置为俄语:

$mail->setLanguage("ru");

您还可以将自己的语言文件添加到 language 目录。

使用 SMTP

您可以使用另一台主机的邮件服务器发送电子邮件,但为此您首先需要进行身份验证。 例如,要从 Gmail 的邮件服务器发送电子邮件,您需要有一个 Gmail 帐户。

SMTP 是邮件客户端用来向邮件服务器发送电子邮件发送请求的协议。 邮件服务器验证电子邮件后,会将其发送到目标邮件服务器。

下面是从您的域从 Gmail 的邮件服务器发送电子邮件的示例。 您不需要本地邮件服务器来运行代码。 我们将使用 SMTP 协议:

<?php
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerSMTP;
use PHPMailerPHPMailerException;

require_once "vendor/autoload.php";

$mail = new PHPMailer(true);

//Enable SMTP debugging.
$mail->SMTPDebug = 3;                               
//Set PHPMailer to use SMTP.
$mail->isSMTP();            
//Set SMTP host name                          
$mail->Host = "smtp.gmail.com";
//Set this to true if SMTP host requires authentication to send email
$mail->SMTPAuth = true;                          
//Provide username and password     
$mail->Username = "[email protected]";                 
$mail->Password = "super_secret_password";                           
//If SMTP requires TLS encryption then set it
$mail->SMTPSecure = "tls";                           
//Set TCP port to connect to
$mail->Port = 587;                                   

$mail->From = "[email protected]";
$mail->FromName = "Full Name";

$mail->addAddress("[email protected]", "Recepient Name");

$mail->isHTML(true);

$mail->Subject = "Subject Text";
$mail->Body = "<i>Mail body in HTML</i>";
$mail->AltBody = "This is the plain text version of the email content";

try {
    $mail->send();
    echo "Message has been sent successfully";
} catch (Exception $e) {
    echo "Mailer Error: " . $mail->ErrorInfo;
}

Gmail 需要通过 SMTP 进行 TLS 加密,因此我们对其进行了相应设置。 在通过 SMTP 发送之前,您需要找出主机名、端口号、加密类型(如果需要),如果需要身份验证,您还需要用户名和密码。 请注意,在 Gmail 上启用双因素身份验证不会让您使用带有用户名/密码的 SMTP。 相反,将需要额外的配置。

使用远程 SMTP 而不是本地邮件的一大优势是,如果您使用 PHP 的 mail() 发送电子邮件的功能 from 地址域设置为本地域名(服务器名称)以外的任何内容,则收件人的电子邮件服务器的攻击过滤器会将其标记为垃圾邮件。 例如,如果您从具有实际主机名的服务器发送电子邮件 example.comfrom 地址 [email protected][email protected],然后雅虎的服务器会将其标记为垃圾邮件或向用户显示一条消息,要求用户不要信任该电子邮件,因为邮件的来源是 example.com 然而它却表现得好像来自 gmail.com. 虽然你拥有 [email protected]雅虎无法发现这一点。

使用 POP3 检索电子邮件

PHPMailer 还允许 POP-before-SMTP 验证来发送电子邮件。 换句话说,您可以使用 POP 进行身份验证并使用 SMTP 发送电子邮件。 遗憾的是,PHPMailer 不支持使用 POP3 协议从邮件服务器检索电子邮件。 它仅限于发送电子邮件。

结论

如果您是 PHP 开发人员,则几乎不可能避免以编程方式发送电子邮件。 虽然您可能会选择 Mandrill 或 SendGrid 等第三方服务,但有时这不是一个选项,而滚动您自己的电子邮件发送库更是如此。 这就是 PHPMailer 及其替代品(Zend Mail、Swift Mailer 等)的用武之地。

您可以在存储库 wiki 或官方文档中了解此库的 API。

您是否被 PHP 库依赖项所困扰? 观看我们的截屏视频,了解 Composer 如何帮助您管理它。

阅读更多

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注