支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
当你在Symfony程序中使用SwiftmailerBundle发送邮件时,默认是邮件立即被发出。你可能希望,避免“Swift Mailer与邮件传输”之间的性能冲击,因为在邮件送出时会引发用户等待而难于加载下一个页面。要避免这个可以选择“spool”(滚动)邮件而不是直接发送它们。这意味着Swift Mailer并不试图发出邮件而是把相关信息存到某处,比如一个文件中。另外的进程会从spool中读取(那些信息)并且解决滚动发送的问题。目前,Swift Mailer仅支持(把邮件信息)spool(存入)到文件或内存。
当你使用spooling把邮件存入内存时,它们会在kernel结束时被立即发送。这表明,邮件只在“完整的请求被执行,且没有任何未处置的异常或没有任何错误”的时候才被发送。要在swiftmailer中对内存选项进行配置,使用以下内容:
1 2 3 4 | # app/config/config.yml
swiftmailer:
# ...
spool: { type: memory } |
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:swiftmailer="http://symfony.com/schema/dic/swiftmailer"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/swiftmailer http://symfony.com/schema/dic/swiftmailer/swiftmailer-1.0.xsd">
<swiftmailer:config>
<swiftmailer:spool type="memory" />
</swiftmailer:config>
</container> |
当你对spooling使用文件系统时,Symfony会在给定的目录下为每一个邮件服务(如,默认的邮件服务就是“default”)创建一个文件夹。这个文件夹内含滚动轴(spool)上面每一封邮件所对应的文件。因此要确保目录可被Symfony(或你的webserver/php)写入!
为了使用文件方式的滚动,使用下列配置:
1 2 3 4 5 6 | # app/config/config.yml
swiftmailer:
# ...
spool:
type: file
path: /path/to/spooldir |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:swiftmailer="http://symfony.com/schema/dic/swiftmailer"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/swiftmailer http://symfony.com/schema/dic/swiftmailer/swiftmailer-1.0.xsd">
<swiftmailer:config>
<swiftmailer:spool
type="file"
path="/path/to/spooldir"
/>
</swiftmailer:config>
</container> |
如果你希望把滚动信息存放于项目中的其他某个目录,记得要使用 %kernel.root_dir%
参数来引用项目根目录:
1 | path: '%kernel.root_dir%/spool' |
现在,当你的程序发送邮件时,并不真正发送,而是添加到spool中。从滚动轴发送信息是单独完成的。有一个命令用于发送spool信息:
1 | $ php bin/console swiftmailer:spool:send --env=prod |
有一个选项用来限制被发送信息的数量:
1 | $ php bin/console swiftmailer:spool:send --message-limit=10 --env=prod |
你也可以对时间秒数进行限制:
1 | $ php bin/console swiftmailer:spool:send --time-limit=10 --env=prod |
在现实中,你当然不希望手动完成这些。命令行应当被一个cron job,或是由一个运行于规律间隔的计划任务来触发。
当你使用SwiftMailer来创建信息时,它会生成一个 Swift_Message
类。如果 swiftmailer
服务是lazy loaded的,它会生成另一个名为 Swift_Message_<someRandomCharacters>
的代理类(proxy class)。
如果你使用memory spool,这种改变是透明的并且没有任何性能损失。但在使用filesystem spool时,message class将在一个文件中以一个随机类名被序列化。问题就在于这个随机的类名在每次清理缓存时会发生改变。因此,如果你发送邮件之后就清除缓存,邮件信息将无法被反序列化。
在下一次的 swiftmailer:spool:send
执行过程中会报错,因为 Swift_Message_<someRandomCharacters>
类不(再)存在。
解决方案可以是 memory spool 或者加载 swiftmailer
服务时不使用 lazy
选项 (见 Lazy Services)。
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。