技术大牛 / email
提供一种面向对象的方式来发送和排队电子邮件
Requires
- php: >=7.0.0
- phpmailer/phpmailer: ^6.1
- phpunit/phpunit: ^9.4
- symfony/polyfill-mbstring: ^1.20
- technicalguru/database: ^1.3
- technicalguru/utils: ~1
README
提供一种面向对象的方式来发送和排队电子邮件。
几乎所有项目都需要发送电子邮件,例如用户注册或密码重置功能。大多数发送的电子邮件都很简单。不需要像PGP加密等复杂功能。这个库提供了一种创建此类电子邮件的方法,无需设置PHPMailer(底层库),可以发送多封电子邮件,甚至可以通过使用数据库支持的队列来延迟发送电子邮件 - 所有这些都在面向对象的方式中完成。
功能包括
- 将SMTP设置封装在
EmailQueue
对象中。 - 重复使用邮件对象发送多封邮件
- 发送HTML和TEXT电子邮件
- 嵌入图片和附件
- 在数据库后端排队邮件
- 自动添加主题行前缀
- 轻松创建包括地址名称在内的兼容电子邮件地址
- 电子邮件队列在失败之前会尝试多次发送电子邮件
- 可以设置“邮件模式”。邮件模式可以是BCC、重定向甚至完全阻止电子邮件,这在开发或验收环境中可能很有用。
许可证
本项目采用GNU LGPL 3.0许可。
安装
通过Composer
composer install technicalguru/email
通过包下载
您可以从GitHub发行页面下载源代码包
如何使用它
创建主配置对象
配置的中心类是EmailConfig
。它包含所有必要的信息。让我们从基本框架开始
use TgEmail\EmailConfig;
$config = new EmailConfig();
$config->setTimezone('Europe/Berlin');
$config->setDefaultSender('John Doe <john.doe@example.com>');
$config->setSubjectPrefix('[MyAppName] ');
$config->setDebugAddress('admin@example.com');
上面的代码创建配置并告诉它,当需要创建时间戳时,使用时区Europe/Berlin
。这主要是在电子邮件排队时需要记录时间戳时所需的。此值是可选的,默认为UTC
。
接下来,配置了一个默认的发件人地址。当要发送的特定电子邮件没有定义发件人地址时,将使用默认发件人。将在下面进一步解释如何创建电子邮件地址。
主题前缀用于所有将要发送的电子邮件。主题将被添加此字符串。默认为NULL
,不会修改主题。
调试地址仅在需要发送测试邮件时才需要。
创建SMTP配置
我们还需要告诉SMTP服务器位于何处。所以这就是设置这些值的方法
use TgEmail\Config\SmtpConfig;
$host = 'smtp.example.com;
$port = 587;
$auth = TRUE;
$username = 'mySmtpUser';
$password = 'mySmtpPassword';
$secureOption = 'starttls';
$smtpConfig = new SmtpConfig($host, $port, $auth, $username, $password, $secureOption);
$config->setSmtpConfig($smtpConfig);
大多数选项都是自解释的。$auth
告诉底层PHPMailer是否使用提供的用户凭据进行身份验证。$secureOption
由PHPMailer
定义,应具有值smtps
或starttls
。有关更多信息,请参阅PHPMailer文档。
可以通过使用setter设置所有属性
use TgEmail\Config\SmtpConfig;
$smtpConfig = new SmtpConfig();
$smtpConfig->setHost('smtp.example.com');
$smtpConfig->setPort(587);
// continue setup...
也可以通过使用来自technicalguru/utils
包的\TgUtils\Auth\CredentialsProvider
接口设置身份验证凭据
// Define here your provider
$provider = ...;
// Tell SMTP config
$smtpConfig->setCredentialsProvider($provider);
创建主邮件队列对象
现在是时候创建我们的中心MailQueue
对象了
use TgEmail\EmailQueue;
$mailer = new EmailQueue($config);
你现在可以发送第一封电子邮件了。
发送测试电子邮件
有一个快速简单的方法来检查您的设置是否正确
$email = $mailer->createTestMail();
$rc = $mailer->send($email);
发送电子邮件
我们已经设置了发送电子邮件的最基本要求
use TgEmail\Email;
$email = new Email();
$email
->setSubject('Hello World')
->addTo('john.doe@example.com', 'John Doe')
->addBcc('jane.doe@example.com')
->setReplyTo('my-support@example.com')
->setBody(Email::TEXT, 'The text e-mail body')
->setBody(Email::HTML, '<p>The HTML e-mail body</p>');
// Will return FALSE when sending fails
$rc = $mailer->send($email);
这就完了。上面的代码片段是您在应用程序代码中发送电子邮件所需的所有内容。配置和设置应埋藏在您的基础设施设置中。
如何添加附件或嵌入图像
添加文件或嵌入图像很简单。您需要在文件系统中可用且可读。
use TgEmail\Attachment;
$myFile = new Attachment(Attachment::ATTACHED, 'file.pdf', NULL, '/local/path/to/file.pdf', 'application/pdf');
$myImage = new Attachment(Attachment::EMBEDDED, 'img.png', 'img1', '/local/path/to/img.png', 'image/png');
$email
->addAttachment($myFile)
->addAttachment($myImage);
请注意嵌入式图像的第三个参数。它定义了HTML电子邮件中的唯一ID,您可以引用它。
// Using the embedded image
$myHTML = '<img src="cid:img1">';
MailQueue
会将所有附件在您的文件系统中保持原样。然而,有时您可能希望在发送电子邮件后删除文件。构造函数接受两个额外的参数
$myFile = new Attachment(Attachment::ATTACHED, $filename, $cid, $path, $mimeType, TRUE, TRUE);
第一个布尔值将在电子邮件成功发送后触发删除文件。第二个布尔值表示在发送失败时是否可以删除文件。使用这些参数,您再也不用担心临时文件了。特别是当涉及到队列和延迟发送时。
邮件模式
MailQueue
支持所谓的邮件模式。它们告诉邮件对象如何一般地处理电子邮件。当您正在测试设置,或者您处于一个具有真实电子邮件地址的环境(例如用户验收测试环境)时,或者在实际上发送电子邮件并不很有意义时,这将非常有用。
以下模式可用
EmailQueue::DEFAULT
- 这是正常操作。所有电子邮件都按定义发送。EmailQueue::BLOCK
- 这将阻止发送或排队任何邮件。返回代码始终为TRUE。EmailQueue::REROUTE
- 所有电子邮件都将发送到另一个地址,通常是管理员或开发人员地址,并且忽略电子邮件的指定收件人。EmailQueue::BCC
- 电子邮件将发送到其预期收件人,但在BCC上设置了额外的地址。
阻止所有电子邮件
阻止发送或排队所有电子邮件非常简单
$mailer->setMailMode(EmailQueue::BLOCK);
可以在中央EmailConfig
对象上使用相同的方法。
重定向所有电子邮件
您需要在主配置中设置RerouteConfig
配置。您可以在创建配置对象时设置它,或者在整个设置邮件模式时设置它。
use TgEmail\Config\RerouteConfig;
// Create the config
$subjectPrefix = '[Rerouted]';
$recipients = array('my-dev-account@example.com');
$rerouteConfig = new RerouteConfig($subjectPrefix, $recipients);
// And set the mail mode
$mailer->setMailMode(EmailQueue::REROUTE, $rerouteConfig);
在所有发送的电子邮件上将开发者设置为BCC
您需要在主配置中设置BccConfig
配置。您可以在创建配置对象时设置它,或者在整个设置邮件模式时设置它。
use TgEmail\Config\BccConfig;
// Create the config
$recipients = array('my-dev-account@example.com');
$bccConfig = new BccConfig($recipients);
// And set the mail mode
$mailer->setMailMode(EmailQueue::BCC, $bccConfig);
将电子邮件排队以稍后发送
从应用程序代码中直接发送电子邮件的缺点是耗时。用户需要等待发送完成,才能看到任何来自您应用程序的响应。排队电子邮件是解决方案,因为发送是延迟的(最好设置在cron作业中),并且用户可以快速收到其应用程序响应。
您需要一个TgDatabase\Database
对象来排队电子邮件。否则,当您尝试排队电子邮件时,EmailQueue
将抛出异常。请参阅TgDatabase\Database
文档,了解如何创建Database
对象。设置相应的EmailsDAO
和EmailQueue
,如下所示
use TgEmail\EmailsDAO;
$dao = new EmailsDAO($database);
$mailer = new EmailQueue($config, $dao);
如果不存在,邮件器将自动创建队列表。
一旦EmailsDAO
可用,您就可以轻松地排队电子邮件
// Create your email object here
$email = ...
// Queue it. Will return FALSE when sending fails
$rc = $mailer->queue($email);
处理电子邮件队列
您可以在另一个调用或cron作业期间处理队列
$mailer->processQueue($maxSeconds);
参数$maxSeconds
将确保在达到时间限制时停止处理。该参数是可选的,默认为60秒。
如何创建电子邮件地址
创建电子邮件地址有多种方式。所有邮件组件都使用一个 EmailAddress
对象。您可以在需要电子邮件地址的地方使用此对象作为参数。创建此类对象有几种方法。
// From a string
$address = EmailAddress::from('john.doe@example.com');
$address = EmailAddress::from('<john.doe@example.com>');
$address = EmailAddress::from('John Doe <john.doe@example.com>');
// From email string and name
$address = EmailAddress::from('john.doe@example.com', 'John Doe');
// From another object
$obj = new \stdClass;
$obj->name = 'John Doe';
$obj->email = 'john.doe@example.com';
$address = EmailAddress::from($obj);
// From another EmailAddress
$address = EmailAddress::from($anotherEmailAddressObject);
这意味着您可以在创建电子邮件时使用这些样式。
$email->addTo('John Doe <john.doe@example.com>');
$email->addTo('john.doe@example.com', 'John Doe');
$email->addTo(array('John Doe <john.doe@example.com>', $anotherEmailAddressObject, $obj);
从对象、数组或JSON字符串创建配置对象
上述配置对象也可以使用JSON字符串、对象或关联数组创建。以下代码片段简要描述了JSON对象。
SmtpConfig:
-----------
{
"host": "www.example.com",
"port": 587,
"debugLevel": 0,
"auth": true,
"secureOption": "starttls",
"charset": "utf8",
"credentials": {
"user": "username",
"pass": "password"
}
},
RerouteConfig:
--------------
{
"recipients": "hans.mustermann@example.com",
"subjectPrefix": "[Rerouted]"
},
BccConfig:
----------
{
"recipients": "hans.mustermann@example.com"
},
EmailConfig:
------------
{
"timezone": "Europe\/Berlin",
"mailMode": "default",
"smtpConfig": {... see above ...},
"rerouteConfig": {... see above ...},
"bccConfig": {... see above ...},
"debugAddress": "john.doe@example.com",
"defaultSender": "jane.doe@example.com",
"subjectPrefix": "[PHPUnitTest] "
}
每个配置类都提供了一个静态的 from()
方法,该方法接受这些类型作为参数,并返回配置对象本身。
$smtpConfig = SmtpConfig::from($jsonStringOrObjectOrAssocArray);
$rerouteConfig = RerouteConfig::from($jsonStringOrObjectOrAssocArray);
$bccConfig = BccConfig::from($jsonStringOrObjectOrAssocArray);
$emailConfig = EmailConfig::from($jsonStringOrObjectOrAssocArray);
发送和队列多个电子邮件
可以将 Email
对象数组传递给 send()
和 queue()
函数。然而,尤其是在立即发送电子邮件时,您应该意识到这可能需要一些时间。更好的策略是队列大量邮件。
开发笔记
当没有SMTP服务器或数据库可用时,大多数PHPUnit测试将不会执行。单元测试将检查环境变量 EMAIL_TEST_SMTP
和 EMAIL_DATABASE
。有一个bash脚本可用,set-test-env.sh
,它为您创建这些变量。将其复制到例如 set-local-test-env.sh
,并遵循文件中的说明。
贡献
在 GitHub Issue Tracker 报告一个错误、请求增强功能或发起拉取请求。