如何在开发过程中处理邮件

3.4 版本
维护中的版本

当开发一个包含了邮件发送的程序时,你总是不希望在开发时真的把邮件发到一个指定接收者那里。如果你使用Symfony的SwiftmailerBundle ,即可通过设定配置文件来实现,而毋须对程序代码做任何改动。在开发中处理邮件问题时有两个主要选项:(a) 彻底关闭邮件发送,或 (b) 把发送邮件到一个特殊地址(带有可选的异常)。

关闭发送 

通过把 disable_delivery 选项设置为 true,你可以关闭邮件发送。这是标准版框架中 test 环境的默认设置。如果你在指定的 test 配置文件中这样做了,那么邮件将不会在你测试时发送,但会在 proddev 环境下被继续发送:

1
2
3
# app/config/config_test.yml
swiftmailer:
    disable_delivery:  true
1
2
3
4
5
6
7
8
9
10
<!-- app/config/config_test.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 disable-delivery="true" />
</container>
1
2
3
4
// app/config/config_test.php
$container->loadFromExtension('swiftmailer', array(
    'disable_delivery'  => "true",
));

如果你也想在 dev 环境下关闭发送,直接向 config_dev.yml 文件中添加相同的配置内容。

发送到指定的地址(集) 

你还可以选择将所有邮件发向一个指定地址或地址列表,而不是信息真实发送的地址。这可以通过 delivery_addresses 选项来完成:

1
2
3
# app/config/config_dev.yml
swiftmailer:
    delivery_addresses: ['dev@example.com']
1
2
3
4
5
6
7
8
9
10
11
12
<!-- app/config/config_dev.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:delivery-address>dev@example.com</swiftmailer:delivery-address>
    </swiftmailer:config>
</container>
1
2
3
4
// app/config/config_dev.php
$container->loadFromExtension('swiftmailer', array(
    'delivery_addresses' => array("dev@example.com"),
));

Now, suppose you're sending an email to recipient@example.com.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function indexAction($name)
{
    $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('send@example.com')
        ->setTo('recipient@example.com')
        ->setBody(
            $this->renderView(
                'HelloBundle:Hello:email.txt.twig',
                array('name' => $name)
            )
        )
    ;
    $this->get('mailer')->send($message);
 
    return $this->render(...);

dev 环境下,邮件会发送到 dev@example.com。Swift Mailer将向邮件添加一个特别的头信息 X-Swift-To,包含有被替换的地址,因此你仍然可以看此邮件将会发给谁。

除了 to 地址外,这也会把发往设置好的 CCBCC 地址的任何邮件一并停止。Swift Mailer将向邮件中添加“附加头”来容纳被覆写的地址。对于 CCBCC 地址,分别是 X-Swift-CcX-Swift-Bcc

发送到一个特殊地址并附带异常 

假设你要把全部邮件重定向到一个指定地址 (就像上例中的 dev@example.com)。但是之后你可能希望邮件被遍历地发往多个指定地址,而不再被重定向(哪怕是在dev环境下)。这可以通过添加 delivery_whitelist 选项来实现:

1
2
3
4
5
6
7
8
9
# app/config/config_dev.yml
swiftmailer:
    delivery_addresses: ['dev@example.com']
    delivery_whitelist:
       # all email addresses matching these regexes will be delivered
       # like normal, as well as being sent to dev@example.com
       # 匹配以下正则的地址将被正常发送,但也会被发送到dev@example.com
       - '/@specialdomain\.com$/'
       - '/^admin@mydomain\.com$/'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- app/config/config_dev.xml -->
 
<?xml version="1.0" charset="UTF-8" ?>
<?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>
        <!-- all email addresses matching these regexes will be delivered
             like normal, as well as being sent to dev@example.com -->
        <swiftmailer:delivery-whitelist-pattern>/@specialdomain\.com$/</swiftmailer:delivery-whitelist-pattern>
        <swiftmailer:delivery-whitelist-pattern>/^admin@mydomain\.com$/</swiftmailer:delivery-whitelist-pattern>
        <swiftmailer:delivery-address>dev@example.com</swiftmailer:delivery-address>
    </swiftmailer:config>
</container>
1
2
3
4
5
6
7
8
9
10
// app/config/config_dev.php
$container->loadFromExtension('swiftmailer', array(
    'delivery_addresses'  => array("dev@example.com"),
    'delivery_whitelist' => array(
        // all email addresses matching these regexes will be delivered
        // like normal, as well as being sent to dev@example.com
        '/@specialdomain\.com$/',
        '/^admin@mydomain\.com$/',
    ),
));

上例中所有的邮件信息都会被重定向到 dev@example.com,而那些发往 admin@mydomain.com 地址的信息,或者任何一个邮件地址属于 specialdomain.com 的信息,将被正常发送出去。

在web工具条中查看 

当处于 dev 环境时,使用web debug toolbar可以查看“某个单一响应”过程中被发送出的邮件。条子的email小图标将显示有多少封信被发出。如果你点击它,会打开发送报告,显示了发送的邮件之细节。

这时,你应该在 config_dev.yml 文件中设置 intercept_redirects 选项为 true,这将会终止重定向,并允许你打开“已发邮件”的详情报告页。

1
2
3
# app/config/config_dev.yml
web_profiler:
    intercept_redirects: true
1
2
3
4
5
6
7
8
9
10
11
<!-- app/config/config_dev.xml -->
 
<!--
    xmlns:webprofiler="http://symfony.com/schema/dic/webprofiler"
    xsi:schemaLocation="http://symfony.com/schema/dic/webprofiler
    http://symfony.com/schema/dic/webprofiler/webprofiler-1.0.xsd">
-->
 
<webprofiler:config
    intercept-redirects="true"
/>
1
2
3
4
// app/config/config_dev.php
$container->loadFromExtension('web_profiler', array(
    'intercept_redirects' => 'true',
));

可选地,你可以在重定向之后开启分析器(profiler),并根据“用在之前的请求(如 /contact/handle)”中的已提交URL进行检索。分析器的检索功能允许你针对任意过往请求来加载分析信息。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)