插件
插件的存在是为了扩展或修改Swift Mailer的行为。它们响应在发送期间在传输中触发的事件。
Swift Mailer基本包中提供了许多插件,它们都遵循一个公共接口来响应库中触发的事件。提供接口来“监听”触发的每种类型的事件,并在监听的事件发生时按需要行事。
虽然Swift Mailer提供了几个开箱即用的插件,但Events系统是专门为有经验的面向对象开发人员编写自己的插件而设计的,以实现基本库可能无法实现的目标。
AntiFlood插件
许多SMTP服务器对在任何单个SMTP连接期间可以发送的消息数量有限制。反洪水插件提供了一种方法,保持在这个限制,同时仍然管理大量的电子邮件。
单个连接的典型限制是100封电子邮件。如果您连接的服务器施加了这样的限制,它希望您在发送该数量的电子邮件后断开连接。你可以在一个循环中手动管理它,但是AntiFlood插件提供了必要的包装器代码,所以你不需要担心这个逻辑。
不管服务器施加的限制如何,对SMTP服务器的资源保持保守通常是一个好主意。如果服务器被过度使用,发送将变得缓慢,所以即使没有限制,使用AntiFlood插件也不是一个坏主意。
防洪水插件的逻辑基本上是断开,并立即重新连接到SMTP服务器发送的每X数量的电子邮件,其中X是一个数字,你指定的插件。
您还可以指定一个以秒为单位的时间段,Swift Mailer应该在断开连接/重新连接过程之间暂停。暂停一小段时间(比如每100封电子邮件暂停30秒)是个好主意,只是为了让SMTP服务器有机会处理它的队列并恢复一些资源。
使用防洪水插件
像所有的插件一样,AntiFlood插件是与Mailer类一起添加的registerPlugin ()
方法。它接受两个构造函数参数:要暂停的电子邮件数量,以及可选的暂停秒数。
当Swift Mailer发送消息时,它将计算自上次重新连接以来已发送的消息数量。一旦数字达到您指定的阈值,它将断开并重新连接,可选择暂停一段时间:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//使用任意传输创建邮件$梅勒=新Swift_Mailer (新Swift_SmtpTransport (“smtp.example.org”,25));//使用AntiFlood在100封邮件后重新连接$梅勒->registerPlugin (新Swift_Plugins_AntiFloodPlugin (One hundred.));//指定一个以秒为单位的暂停时间(30秒)$梅勒->registerPlugin (新Swift_Plugins_AntiFloodPlugin (One hundred.,30.));//继续正常发送为($lotsOfRecipients作为$收件人){…$梅勒->发送(…);}
节流器插件
如果您的SMTP服务器有适当的限制来限制您发送电子邮件的速率,那么您的代码将需要知道这个速率限制。Throttler插件使Swift Mailer以速率限制的速度运行。
许多共享主机并没有免费打开SMTP服务器。通常他们有适当的政策(可能是为了阻止垃圾邮件发送者),只允许你每小时/每天发送固定数量的电子邮件。
Throttler插件支持两种速率限制模式,对于每一种模式,你都需要计算出你想要的值。该插件可以根据每分钟的电子邮件数量或每分钟传输的字节数进行限制。
使用Throttler插件
Throttler插件——像所有插件一样——是与Mailer类一起添加的。registerPlugin ()
方法。它有两个必需的构造函数参数,告诉它如何进行速率限制。
当Swift Mailer发送消息时,它将跟踪发送消息发生的速率。如果它意识到发送发生得太快,它将导致你的程序睡眠()
为了有足够的时间计算出平均率:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
//使用任意传输创建邮件$梅勒=新Swift_Mailer (新Swift_SmtpTransport (“smtp.example.org”,25));//每分钟100封邮件$梅勒->registerPlugin (新Swift_Plugins_ThrottlerPlugin (One hundred., Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE));//速率限制为每分钟10MB$梅勒->registerPlugin (新Swift_Plugins_ThrottlerPlugin (1024*1024*10, Swift_Plugins_ThrottlerPlugin::BYTES_PER_MINUTE));//继续正常发送为($lotsOfRecipients作为$收件人){…$梅勒->发送(…);}
记录器插件
Logger插件有助于在发送过程中进行调试。它可以帮助确定为什么SMTP服务器拒绝地址,或任何其他难以发现的问题可能会出现。
Logger插件分为两部分。有插件本身,以及您可以选择使用的一些可能的记录器之一。例如,记录器可以直接实时输出消息,也可以在数组中捕获消息。
另一个值得注意的特性是Logger插件更改异常消息的方式。如果抛出异常,但错误消息没有提供关于问题来源的结结性信息(例如模棱两可的SMTP错误),Logger插件将整个SMTP记录包含在错误消息中,以便调试变得更简单。
Swift Mailer中包含了一些可用的logger,但编写自己的实现非常简单,只需创建一个实现Swift_Plugins_Logger
接口。
Swift_Plugins_Loggers_ArrayLogger
:在数组中保存日志消息的集合。数组内容可以被清除或转储到屏幕上。Swift_Plugins_Loggers_EchoLogger
:实时输出到屏幕。用于非常基本的调试输出。
使用Logger插件
与所有插件一样,Logger插件是与Mailer类一起添加的。registerPlugin ()
方法。的实例Swift_Plugins_Logger
在它的构造函数中。
当Swift Mailer发送消息时,它将保留与底层传输正在使用的所有交互的日志。根据所使用的Logger的不同,行为会有所不同,但所有实现都提供了一种获取日志内容的方法:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
//使用任意传输创建邮件$梅勒=新Swift_Mailer (新Swift_SmtpTransport (“smtp.example.org”,25));//使用ArrayLogger$日志记录器=新Swift_Plugins_Loggers_ArrayLogger ();$梅勒->registerPlugin (新Swift_Plugins_LoggerPlugin ($日志记录器));或使用Echo Logger$日志记录器=新Swift_Plugins_Loggers_EchoLogger ();$梅勒->registerPlugin (新Swift_Plugins_LoggerPlugin ($日志记录器));//继续正常发送为($lotsOfRecipients作为$收件人){…$梅勒->发送(…);}//转储日志内容//注意:echoologger是实时转储的,因此dump()不为它做任何事情回声$日志记录器->dump ();
装饰器插件
通常情况下,需要将相同的消息发送给多个收件人,但是会有一些细微的变化,例如在消息体中使用收件人的名称。Decorator插件旨在为允许这些小差异提供解决方案。
decorator插件的工作原理是拦截Swift Mailer的发送过程,读取收件人字段中的电子邮件地址,然后查找一组模板的替换项。
虽然这个插件的使用很简单,但由于它的工作方式,它可能是最常被误解的插件。用户犯的典型错误是尝试多次注册插件(每个收件人一次)——例如在循环中。这是不正确的。
Decorator插件应该只注册一次,但是在发送之前包含所有收件人的列表。它将在发送过程中使用此收件人列表来查找所需的替换。
使用Decorator插件
要使用Decorator插件,只需根据电子邮件地址创建一个替换的关联数组,然后使用邮件发送器的替换数组registerPlugin ()
方法添加插件。
首先,根据要发送邮件的电子邮件地址创建一个替换的关联数组。
请注意
替换数组变成一个二维数组,键是电子邮件地址,值是该电子邮件地址替换的关联数组。本例中使用的花括号可以是你选择的任何类型的语法,只要它们与电子邮件模板中的占位符匹配:
1 2 3 4 5 6 7
$更换= [];foreach($用户作为$用户){$更换[$用户[“电子邮件”]] = [“{username}”= >$用户[“用户名”),“{resetcode}”= >$用户[“resetcode”]];}
现在使用这个替换数组创建Decorator插件实例,然后将其注册到Mailer中。只做一次!
1 2 3
$装饰=新Swift_Plugins_DecoratorPlugin ($更换);$梅勒->registerPlugin ($装饰);
当你创建你的消息时,用占位符替换正文(和/或主题行)中的元素:
1 2 3 4 5 6 7 8 9 10 11
$消息= (新Swift_Message ())->setSubject (“关于{username}的重要通知”)->setBody (你好{用户名},您要求重置密码。\n.“请访问https://example.com/pwreset并使用重置代码{resetcode}设置新密码。”) ;foreach($用户作为$用户){$消息->遭受($用户[“电子邮件”]);}
当您将此消息发送给您的邮箱中列出的每个收件人时美元替代品
数组,他们将收到一条为自己定制的消息。例如,上面使用的消息在收到时可能会对一个用户显示如下:
1 2 3 4
主题:smilingsunshine2009重要通知你好smilingsunshine2009,你要求重置你的密码。请访问https://example.com/pwreset并使用重置代码183457设置新密码。
而另一种用法可能会收到这样的信息:
1 2 3 4
主题:比利-鲍勃的重要通知你好比利-鲍勃,你要求重置你的密码。请访问https://example.com/pwreset并使用重置码539127设置新密码。
虽然decorator插件提供了一种解决这个问题的方法,但是有很多方法可以在不需要插件的情况下解决这个问题。我们正在努力想出一个更好的方法,虽然我们有几个(明显的)想法,但我们还没有一个完美的解决方案来继续执行它。注意这个空间。
为装饰器提供自己的替换查找
用替换填充数组可能不是向装饰器提供替换信息的最佳解决方案。如果您有一个更优雅的算法,可以实时执行替换查找,那么您可以提供自己的实现。
为Decorator提供您自己的替换查找实现,只需传递一个实例Swift_Plugins_Decorator_Replacements
传递给decorator插件的构造函数,而不是传入一个数组。
替换接口的实现非常简单,因为它只有一个方法:getReplacementsFor(地址)
.
假设您想要动态地从数据库中查找替换项,您可以提供这样的实现。你需要创建一个小类:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
类DbReplacements实现了Swift_Plugins_Decorator_Replacements{公共函数getReplacementsFor($地址){全球$db;//连接到数据库的PDO实例$查询=$db->准备("SELECT * FROM ' users ' WHERE ' email ' = ?");$查询->执行([$地址]);如果($行=$查询->fetch (PDO::FETCH_ASSOC)) {返回[“{username}”= >$行[“用户名”),“{resetcode}”= >$行[“resetcode”]];}}}
现在你所需要做的就是将你的类的实例传递到Decorator插件的构造函数中,而不是传递一个数组:
1 2 3
$装饰=新Swift_Plugins_DecoratorPlugin (新DbReplacements ());$梅勒->registerPlugin ($装饰);
对于发送的每条消息,插件都会调用你的类getReplacementsFor ()
方法来查找所需的替换数组。
请注意
如果查找算法区分大小写,则应该转换美元的地址
参数,例如通过传入函数()
.