第十一章-电子邮件
的使用使symfony发送电子邮件变得简ob娱乐下载单而强大斯威夫特梅勒图书馆。虽然Swift Mailer使发送电子邮件变得简单,但symfony在其之上提供了一个薄的包装器,ob娱乐下载使发送电子邮件更加灵活和强大。这一章将教你如何将所有的力量置于自己的支配之下。
请注意
ob娱乐下载symfony 1.3嵌入了Swift Mailer 4.1版本。
简介
symfony中的电子邮件管理以邮件对象ob娱乐下载为中心。与许多其他核心symfony对象一样,mailerob娱乐下载也是一个工厂。配置factories.yml
配置文件,并始终可通过上下文实例:
梅勒美元= sfContext::getInstance()->getMailer();
提示
与其他工厂不同的是,mailer是按需加载和初始化的。如果您不使用它,则不会对性能产生任何影响。
本教程解释了symfony中的Swift Mailer集成。ob娱乐下载如果您想了解Swift Mailer库本身的基本细节,请参阅其专用的欧宝官网下载app.
从动作发送电子邮件
类使从操作中检索邮件实例变得简单getMailer ()
快捷方法:
梅勒美元=这个美元->getMailer();
最快的方法
发送电子邮件就像使用sfAction: composeAndSend ()
方法:
这个美元->getMailer()->composeAndSend(“from@example.com”,“fabien@example.com”,“主题”,“身体”);
的composeAndSend ()
方法有四个参数:
- 发件人电邮地址(
从
); - 收件人电邮地址(
来
); - 信息的主题;
- 消息的主体。
当一个方法接受一个电子邮件地址作为参数时,你可以传递一个字符串或数组:
美元的地址=“fabien@example.com”;美元的地址=数组(“fabien@example.com”= >“法比效力”);
当然,你可以通过传递一个电子邮件数组作为方法的第二个参数,一次发送电子邮件给几个人:
美元,=数组(“foo@example.com”,“bar@example.com”,);这个美元->getMailer()->composeAndSend(“from@example.com”,美元,,“主题”,“身体”);美元,=数组(“foo@example.com”= >“Foo”先生,“bar@example.com”= >“酒吧小姐”,);这个美元->getMailer()->composeAndSend(“from@example.com”,美元,,“主题”,“身体”);
灵活的方式
如果需要更大的灵活性,还可以使用sfAction:组成()
方法来创建消息、按所需方式自定义消息并最终发送消息。这很有用,例如,当你需要添加如下所示的附件时:
//创建一个消息对象美元的消息=这个美元->getMailer()->组成(“from@example.com”,“fabien@example.com”,“主题”,“身体”)->附加(Swift_Attachment::fromPath(“/道路/ / / file.zip”));//发送消息这个美元->getMailer()->发送(美元的消息);
强大的方式
您也可以直接创建一个消息对象,以获得更大的灵活性:
美元的消息= Swift_Message::newInstance()->setFrom(“from@example.com”)->该太空站(“to@example.com”)->setSubject(“主题”)->setBody(“身体”)->附加(Swift_Attachment::fromPath(“/道路/ / / file.zip”));这个美元->getMailer()->发送(美元的消息);
使用Symfony视ob娱乐下载图
从你的动作中发送电子邮件可以让你很容易地利用部分和组件的力量。
美元的消息->setBody(这个美元->getPartial(“partial_name”,美元的参数));
配置
与任何其他symfony工ob娱乐下载厂一样,可以在factories.yml
配置文件。缺省配置如下:
mailer: class: sfMailer param: logging: %SF_LOGGING_ENABLED% charset: %SF_CHARSET% delivery_strategy: realtime transport: class: Swift_SmtpTransport param: host: localhost port: 25 encryption: ~ username: ~ password: ~
当创建一个新的应用程序时,本地factories.yml
属性的一些合理的默认值将覆盖默认配置刺激
,env
,测验
环境:
Test: mailer: param: delivery_strategy:无dev: mailer: param: delivery_strategy:无
交付策略
symfony中Swift Mailer集成的最有用的特性之一是交付策略。ob娱乐下载传递策略允许您告诉symfony如何传递电子邮件消息,并通过ob娱乐下载delivery_strategy
设置factories.yml
.这一策略改变了send ()
|sfMailer:发送()
方法的行为。默认情况下有四种策略可用,它们应该适合所有常见需求:
实时
:实时发送消息。single_address
:消息发送到单个地址。线轴
:消息存储在队列中。没有一个
:消息被简单地忽略。
的实时
策略
的实时
Strategy是默认的交付策略,也是最容易设置的,因为没有什么特别的事情要做。
类中配置的传输方式发送电子邮件运输
部份factories.yml
配置文件(有关如何配置邮件传输的详细信息,请参阅下一节)。
的single_address
策略
与single_address
策略,将所有消息发送到单个地址,该地址通过delivery_address
设置。
这种策略在开发环境中非常有用,可以避免向实际用户发送消息,但仍然允许开发人员在电子邮件阅读器中检查呈现的消息。
提示
如果您需要验证原件来
,cc
,bcc
收件人,它们可以作为以下头文件的值:X-Swift-To
,X-Swift-Cc
,X-Swift-Bcc
分别。
电子邮件消息通过与用于实时
策略。
的线轴
策略
与线轴
策略,消息存储在队列中。
这是生产环境的最佳策略,因为web请求不会等待电子邮件被发送。
的线轴
类配置spool_class
设置。默认情况下,symfonob娱乐下载y与其中三个绑定:
Swift_FileSpool
:消息存储在文件系统上。Swift_DoctrineSpool
:消息存储在Doctrine模型中。Swift_PropelSpool
:消息存储在一个Propel模型中。
实例化阀芯时,spool_arguments
设置用作构造函数参数。下面是内置队列类可用的选项:
Swift_FileSpool
:- 队列目录的绝对路径(消息存储在此目录中)
Swift_DoctrineSpool
:用于存储消息的Doctrine模型(
MailMessage
默认情况下)用于消息存储的列名(
消息
默认情况下)要调用的方法以检索要发送的消息(可选)。它接收队列选项作为参数。
Swift_PropelSpool
:用于存储消息的Propel模型(
MailMessage
默认情况下)用于消息存储的列名(
消息
默认情况下)要调用的方法以检索要发送的消息(可选)。它接收队列选项作为参数。
以下是Doctrine线轴的经典配置:
#模式配置。yml MailMessage: actAs: {timestamp: ~} columns: message: {type: clob, notull: true}
#工厂配置。yml mailer: class: sfMailer param: delivery_strategy: spool spool_class: Swift_DoctrineSpool spool_arguments: [MailMessage, message, getSpooledMessages]
同样的配置为驱动阀芯:
#模式配置。Yml mail_message: message:{类型:clob, required: true} created_at: ~
#工厂配置。yml dev: mailer: param: delivery_strategy: spool spool_class: Swift_PropelSpool spool_arguments: [MailMessage, message, getSpooledMessages]
要发送存储在队列中的消息,可以使用项目:发送电子邮件
任务(注意,这个任务完全独立于队列实现和它所接受的选项):
PHP syob娱乐下载mfony项目:发送电子邮件
请注意
的项目:发送电子邮件
任务需要一个应用程序
而且env
选项。
当致电项目:发送电子邮件
任务时,电子邮件消息通过与用于实时
策略。
提示
注意项目:发送电子邮件
Task可以在任何机器上运行,而不一定在创建消息的机器上运行。它之所以有效,是因为所有内容都存储在消息对象中,甚至包括文件附件。
请注意
队列的内置实现非常简单。它们发送电子邮件时没有任何错误管理,就像您使用实时
策略。当然,可以扩展缺省队列类来实现您自己的逻辑和错误管理。
的项目:发送电子邮件
Task有两个可选选项:
message-limit
:限制发送消息的数量。时限
:限制发送消息的时间(以秒为单位)。
这两个选项可以组合:
$ PHP ob娱乐下载symfony项目:send-email——message-limit=10——time-limit=20
上面的命令将在发送10条消息或发送20秒后停止发送消息。
即使在使用线轴
策略,您可能需要立即发送消息,而不将其存储在队列中。这是可以通过使用特殊sendNextImmediately ()
邮寄方式:
这个美元->getMailer()->sendNextImmediately()->发送(美元的消息);
在前面的示例中,美元的消息
不会存储在队列中,而是立即发送。顾名思义,是sendNextImmediately ()
方法只影响要发送的下一个消息。
请注意
的sendNextImmediately ()
当交付策略没有特殊效果时,方法没有特殊效果线轴
.
的没有一个
策略
此策略在开发环境中非常有用,可以避免将电子邮件发送给实际用户。消息在web调试工具栏中仍然可用(关于web调试工具栏的邮件器面板的更多信息在下一节中)。
它也是测试环境的最佳策略,在测试环境中sfTesterMailer
对象允许您自省消息,而不需要实际发送它们(关于测试的更多信息在下面的部分中)。
邮件运输
邮件消息实际上是由传输器发送的。中的传输配置factories.yml
配置文件,默认配置使用本机的SMTP服务器:
transport: class: Swift_SmtpTransport param: host: localhost port: 25 encryption: ~ username: ~ password: ~
Swift Mailer捆绑了三种不同的传输类:
Swift_SmtpTransport
:通过SMTP服务器发送消息。Swift_SendmailTransport
:使用sendmail
发送信息。Swift_MailTransport
:使用原生PHP邮件()
发送消息的功能。
提示
的“运输类型”Swift Mailer官方文档的部分描述了所有您需要了解的关于内置传输类欧宝官网下载app及其不同参数的信息。
从任务发送电子邮件
从任务发送电子邮件与从操作发送电子邮件非常相似,因为任务系统还提供getMailer ()
方法。
在创建邮件程序时,任务系统依赖于当前配置。因此,如果希望使用来自特定应用程序的配置,则必须接受——应用程序
选项(有关此主题的更多信息,请参阅任务章节)。
注意,该任务使用与控制器相同的配置。所以,如果你想强制交付的时候线轴
策略就是利用,利用sendNextImmediately ()
:
这个美元->getMailer()->sendNextImmediately()->发送(美元的消息);
调试
传统上,调试电子邮件是一场噩梦。使用symob娱乐下载fony,非常简单,这要感谢web调试工具栏。
从舒适的浏览器,你可以很容易和快速地看到有多少消息已经被当前动作发送:
如果单击电子邮件图标,发送的邮件将以原始形式显示在面板中,如下所示。
请注意
每次发送电子邮件时,symfony还会在日志中添加一条消ob娱乐下载息。
测试
当然,如果没有测试邮件消息的方法,集成就不可能完成。默认情况下,symfonob娱乐下载y注册一个梅勒
测试人员(sfMailerTester
)以简化功能测试中的邮件测试。
的hasSent ()
方法测试当前请求期间发送的消息数:
美元的浏览器->得到(' / foo ')->与(“梅勒”)->hasSent(1);
前面的代码检查/ foo
URL只发送一封电子邮件。
的帮助下,每一封发送的电子邮件都可以进一步测试checkHeader ()
而且checkBody ()
方法:
美元的浏览器->得到(' / foo ')->与(“梅勒”)->开始()->hasSent(1)->checkHeader(“主题”,“/主题/”)->checkBody(“身体/”)->结束();
第二个论点checkHeader ()
的第一个参数checkBody ()
可以是以下之一:
用于检查精确匹配的字符串;
一个正则表达式来检查它的值;
负正则表达式(以A开始的正则表达式)
!
),以检查该值是否匹配。
默认情况下,对发送的第一条消息进行检查。方法,选择要测试的消息withMessage ()
方法:
美元的浏览器->得到(' / foo ')->与(“梅勒”)->开始()->hasSent(2)->withMessage(“foo@example.com”)->checkHeader(“主题”,“/主题/”)->checkBody(“身体/”)->结束();
的withMessage ()
以接收者作为第一个参数。它还使用第二个参数来指示您希望测试哪个消息,如果多个消息已发送给同一个收件人。
最后但并非最不重要的是调试()
方法在测试失败时转储发送的消息以发现问题:
美元的浏览器->得到(' / foo ')->与(“梅勒”)->调试();
电子邮件作为类
在本章的介绍中,你已经学习了如何通过一个动作发送电子邮件。这可能是在symfony应用程序中发送电子邮件的最简单方法,并且可能是当您只需要发送一些简单消息时的最佳方ob娱乐下载法。
但是当您的应用程序需要管理大量不同的电子邮件消息时,您可能应该采用不同的策略。
请注意
作为额外的好处,为电子邮件消息使用类意味着相同的电子邮件消息可以在不同的应用程序中使用;比如前端和后端。
由于消息是纯PHP对象,组织消息的明显方法是为每个消息创建一个类:
/ / lib /电子邮件/ ProjectConfirmationMessage.class.php类ProjectConfirmationMessage扩展Swift_Message{公共函数__construct(){父:__construct(“主题”,“身体”);这个美元->setFrom(数组(“app@example.com”= >“我的应用机器人”))->附加(“……”);}}
从动作发送消息,或者从其他任何地方发送消息,这是一个简单的实例化正确的消息类:
这个美元->getMailer()->发送(新ProjectConfirmationMessage());
当然,添加基类来集中共享头文件,例如从
头,或添加一个公共签名可以方便:
/ / lib /电子邮件/ ProjectConfirmationMessage.class.php类ProjectConfirmationMessage扩展ProjectBaseMessage{公共函数__construct(){父:__construct(“主题”,“身体”);//特定的头文件,附件,…这个美元->附加(“……”);}}/ / lib /电子邮件/ ProjectBaseMessage.class.php类ProjectBaseMessage扩展Swift_Message{公共函数__construct(美元的主题,美元的身体){美元的身体.= <<< eof——My App Bot EOF发送的邮件;父:__construct(美元的主题,美元的身体);//设置所有共享头信息这个美元->setFrom(数组(“app@example.com”= >“我的应用机器人”));}}
如果一个消息依赖于一些模型对象,你当然可以把它们作为参数传递给构造函数:
/ / lib /电子邮件/ ProjectConfirmationMessage.class.php类ProjectConfirmationMessage扩展ProjectBaseMessage{公共函数__construct($ user){父:__construct(“确认”.$ user->getName(),“身体”);}}
食谱
通过Gmail发送电子邮件
如果您没有SMTP服务器,但有Gmail帐户,请使用以下配置使用谷歌服务器发送和存档邮件:
传输:类:Swift_SmtpTransport参数:主机:smtp.gmail.com端口:465加密:ssl用户名:your_gmail_username_goes_here密码:your_gmail_password_goes_here
取代用户名
而且密码
带着你的Gmail证书,你就完蛋了。
定制Mailer对象
方法配置邮件发送器factories.yml
还不够,你能听吗mailer.configure
事件,并进一步自定义邮件。
你可以在你的ProjectConfiguration
类如下所示:
类ProjectConfiguration扩展sfProjectConfiguration{公共函数设置(){/ /……这个美元->调度程序->连接(“mailer.configure”,数组(这个美元,“configureMailer”));}公共函数configureMailer(sfEvent美元的事件){梅勒美元=美元的事件->getSubject();//处理邮件}}
下面一节将说明这种技术的强大用法。
使用Swift Mailer插件
要使用Swift Mailer插件,请收听mailer.configure
事件(请参阅上面的部分):
公共函数configureMailer(sfEvent美元的事件){梅勒美元=美元的事件->getSubject();美元的插件=新Swift_Plugins_ThrottlerPlugin(One hundred., Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE);梅勒美元->registerPlugin(美元的插件);}
提示
的“插件”Swift Mailer官方文档的部分描述了所有您需要了解的内置插件。欧宝官网下载app
自定义线轴行为
这些线轴的内置实现非常简单。每个spool以随机顺序从队列中检索所有电子邮件并发送它们。
您可以配置一个线轴来限制发送电子邮件所花费的时间(以秒为单位),或限制要发送的消息数量:
美元的线轴=梅勒美元->getSpool();美元的线轴->setMessageLimit(10);美元的线轴->setTimeLimit(10);
在本节中,您将学习如何为队列实现优先级系统。它将为您提供实现您自己的逻辑所需的所有信息。
首先,添加一个优先级
列到模式:
# for Propel mail_message: message: {type: clob, required: true} created_at: ~ priority: {type: integer, default: 3} # for Doctrine MailMessage: actAs: {timestamp: ~} columns: message: {type: clob, notnull: true} priority: {type: integer}
发送邮件时,设置优先级头(1表示最高):
美元的消息=这个美元->getMailer()->组成(“john@doe.com”,“foo@example.com”,“主题”,“身体”)->setPriority(1);这个美元->getMailer()->发送(美元的消息);
然后,重写默认值setMessage ()
属性的优先级MailMessage
对象本身:
//用于驱动类MailMessage扩展BaseMailMessage{公共函数setMessage(美元的消息){美元味精=非系列化(美元的消息);这个美元->setPriority(美元味精->getPriority());父::setMessage(美元的消息);}}// for Doctrine类MailMessage扩展BaseMailMessage{公共函数setMessage(美元的消息){美元味精=非系列化(美元的消息);这个美元->优先级=美元味精->getPriority();这个美元- > _set(“消息”,美元的消息);}}
请注意,消息是由队列序列化的,因此在获得优先级值之前必须对其进行反序列化。现在,创建一个按优先级对消息进行排序的方法:
//用于驱动类MailMessagePeer扩展BaseMailMessagePeer{静态公共函数getSpooledMessages(标准美元标准){美元标准->addAscendingOrderByColumn(自我::优先级);返回自我::doSelect(美元标准);}/ /……}// for Doctrine类MailMessageTable扩展Doctrine_Table{公共函数getSpooledMessages(){返回这个美元->createQuery(“米”)->orderBy(“m.priority”);}/ /……}
类中定义检索方法是最后一步factories.yml
配置以更改从队列中获取消息的默认方式:
spool_arguments: [MailMessage, message, getSpooledMessages]
这就是它的全部。现在,每次你运行项目:发送电子邮件
任务,每个电子邮件将根据其优先级发送。
侧边栏
自定义阀芯与任何标准
前面的示例使用了一个标准消息头,即优先级。但是,如果您想使用任何条件,或者不想更改已发送的消息,还可以将条件存储为自定义标头,并在发送电子邮件之前删除它。
首先,在要发送的消息中添加一个自定义头:
公共函数executeIndex(){美元的消息=这个美元->getMailer()->组成(“john@doe.com”,“foo@example.com”,“主题”,“身体”);美元的消息->getHeaders()->addTextHeader(“X-Queue-Criteria”,“foo”);这个美元->getMailer()->发送(美元的消息);}
然后,在队列中存储消息时,从这个头中检索值,并立即删除它:
公共函数setMessage(美元的消息){美元味精=非系列化(美元的消息);美元的头=美元味精->getHeaders();美元标准=美元的头->得到(“X-Queue-Criteria”)->getFieldBody();这个美元->setCriteria(美元标准);美元的头->删除(“X-Queue-Criteria”);父::setMessage(美元的消息);}
本作品在GFDL许可下获得许可。