返回首页 Symfony2 Cookbook

Assetic

Bundles

缓存

Composer

配置

控制台

Controller

调试

部署

Doctrine

电子邮件

事件分发器

表达式

表单

前端

日志

分析器

请求

路由

安全

序列化

服务容器

会话

PSR-7

Symfony 版本

模板

测试

升级

验证

Web 服务器

Web 服务

工作流

如何缓存电子邮件

当您正在从 Symfony 应用程序中使用 SwiftmailerBundle 发送一封电子邮件,默认情况下会立刻发送该邮件。然而您可能想避免 Swift Mailer 与电子邮件传送之间的性能影响,可能导致用户在邮件发送的过程中等待下一页面加载。这可以通过选择“缓存”电子邮件而不是直接发送来避免、这意味着 Swift Mailer 并不试图发送一封电子邮件,而是将邮件保存在某处,如一个文件。另一个进程可以在缓存中读取并且在缓存中处理发送电子邮件。现在 Swift Mailer 只支持缓存到文件或者内存中。

使用内存缓存

当您使用缓存来存储电子邮件到内存时,它们会在内核终止前立即发送。这意味着如果整个请求在没有任何异常情况或错误下执行的话,电子邮件才会被发送。要用内存选项配置 swiftmailer,使用以下配置:

YAML:

# app/config/config.yml
swiftmailer:
    # ...
    spool: { type: memory }

XML:

<!-- app/config/config.xml -->

<!--
    xmlns:swiftmailer="http://symfony.com/schema/dic/swiftmailer"
    http://symfony.com/schema/dic/swiftmailer
    http://symfony.com/schema/dic/swiftmailer/swiftmailer-1.0.xsd
-->

<swiftmailer:config>
     <swiftmailer:spool type="memory" />
</swiftmailer:config>

PHP:

// app/config/config.php
$container->loadFromExtension('swiftmailer', array(
     // ...
    'spool' => array('type' => 'memory')
));

使用文件缓存

YAML:

# app/config/config.yml
swiftmailer:
    # ...
    spool:
        type: file
        path: /path/to/spool

XML:

<!-- app/config/config.xml -->

<!--
    xmlns:swiftmailer="http://symfony.com/schema/dic/swiftmailer"
    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/spool" />
</swiftmailer:config>

PHP:

// app/config/config.php
$container->loadFromExtension('swiftmailer', array(
     // ...

    'spool' => array(
        'type' => 'file',
        'path' => '/path/to/spool',
    ),
));

如果您想用项目目录缓存到某个地方,记住您可以使用 %kernel.root_dir% 参数来引用项目的根:

path: "%kernel.root_dir%/spool"

现在,当您的应用程序发送一封电子邮件的时候,它不会实际被发送,而是添加到缓存。从缓存中发送消息是分开完成的。在缓存中有一个控制台命令来发送消息:

$ php app/console swiftmailer:spool:send --env=prod

有一个选项来限制发送的消息数:

$ php app/console swiftmailer:spool:send --message-limit=10 --env=prod

您也可以设置时间,限制到秒:

$ php app/console swiftmailer:spool:send --time-limit=10 --env=prod

当然您在现实中不想手动运行这个。相反,控制台命令应该由一个 cron 作业或计划任务激发并且在固定的间隔运行。