Sending Emails with Mailer

Installation

Symfony's Mailer & Mime components form a powerful system for creating and sending emails - complete with support for multipart messages, Twig integration, CSS inlining, file attachments and a lot more. Get them installed with:

1
$ composer require symfony/mailer

Transport Setup

Emails are delivered via a "transport". Out of the box, you can deliver emails over SMTP by configuring the DSN in your .env file (the user, pass and port parameters are optional):

メールは「トランスポート」経由で配信されます。すぐに使用できるように、.env ファイルで DSN を構成することにより、SMTP 経由でメールを配信できます (ユーザー、パス、およびポートのパラメーターはオプションです)。
1
2
# .env
MAILER_DSN=smtp://user:pass@smtp.example.com:port
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/mailer.yaml
framework:
    mailer:
        dsn: '%env(MAILER_DSN)%'

Caution

注意

If the username, password or host contain any character considered special in a URI (such as +, @, $, #, /, :, *, !), you must encode them. See RFC 3986 for the full list of reserved characters or use the urlencode function to encode them.

ユーザー名、パスワード、またはホストに、URI で特殊と見なされる文字 (+、@、$、#、/、:、*、! など) が含まれている場合は、それらをエンコードする必要があります。予約文字の完全なリストについては、RFC 3986 を参照するか、urlencode 関数を使用してそれらをエンコードします。

Using Built-in Transports

DSN protocol Example Description
smtp smtp://user:pass@smtp.example.com:25 Mailer uses an SMTP server to send emails
sendmail sendmail://default Mailer uses the local sendmail binary to send emails
native native://default Mailer uses the sendmail binary and options configured in the sendmail_path setting of php.ini. On Windows hosts, Mailer fallbacks to smtp and smtp_port php.ini settings when sendmail_path is not configured.

Caution

注意

When using native://default, if php.ini uses the sendmail -t command, you won't have error reporting and Bcc headers won't be removed. It's highly recommended to NOT use native://default as you cannot control how sendmail is configured (prefer using sendmail://default if possible).

native://default を使用する場合、php.ini で sendmail -t コマンドを使用すると、エラー レポートが表示されず、Bcc ヘッダーが削除されません。sendmail を制御できないため、native://default を使用しないことを強くお勧めします。設定されています (可能であれば、sendmail://default を使用することをお勧めします)。

Using a 3rd Party Transport

Instead of using your own SMTP server or sendmail binary, you can send emails via a third-party provider:

独自の SMTP サーバーまたは sendmail バイナリを使用する代わりに、サードパーティ プロバイダー経由でメールを送信できます。
Service Install with
Amazon SES composer require symfony/amazon-mailer
MailChimp composer require symfony/mailchimp-mailer
Mailgun composer require symfony/mailgun-mailer
Mailjet composer require symfony/mailjet-mailer
Postmark composer require symfony/postmark-mailer
SendGrid composer require symfony/sendgrid-mailer
Sendinblue composer require symfony/sendinblue-mailer
MailPace composer require symfony/mailpace-mailer
Infobip composer require symfony/infobip-mailer

6.2

6.2

The Infobip integration was introduced in Symfony 6.2 and the MailPace integration was renamed in Symfony 6.2 (in previous Symfony versions it was called OhMySMTP).

Infobip 統合は Symfony 6.2 で導入され、MailPace 統合は Symfony 6.2 で名前が変更されました (以前の Symfony バージョンでは OhMySMTP と呼ばれていました)。

Note

ノート

As a convenience, Symfony also provides support for Gmail (composer require symfony/google-mailer), but this should not be used in production. In development, you should probably use an email catcher instead. Note that most supported providers also offer a free tier.

便宜上、Symfony は Gmail のサポートも提供します (composerrequire symfony/google-mailer) が、これは本番環境では使用しないでください。開発中は、代わりにメール キャッチャーを使用する必要があります。サポートされているプロバイダーのほとんどは無料枠も提供していることに注意してください。

Each library includes a Symfony Flex recipe that will add a configuration example to your .env file. For example, suppose you want to use SendGrid. First, install it:

各ライブラリには、設定例を .env ファイルに追加する Symfony Flex レシピが含まれています。たとえば、SendGrid を使用するとします。まず、インストールします。
1
$ composer require symfony/sendgrid-mailer

You'll now have a new line in your .env file that you can uncomment:

これで、コメントを解除できる .env ファイルに新しい行が追加されました。
1
2
# .env
MAILER_DSN=sendgrid://KEY@default

The MAILER_DSN isn't a real address: it's a convenient format that offloads most of the configuration work to mailer. The sendgrid scheme activates the SendGrid provider that you just installed, which knows all about how to deliver messages via SendGrid. The only part you need to change is the KEY placeholder.

MAILER_DSN は実際のアドレスではありません。構成作業のほとんどをメーラーに任せる便利な形式です。 sendgrid スキームは、SendGrid 経由でメッセージを配信する方法をすべて知っている、インストールしたばかりの SendGrid プロバイダーをアクティブにします。変更する必要があるのは、KEY プレースホルダーだけです。

Each provider has different environment variables that the Mailer uses to configure the actual protocol, address and authentication for delivery. Some also have options that can be configured with query parameters at the end of the MAILER_DSN - like ?region= for Amazon SES or Mailgun. Some providers support sending via http, api or smtp. Symfony chooses the best available transport, but you can force to use one:

各プロバイダーには、メーラーが配信用の実際のプロトコル、アドレス、および認証を構成するために使用するさまざまな環境変数があります。 Amazon SES や Mailgun の ?region= のように、MAILER_DSN の最後にあるクエリ パラメータで設定できるオプションがあるものもあります。一部のプロバイダーは、http、api、または smtp 経由の送信をサポートしています。 symfony は利用可能な最適なトランスポートを選択しますが、強制的に使用することもできます:
1
2
3
# .env
# force to use SMTP instead of HTTP (which is the default)
MAILER_DSN=sendgrid+smtp://$SENDGRID_KEY@default

This table shows the full list of available DSN formats for each third party provider:

この表は、各サードパーティ プロバイダーで使用可能な DSN 形式の完全なリストを示しています。

Caution

注意

If your credentials contain special characters, you must URL-encode them. For example, the DSN ses+smtp://ABC1234:abc+12/345@default should be configured as ses+smtp://ABC1234:abc%2B12%2F345@default

資格情報に特殊文字が含まれている場合は、それらを URL エンコードする必要があります。 @デフォルト

Caution

注意

If you want to use the ses+smtp transport together with Messenger to send messages in background, you need to add the ping_threshold parameter to your MAILER_DSN with a value lower than 10: ses+smtp://USERNAME:PASSWORD@default?ping_threshold=9

Messenger と一緒に ses+smtp トランスポートを使用してバックグラウンドでメッセージを送信する場合は、ping_threshold パラメータを 10 未満の値で MAILER_DSN に追加する必要があります: ses+smtp://USERNAME:PASSWORD@default?ping_threshold=9

Note

ノート

When using SMTP, the default timeout for sending a message before throwing an exception is the value defined in the default_socket_timeout PHP.ini option.

SMTP を使用する場合、例外をスローする前にメッセージを送信するためのデフォルトのタイムアウトは、default_socket_timeout PHP.ini オプションで定義された値です。

Note

ノート

To use Google Gmail, you must have a Google Account with 2-Step-Verification (2FA) enabled and you must use App Password to authenticate. Also note that Google revokes your App Passwords when you change your Google Account password and then you need to generate a new one. Using other methods (like XOAUTH2 or the Gmail API) are not supported currently. You should use Gmail for testing purposes only and use a real provider in production.

Google Gmail を使用するには、2 段階認証プロセス (2FA) が有効になっている Google アカウントが必要であり、認証にはアプリ パスワードを使用する必要があります。また、Google アカウントのパスワードを変更すると、Google によってアプリ パスワードが取り消され、新しいパスワードを生成する必要があることにも注意してください。他の方法 (XOAUTH2 や Gmail API など) の使用は現在サポートされていません。Gmail はテスト目的でのみ使用し、実稼働中の実際のプロバイダー。

Tip

ヒント

If you want to override the default host for a provider (to debug an issue using a service like requestbin.com), change default by your host:

プロバイダーのデフォルト ホストをオーバーライドする場合 (requestbin.com などのサービスを使用して問題をデバッグするため)、ホストごとにデフォルトを変更します。
1
2
# .env
MAILER_DSN=mailgun+https://KEY:DOMAIN@requestbin.com

Note that the protocol is always HTTPs and cannot be changed.

プロトコルは常に HTTPS であり、変更できないことに注意してください。

High Availability

Symfony's mailer supports high availability via a technique called "failover" to ensure that emails are sent even if one mailer server fails.

Symfony のメーラーは、「フェイルオーバー」と呼ばれる技術を介して高可用性をサポートし、1 つのメーラー サーバーに障害が発生した場合でもメールが送信されるようにします。

A failover transport is configured with two or more transports and the failover keyword:

フェールオーバー トランスポートは、2 つ以上のトランスポートとfailover キーワードで構成されます。
1
MAILER_DSN="failover(postmark+api://ID@default sendgrid+smtp://KEY@default)"

The failover-transport starts using the first transport and if it fails, it will retry the same delivery with the next transports until one of them succeeds (or until all of them fail).

フェールオーバー トランスポートは最初のトランスポートを使用して開始し、失敗した場合は、次のトランスポートのいずれかが成功するまで (またはすべてが失敗するまで)、次のトランスポートで同じ配信を再試行します。

Load Balancing

Symfony's mailer supports load balancing via a technique called "round-robin" to distribute the mailing workload across multiple transports.

Symfony のメーラーは、「ラウンドロビン」と呼ばれる手法を介して負荷分散をサポートし、複数のトランスポートにメールのワークロードを分散します。

A round-robin transport is configured with two or more transports and the roundrobin keyword:

ラウンド ロビン トランスポートは、2 つ以上のトランスポートと roundrobin キーワードで構成されます。
1
MAILER_DSN="roundrobin(postmark+api://ID@default sendgrid+smtp://KEY@default)"

The round-robin transport starts with a randomly selected transport and then switches to the next available transport for each subsequent email.

ラウンド ロビン トランスポートは、ランダムに選択されたトランスポートから始まり、その後の電子メールごとに次に利用可能なトランスポートに切り替わります。

As with the failover transport, round-robin retries deliveries until a transport succeeds (or all fail). In contrast to the failover transport, it spreads the load across all its transports.

フェールオーバー トランスポートと同様に、ラウンド ロビンはトランスポートが成功する (またはすべて失敗する) まで配信を再試行します。フェールオーバー トランスポートとは対照的に、すべてのトランスポートに負荷を分散します。

TLS Peer Verification

By default, SMTP transports perform TLS peer verification. This behavior is configurable with the verify_peer option. Although it's not recommended to disable this verification for security reasons, it can be useful while developing the application or when using a self-signed certificate:

デフォルトでは、SMTP トランスポートは TLS ピア検証を実行します。この動作は、verify_peer オプションで構成できます。セキュリティ上の理由からこの検証を無効にすることはお勧めしませんが、アプリケーションの開発中または自己署名証明書を使用する場合に役立ちます。
1
$dsn = 'smtp://user:pass@smtp.example.com?verify_peer=0';

Other Options

command

Command to be executed by sendmail transport:

sendmail トランスポートによって実行されるコマンド:
1
$dsn = 'sendmail://default?command=/usr/sbin/sendmail%20-oi%20-t'
local_domain

The domain name to use in HELO command:

HELO コマンドで使用するドメイン名:
1
$dsn = 'smtps://smtp.example.com?local_domain=example.org'
restart_threshold

The maximum number of messages to send before re-starting the transport. It can be used together with restart_threshold_sleep:

トランスポートを再開する前に送信するメッセージの最大数。 restart_threshold_sleep と一緒に使用できます。
1
$dsn = 'smtps://smtp.example.com?restart_threshold=10&restart_threshold_sleep=1'
restart_threshold_sleep

The number of seconds to sleep between stopping and re-starting the transport. It's common to combine it with restart_threshold:

トランスポートの停止と再起動の間にスリープする秒数。restart_threshold と組み合わせるのが一般的です。
1
$dsn = 'smtps://smtp.example.com?restart_threshold=10&restart_threshold_sleep=1'
ping_threshold

The minimum number of seconds between two messages required to ping the server:

サーバーへの ping に必要な 2 つのメッセージ間の最小秒数:
1
$dsn = 'smtps://smtp.example.com?ping_threshold=200'
max_per_second

The number of messages to send per second (0 to disable this limitation):

1 秒あたりに送信するメッセージの数 (この制限を無効にするには 0):
1
$dsn = 'smtps://smtp.example.com?max_per_second=2'

6.2

6.2

The max_per_second option was introduced in Symfony 6.2.

max_per_second オプションは Symfony 6.2 で導入されました。

Creating & Sending Messages

To send an email, get a Mailer instance by type-hinting MailerInterface and create an Email object:

メールを送信するには、タイプヒント MailerInterface で Mailer インスタンスを取得し、 Email オブジェクトを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// src/Controller/MailerController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;

class MailerController extends AbstractController
{
    #[Route('/email')]
    public function sendEmail(MailerInterface $mailer): Response
    {
        $email = (new Email())
            ->from('hello@example.com')
            ->to('you@example.com')
            //->cc('cc@example.com')
            //->bcc('bcc@example.com')
            //->replyTo('fabien@example.com')
            //->priority(Email::PRIORITY_HIGH)
            ->subject('Time for Symfony Mailer!')
            ->text('Sending emails is fun again!')
            ->html('<p>See Twig integration for better HTML integration!</p>');

        $mailer->send($email);

        // ...
    }
}

That's it! The message will be sent via the transport you configured. If the transport is configured to send emails asynchronously, the message won't be actually sent until a worker consumes it.

それでおしまい!メッセージは、構成したトランスポート経由で送信されます。トランスポートが電子メールを非同期で送信するように構成されている場合、メッセージはワーカーが消費するまで実際には送信されません。

Email Addresses

All the methods that require email addresses (from(), to(), etc.) accept both strings or address objects:

電子メール アドレスを必要とするすべてのメソッド (from()、to() など) は、文字列またはアドレス オブジェクトの両方を受け入れます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ...
use Symfony\Component\Mime\Address;

$email = (new Email())
    // email address as a simple string
    ->from('fabien@example.com')

    // email address as an object
    ->from(new Address('fabien@example.com'))

    // defining the email address and name as an object
    // (email clients will display the name)
    ->from(new Address('fabien@example.com', 'Fabien'))

    // defining the email address and name as a string
    // (the format must match: 'Name <email@example.com>')
    ->from(Address::create('Fabien Potencier <fabien@example.com>'))

    // ...
;

Tip

ヒント

Instead of calling ->from() every time you create a new email, you can configure emails globally to set the same From email to all messages.

新しい電子メールを作成するたびに ->from() を呼び出す代わりに、電子メールをグローバルに構成して、同じ From 電子メールをすべてのメッセージに設定できます。

Note

ノート

The local part of the address (what goes before the @) can include UTF-8 characters, except for the sender address (to avoid issues with bounced emails). For example: föóbàr@example.com, 用户@example.com, θσερ@example.com, etc.

アドレスのローカル部分 (@ の前) には、送信者アドレスを除いて UTF-8 文字を含めることができます (メールのバウンスの問題を回避するため)。例: föóbàr@example.com, 用户@example.com, θσερ@ example.com など

Use addTo(), addCc(), or addBcc() methods to add more addresses:

さらにアドレスを追加するには、addTo()、addCc()、または addBcc() メソッドを使用します。
1
2
3
4
5
6
7
8
$email = (new Email())
    ->to('foo@example.com')
    ->addTo('bar@example.com')
    ->cc('cc@example.com')
    ->addCc('cc2@example.com')

    // ...
;

Alternatively, you can pass multiple addresses to each method:

または、各メソッドに複数のアドレスを渡すこともできます:
1
2
3
4
5
6
7
8
$toAddresses = ['foo@example.com', new Address('bar@example.com')];

$email = (new Email())
    ->to(...$toAddresses)
    ->cc('cc1@example.com', 'cc2@example.com')

    // ...
;

Message Headers

Messages include a number of header fields to describe their contents. Symfony sets all the required headers automatically, but you can set your own headers too. There are different types of headers (Id header, Mailbox header, Date header, etc.) but most of the times you'll set text headers:

メッセージには、内容を説明する多数のヘッダー フィールドが含まれます。 symfony は必要なすべてのヘッダーを自動的に設定しますが、独自のヘッダーも設定できます。さまざまな種類のヘッダー (Id ヘッダー、メールボックス ヘッダー、Dateheader など) がありますが、ほとんどの場合、テキスト ヘッダーを設定します。
1
2
3
4
5
6
7
8
9
10
11
12
$email = (new Email())
    ->getHeaders()
        // this non-standard header tells compliant autoresponders ("email holiday mode") to not
        // reply to this message because it's an automated email
        ->addTextHeader('X-Auto-Response-Suppress', 'OOF, DR, RN, NRN, AutoReply')

        // use an array if you want to add a header with multiple values
        // (for example in the "References" or "In-Reply-To" header)
        ->addIdHeader('References', ['123@example.com', '456@example.com'])

        // ...
;

Tip

ヒント

Instead of calling ->addTextHeader() every time you create a new email, you can configure emails globally to set the same headers to all sent emails.

新しい電子メールを作成するたびに ->addTextHeader() を呼び出す代わりに、電子メールをグローバルに構成して、送信されたすべての電子メールに同じヘッダーを設定できます。

Message Contents

The text and HTML contents of the email messages can be strings (usually the result of rendering some template) or PHP resources:

電子メール メッセージのテキストおよび HTML コンテンツは、文字列 (通常はテンプレートをレンダリングした結果) または PHP リソースです。
1
2
3
4
5
6
7
8
9
10
$email = (new Email())
    // ...
    // simple contents defined as a string
    ->text('Lorem ipsum...')
    ->html('<p>Lorem ipsum...</p>')

    // attach a file stream
    ->text(fopen('/path/to/emails/user_signup.txt', 'r'))
    ->html(fopen('/path/to/emails/user_signup.html', 'r'))
;

Tip

ヒント

You can also use Twig templates to render the HTML and text contents. Read the Twig: HTML & CSS section later in this article to learn more.

File Attachments

Use the addPart() method with a BodyFile to add files that exist on your file system:

BodyFile で addPart() メソッドを使用して、ファイル システムに存在するファイルを追加します。
1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\File;
// ...

$email = (new Email())
    // ...
    ->addPart(new DataPart(new File('/path/to/documents/terms-of-use.pdf')))
    // optionally you can tell email clients to display a custom name for the file
    ->addPart(new DataPart(new File('/path/to/documents/privacy.pdf'), 'Privacy Policy'))
    // optionally you can provide an explicit MIME type (otherwise it's guessed)
    ->addPart(new DataPart(new File('/path/to/documents/contract.doc'), 'Contract', 'application/msword'))
;

Alternatively you can attach contents from a stream by passing it directly to the DataPart :

または、 DataPart に直接渡すことで、ストリームからコンテンツを添付できます。
1
2
3
4
$email = (new Email())
    // ...
    ->addPart(new DataPart(fopen('/path/to/documents/contract.doc', 'r')))
;

6.2

6.2

In Symfony versions previous to 6.2, the methods attachFromPath() and attach() could be used to add attachments. These methods have been deprecated and replaced with addPart().

6.2 より前のバージョンの Symfony では、メソッド attachFromPath() および attach() を使用して添付ファイルを追加できました。これらのメソッドは廃止され、addPart() に置き換えられました。

Embedding Images

If you want to display images inside your email, you must embed them instead of adding them as attachments. When using Twig to render the email contents, as explained later in this article, the images are embedded automatically. Otherwise, you need to embed them manually.

メール内に画像を表示したい場合は、画像を添付ファイルとして追加するのではなく、埋め込む必要があります。この記事の後半で説明するように、Twig を使用してメールの内容をレンダリングすると、画像が自動的に埋め込まれます。それ以外の場合は、手動で埋め込む必要があります。

First, use the addPart() method to add an image from a file or stream:

まず、addPart() メソッドを使用して、ファイルまたはストリームから画像を追加します。
1
2
3
4
5
6
7
$email = (new Email())
    // ...
    // get the image contents from a PHP resource
    ->addPart((new DataPart(fopen('/path/to/images/logo.png', 'r'), 'logo', 'image/png'))->asInline())
    // get the image contents from an existing file
    ->addPart((new DataPart(new File('/path/to/images/signature.gif'), 'footer-signature', 'image/gif'))->asInline())
;

Use the asInline() method to embed the content instead of attaching it.

asInline() メソッドを使用して、コンテンツを添付する代わりに埋め込みます。

The second optional argument of both methods is the image name ("Content-ID" in the MIME standard). Its value is an arbitrary string used later to reference the images inside the HTML contents:

両方のメソッドの 2 番目のオプション引数は、イメージ名 (MIME 標準の「Content-ID」) です。その値は、後で HTML コンテンツ内の画像を参照するために使用される任意の文字列です。
1
2
3
4
5
6
7
8
9
10
11
$email = (new Email())
    // ...
    ->addPart((new DataPart(fopen('/path/to/images/logo.png', 'r'), 'logo', 'image/png'))->asInline())
    ->addPart((new DataPart(new File('/path/to/images/signature.gif'), 'footer-signature', 'image/gif'))->asInline())

    // reference images using the syntax 'cid:' + "image embed name"
    ->html('<img src="cid:logo"> ... <img src="cid:footer-signature"> ...')

    // use the same syntax for images included as HTML background images
    ->html('... <div background="cid:footer-signature"> ... </div> ...')
;

6.1

6.1

The support of embedded images as HTML backgrounds was introduced in Symfony 6.1.

HTML 背景としての埋め込み画像のサポートは、Symfony 6.1 で導入されました。

6.2

6.2

In Symfony versions previous to 6.2, the methods embedFromPath() and embed() could be used to embed images. These methods have been deprecated and replaced with addPart() together with inline DataPart objects.

6.2 より前のバージョンの Symfony では、embedFromPath() およびembed() メソッドを使用して画像を埋め込むことができました。これらのメソッドは廃止され、インライン DataPart オブジェクトとともに addPart() に置き換えられました。

Configuring Emails Globally

Instead of calling ->from() on each Email you create, you can configure this value globally so that it is set on all sent emails. The same is true with ->to() and headers.

作成する各電子メールで ->from() を呼び出す代わりに、この値をグローバルに構成して、送信されたすべての電子メールに設定することができます。同じことが ->to() およびヘッダーにも当てはまります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/packages/dev/mailer.yaml
framework:
    mailer:
        envelope:
            sender: 'fabien@example.com'
            recipients: ['foo@example.com', 'bar@example.com']
        headers:
            From: 'Fabien <fabien@example.com>'
            Bcc: 'baz@example.com'
            X-Custom-Header: 'foobar'

Caution

注意

Some third-party providers don't support the usage of keywords like from in the headers. Check out your provider's documentation before setting any global header.

一部のサードパーティ プロバイダーは、ヘッダー内の from などのキーワードの使用をサポートしていません。グローバル ヘッダーを設定する前に、プロバイダーのドキュメントを確認してください。

Handling Sending Failures

Symfony Mailer considers that sending was successful when your transport (SMTP server or third-party provider) accepts the mail for further delivery. The message can later be lost or not delivered because of some problem in your provider, but that's out of reach for your Symfony application.

Symfony Mailer は、トランスポート (SMTP サーバーまたはサードパーティプロバイダー) がメールを受け入れてさらに配信すると、送信が成功したと見なします。メッセージは、プロバイダーの問題のために後で失われたり、配信されなかったりする可能性がありますが、それは Symfony アプリケーションには手の届かないところにあります。

If there's an error when handing over the email to your transport, Symfony throws a TransportExceptionInterface. Catch that exception to recover from the error or to display some message:

電子メールをトランスポートに渡すときにエラーが発生した場合、Symfony は TransportExceptionInterface.Catch をスローして、エラーから回復するか、メッセージを表示します。
1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;

$email = new Email();
// ...
try {
    $mailer->send($email);
} catch (TransportExceptionInterface $e) {
    // some error prevented the email sending; display an
    // error message or try to resend the message
}

Debugging Emails

The SentMessage object returned by the send() method of the TransportInterface provides access to the original message (getOriginalMessage()) and to some debug information (getDebug()) such as the HTTP calls done by the HTTP transports, which is useful to debug errors.

TransportInterface の send() メソッドによって返される SentMessage オブジェクトは、元のメッセージ (getOriginalMessage()) へのアクセスと、エラーのデバッグに役立つ HTTP トランスポートによって実行される HTTP 呼び出しなどのデバッグ情報 (getDebug()) へのアクセスを提供します。

Note

ノート

Some mailer providers change the Message-Id when sending the email. The getMessageId() method from SentMessage always returns the definitive ID of the message (being the original random ID generated by Symfony or the new ID generated by the mailer provider).

一部のメーラー プロバイダーは、メールを送信するときに Message-Id を変更します。 SentMessage の getMessageId() メソッドは、常にメッセージの definitiveID (Symfony によって生成された元のランダム ID またはメーラー プロバイダーによって生成された新しい ID) を返します。

The exceptions related to mailer transports (those which implement TransportException) also provide this debug information via the getDebug() method.

メーラー トランスポートに関連する例外 (TransportException を実装するもの) も、getDebug() メソッドを介してこのデバッグ情報を提供します。

Twig: HTML & CSS

The Mime component integrates with the Twig template engine to provide advanced features such as CSS style inlining and support for HTML/CSS frameworks to create complex HTML email messages. First, make sure Twig is installed:

Mime コンポーネントは Twig テンプレート エンジンと統合して、CSS スタイルのインライン化や HTML/CSS フレームワークのサポートなどの高度な機能を提供し、複雑な HTML 電子メール メッセージを作成します。まず、Twig がインストールされていることを確認します。
1
2
3
4
$ composer require symfony/twig-bundle

# or if you're using the component in a non-Symfony app:
# composer require symfony/twig-bridge

HTML Content

To define the contents of your email with Twig, use the TemplatedEmail class. This class extends the normal Email class but adds some new methods for Twig templates:

Twig でメールの内容を定義するには、TemplatedEmail クラスを使用します。このクラスは通常の Email クラスを拡張しますが、Twig テンプレート用のいくつかの新しいメソッドを追加します:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Bridge\Twig\Mime\TemplatedEmail;

$email = (new TemplatedEmail())
    ->from('fabien@example.com')
    ->to(new Address('ryan@example.com'))
    ->subject('Thanks for signing up!')

    // path of the Twig template to render
    ->htmlTemplate('emails/signup.html.twig')

    // pass variables (name => value) to the template
    ->context([
        'expiration_date' => new \DateTime('+7 days'),
        'username' => 'foo',
    ])
;

Then, create the template:

次に、テンプレートを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
{# templates/emails/signup.html.twig #}
<h1>Welcome {{ email.toName }}!</h1>

<p>
    You signed up as {{ username }} the following email:
</p>
<p><code>{{ email.to[0].address }}</code></p>

<p>
    <a href="#">Click here to activate your account</a>
    (this link is valid until {{ expiration_date|date('F jS') }})
</p>

The Twig template has access to any of the parameters passed in the context() method of the TemplatedEmail class and also to a special variable called email, which is an instance of WrappedTemplatedEmail.

Twig テンプレートは、TemplatedEmail クラスの context() メソッドで渡された任意のパラメーターにアクセスできます。また、WrappedTemplatedEmail のインスタンスである email という特別な変数にもアクセスできます。

Text Content

When the text content of a TemplatedEmail is not explicitly defined, it is automatically generated from the HTML contents.

TemplatedEmail のテキスト コンテンツが明示的に定義されていない場合は、HTML コンテンツから自動的に生成されます。

Symfony uses the following strategy when generating the text version of an email:

symfony は、anemail のテキスト バージョンを生成するときに次の戦略を使用します。
  • If an explicit HTML to text converter has been configured (see twig.mailer.html_to_text_converter), it calls it;
    明示的な HTML からテキストへのコンバーターが構成されている場合 (seetwig.mailer.html_to_text_converter)、それを呼び出します。
  • If not, and if you have league/html-to-markdown installed in your application, it uses it to turn HTML into Markdown (so the text email has some visual appeal);
    そうでない場合で、リーグ/html-to-markdown がアプリケーションにインストールされている場合、それを使用して HTML を Markdown に変換します (そのため、テキスト メールに視覚的な魅力があります)。
  • Otherwise, it applies the strip_tags PHP function to the original HTML contents.
    それ以外の場合は、strip_tags PHP 関数を元の HTML コンテンツに適用します。

If you want to define the text content yourself, use the text() method explained in the previous sections or the textTemplate() method provided by the TemplatedEmail class:

テキスト コンテンツを自分で定義する場合は、前のセクションで説明した text() メソッド、または TemplatedEmail クラスが提供する textTemplate() メソッドを使用します。
1
2
3
4
5
6
7
8
9
+ use Symfony\Bridge\Twig\Mime\TemplatedEmail;

 $email = (new TemplatedEmail())
     // ...

     ->htmlTemplate('emails/signup.html.twig')
+     ->textTemplate('emails/signup.txt.twig')
     // ...
 ;

Embedding Images

Instead of dealing with the <img src="cid: ..."> syntax explained in the previous sections, when using Twig to render email contents you can refer to image files as usual. First, to simplify things, define a Twig namespace called images that points to whatever directory your images are stored in:

前のセクションで説明した構文を扱う代わりに、Twig を使用して電子メール コンテンツをレンダリングする場合、通常どおり画像ファイルを参照できます。まず、簡単にするために、画像が保存されているディレクトリを指す、images という名前の Twig 名前空間を定義します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/packages/twig.yaml
twig:
    # ...

    paths:
        # point this wherever your images live
        '%kernel.project_dir%/assets/images': images

Now, use the special email.image() Twig helper to embed the images inside the email contents:

ここで、特別な email.image() Twig ヘルパーを使用して、メールの内容内に画像を埋め込みます。
1
2
3
4
5
{# '@images/' refers to the Twig namespace defined earlier #}
<img src="{{ email.image('@images/logo.png') }}" alt="Logo">

<h1>Welcome {{ email.toName }}!</h1>
{# ... #}

Inlining CSS Styles

Designing the HTML contents of an email is very different from designing a normal HTML page. For starters, most email clients only support a subset of all CSS features. In addition, popular email clients like Gmail don't support defining styles inside <style> ... </style> sections and you must inline all the CSS styles.

電子メールの HTML コンテンツのデザインは、通常の HTML ページのデザインとは大きく異なります。まず第一に、ほとんどの電子メール クライアントはすべての CSS 機能のサブセットのみをサポートしています。さらに、Gmail などの一般的な電子メール クライアントは、セクション内でのスタイルの定義をサポートしていないため、すべての CSS スタイルをインライン化する必要があります。

CSS inlining means that every HTML tag must define a style attribute with all its CSS styles. This can make organizing your CSS a mess. That's why Twig provides a CssInlinerExtension that automates everything for you. Install it with:

CSS のインライン化とは、すべての HTML タグがすべての CSS スタイルで style 属性を定義する必要があることを意味します。これにより、CSS の整理が混乱する可能性があります。そのため、Twig はすべてを自動化する CssInlinerExtension を提供します。次を使用してインストールします。
1
$ composer require twig/extra-bundle twig/cssinliner-extra

The extension is enabled automatically. To use it, wrap the entire template with the inline_css filter:

拡張機能は自動的に有効になります。これを使用するには、テンプレート全体を inline_css フィルターでラップします。
1
2
3
4
5
6
7
8
9
10
11
{% apply inline_css %}
    <style>
        {# here, define your CSS styles as usual #}
        h1 {
            color: #333;
        }
    </style>

    <h1>Welcome {{ email.toName }}!</h1>
    {# ... #}
{% endapply %}

Using External CSS Files

You can also define CSS styles in external files and pass them as arguments to the filter:

外部ファイルで CSS スタイルを定義し、引数としてフィルターに渡すこともできます。
1
2
3
4
{% apply inline_css(source('@styles/email.css')) %}
    <h1>Welcome {{ username }}!</h1>
    {# ... #}
{% endapply %}

You can pass unlimited number of arguments to inline_css() to load multiple CSS files. For this example to work, you also need to define a new Twig namespace called styles that points to the directory where email.css lives:

複数の CSS ファイルをロードするために inline_css() に無制限の数の引数を渡すことができます。この例を機能させるには、email.css が存在するディレクトリを指す、styles という名前の新しい Twig 名前空間も定義する必要があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/packages/twig.yaml
twig:
    # ...

    paths:
        # point this wherever your css files live
        '%kernel.project_dir%/assets/styles': styles

Rendering Markdown Content

Twig provides another extension called MarkdownExtension that lets you define the email contents using Markdown syntax. To use this, install the extension and a Markdown conversion library (the extension is compatible with several popular libraries):

Twig は、MarkdownExtension と呼ばれる別の拡張機能を提供します。これにより、Markdown 構文を使用して電子メールの内容を定義できます。これを使用するには、拡張機能と Markdown 変換ライブラリをインストールします (拡張機能はいくつかの一般的なライブラリと互換性があります)。
1
2
# instead of league/commonmark, you can also use erusev/parsedown or michelf/php-markdown
$ composer require twig/extra-bundle twig/markdown-extra league/commonmark

The extension adds a markdown_to_html filter, which you can use to convert parts or the entire email contents from Markdown to HTML:

この拡張機能は、markdown_to_html フィルターを追加します。これを使用して、メール コンテンツの一部または全体を Markdown から HTML に変換できます。
1
2
3
4
5
6
7
8
9
{% apply markdown_to_html %}
    Welcome {{ email.toName }}!
    ===========================

    You signed up to our site using the following email:
    `{{ email.to[0].address }}`

    [Click here to activate your account]({{ url('...') }})
{% endapply %}

Inky Email Templating Language

Creating beautifully designed emails that work on every email client is so complex that there are HTML/CSS frameworks dedicated to that. One of the most popular frameworks is called Inky. It defines a syntax based on some HTML-like tags which are later transformed into the real HTML code sent to users:

すべてのメール クライアントで動作する美しくデザインされたメールを作成することは非常に複雑であるため、専用の HTML/CSS フレームワークが存在します。最も人気のあるフレームワークの 1 つは Inky と呼ばれます。これは、後でユーザーに送信される実際の HTML コードに変換される HTML ライクなタグに基づいて構文を定義します。
1
2
3
4
5
6
<!-- a simplified example of the Inky syntax -->
<container>
    <row>
        <columns>This is a column.</columns>
    </row>
</container>

Twig provides integration with Inky via the InkyExtension. First, install the extension in your application:

Twig は、InkyExtension を介して Inky との統合を提供します。まず、拡張機能をアプリケーションにインストールします。
1
$ composer require twig/extra-bundle twig/inky-extra

The extension adds an inky_to_html filter, which can be used to convert parts or the entire email contents from Inky to HTML:

この拡張機能は、inky_to_html フィルターを追加します。これを使用して、電子メール コンテンツの一部または全体を Inky から HTML に変換できます。
1
2
3
4
5
6
7
8
9
10
11
12
{% apply inky_to_html %}
    <container>
        <row class="header">
            <columns>
                <spacer size="16"></spacer>
                <h1 class="text-center">Welcome {{ email.toName }}!</h1>
            </columns>

            {# ... #}
        </row>
    </container>
{% endapply %}

You can combine all filters to create complex email messages:

すべてのフィルターを組み合わせて、複雑な電子メール メッセージを作成できます。
1
2
3
{% apply inky_to_html|inline_css(source('@styles/foundation-emails.css')) %}
    {# ... #}
{% endapply %}

This makes use of the styles Twig namespace we created earlier. You could, for example, download the foundation-emails.css file directly from GitHub and save it in assets/styles.

これは、以前に作成したスタイルの Twig 名前空間を利用します。たとえば、foundation-emails.css ファイルを GitHub から直接ダウンロードして、assets/styles に保存できます。

Signing and Encrypting Messages

It's possible to sign and/or encrypt email messages to increase their integrity/security. Both options can be combined to encrypt a signed message and/or to sign an encrypted message.

電子メール メッセージに署名および/または暗号化して、完全性/セキュリティを向上させることができます。両方のオプションを組み合わせて、署名付きメッセージを暗号化したり、暗号化されたメッセージに署名したりできます。

Before signing/encrypting messages, make sure to have:

メッセージに署名/暗号化する前に、次のことを確認してください。
  • The OpenSSL PHP extension properly installed and configured;
    OpenSSL PHP 拡張機能が適切にインストールおよび構成されている。
  • A valid S/MIME security certificate.
    有効な S/MIME セキュリティ証明書。

Tip

ヒント

When using OpenSSL to generate certificates, make sure to add the -addtrust emailProtection command option.

OpenSSL を使用して証明書を生成する場合は、-addtrust emailProtection コマンド オプションを必ず追加してください。

Signing Messages

When signing a message, a cryptographic hash is generated for the entire content of the message (including attachments). This hash is added as an attachment so the recipient can validate the integrity of the received message. However, the contents of the original message are still readable for mailing agents not supporting signed messages, so you must also encrypt the message if you want to hide its contents.

メッセージに署名すると、メッセージのコンテンツ全体 (添付ファイルを含む) に対して暗号化ハッシュが生成されます。このハッシュは添付ファイルとして追加されるため、受信者は受信したメッセージの整合性を検証できます。ただし、元のメッセージの内容は、署名付きメッセージをサポートしていないメーリング エージェントでも読み取ることができるため、メッセージの内容を非表示にする場合は、メッセージも暗号化する必要があります。

You can sign messages using either S/MIME or DKIM. In both cases, the certificate and private key must be PEM encoded, and can be either created using for example OpenSSL or obtained at an official Certificate Authority (CA). The email recipient must have the CA certificate in the list of trusted issuers in order to verify the signature.

S/MIME または DKIM を使用してメッセージに署名できます。どちらの場合も、証明書と秘密鍵は PEM でエンコードされている必要があり、OpenSSL などを使用して作成するか、公式の認証局 (CA) で取得できます。サイン。

S/MIME Signer

S/MIME is a standard for public key encryption and signing of MIME data. It requires using both a certificate and a private key:

S/MIME は、公開鍵暗号化と MIME データの署名の標準です。証明書と秘密鍵の両方を使用する必要があります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\Mime\Crypto\SMimeSigner;
use Symfony\Component\Mime\Email;

$email = (new Email())
    ->from('hello@example.com')
    // ...
    ->html('...');

$signer = new SMimeSigner('/path/to/certificate.crt', '/path/to/certificate-private-key.key');
// if the private key has a passphrase, pass it as the third argument
// new SMimeSigner('/path/to/certificate.crt', '/path/to/certificate-private-key.key', 'the-passphrase');

$signedEmail = $signer->sign($email);
// now use the Mailer component to send this $signedEmail instead of the original email

Tip

ヒント

The SMimeSigner class defines other optional arguments to pass intermediate certificates and to configure the signing process using a bitwise operator options for openssl_pkcs7_sign PHP function.

SMimeSigner クラスは、中間証明書を渡し、openssl_pkcs7_sign PHP 関数の abitwise operator オプションを使用して署名プロセスを構成するためのその他のオプションの引数を定義します。

DKIM Signer

DKIM is an email authentication method that affixes a digital signature, linked to a domain name, to each outgoing email messages. It requires a private key but not a certificate:

DKIM は、ドメイン名にリンクされたデジタル署名を各送信メール メッセージに添付するメール認証方法です。秘密鍵が必要ですが、証明書は必要ありません。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use Symfony\Component\Mime\Crypto\DkimSigner;
use Symfony\Component\Mime\Email;

$email = (new Email())
    ->from('hello@example.com')
    // ...
    ->html('...');

// first argument: same as openssl_pkey_get_private(), either a string with the
// contents of the private key or the absolute path to it (prefixed with 'file://')
// second and third arguments: the domain name and "selector" used to perform a DNS lookup
// (the selector is a string used to point to a specific DKIM public key record in your DNS)
$signer = new DkimSigner('file:///path/to/private-key.key', 'example.com', 'sf');
// if the private key has a passphrase, pass it as the fifth argument
// new DkimSigner('file:///path/to/private-key.key', 'example.com', 'sf', [], 'the-passphrase');

$signedEmail = $signer->sign($email);
// now use the Mailer component to send this $signedEmail instead of the original email

// DKIM signer provides many config options and a helper object to configure them
use Symfony\Component\Mime\Crypto\DkimOptions;

$signedEmail = $signer->sign($email, (new DkimOptions())
    ->bodyCanon('relaxed')
    ->headerCanon('relaxed')
    ->headersToIgnore(['Message-ID'])
    ->toArray()
);

Encrypting Messages

When encrypting a message, the entire message (including attachments) is encrypted using a certificate. Therefore, only the recipients that have the corresponding private key can read the original message contents:

メッセージを暗号化する場合、メッセージ全体 (添付ファイルを含む) が証明書を使用して暗号化されます。したがって、対応する秘密鍵を持つ受信者のみが元のメッセージの内容を読み取ることができます。
1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\Mime\Crypto\SMimeEncrypter;
use Symfony\Component\Mime\Email;

$email = (new Email())
    ->from('hello@example.com')
    // ...
    ->html('...');

$encrypter = new SMimeEncrypter('/path/to/certificate.crt');
$encryptedEmail = $encrypter->encrypt($email);
// now use the Mailer component to send this $encryptedEmail instead of the original email

You can pass more than one certificate to the SMimeEncrypter constructor and it will select the appropriate certificate depending on the To option:

複数の証明書を SMimeEncrypter コンストラクターに渡すことができ、To オプションに応じて適切な証明書が選択されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$firstEmail = (new Email())
    // ...
    ->to('jane@example.com');

$secondEmail = (new Email())
    // ...
    ->to('john@example.com');

// the second optional argument of SMimeEncrypter defines which encryption algorithm is used
// (it must be one of these constants: https://www.php.net/manual/en/openssl.ciphers.php)
$encrypter = new SMimeEncrypter([
    // key = email recipient; value = path to the certificate file
    'jane@example.com' => '/path/to/first-certificate.crt',
    'john@example.com' => '/path/to/second-certificate.crt',
]);

$firstEncryptedEmail = $encrypter->encrypt($firstEmail);
$secondEncryptedEmail = $encrypter->encrypt($secondEmail);

Multiple Email Transports

You may want to use more than one mailer transport for delivery of your messages. This can be configured by replacing the dsn configuration entry with a transports entry, like:

メッセージの配信に複数のメーラー トランスポートを使用したい場合があります。これは、次のように dsn 構成エントリを atranssports エントリに置き換えることで構成できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
# config/packages/mailer.yaml
framework:
    mailer:
        transports:
            main: '%env(MAILER_DSN)%'
            alternative: '%env(MAILER_DSN_IMPORTANT)%'

By default the first transport is used. The other transports can be selected by adding an X-Transport header (which Mailer will remove automatically from the final email):

デフォルトでは、最初のトランスポートが使用されます。他のトランスポートは、X-Transport ヘッダーを追加することで選択できます (メーラーは最終的な電子メールから自動的に削除します)。
1
2
3
4
5
6
// Send using first transport ("main"):
$mailer->send($email);

// ... or use the transport "alternative":
$email->getHeaders()->addTextHeader('X-Transport', 'alternative');
$mailer->send($email);

Sending Messages Async

When you call $mailer->send($email), the email is sent to the transport immediately. To improve performance, you can leverage Messenger to send the messages later via a Messenger transport.

$mailer->send($email) を呼び出すと、電子メールはすぐにトランスポートに送信されます。パフォーマンスを向上させるために、Messenger を利用して、後で Messenger トランスポート経由でメッセージを送信できます。

Start by following the Messenger documentation and configuring a transport. Once everything is set up, when you call $mailer->send(), a SendEmailMessage message will be dispatched through the default message bus (messenger.default_bus). Assuming you have a transport called async, you can route the message there:

Messenger のドキュメントに従って、トランスポートを構成することから始めます。すべての設定が完了したら、$mailer->send() を呼び出すと、SendEmailMessage メッセージがデフォルトのメッセージ バス (messenger.default_bus) を介してディスパッチされます。 async と呼ばれるトランスポートがあると仮定すると、そこにメッセージをルーティングできます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/packages/messenger.yaml
framework:
    messenger:
        transports:
            async: "%env(MESSENGER_TRANSPORT_DSN)%"

        routing:
            'Symfony\Component\Mailer\Messenger\SendEmailMessage': async

Thanks to this, instead of being delivered immediately, messages will be sent to the transport to be handled later (see Messenger: Sync & Queued Message Handling). Note that the "rendering" of the email (computed headers, body rendering, ...) is also deferred and will only happen just before the email is sent by the Messenger handler.

6.2

6.2

The following example about rendering the email before calling $mailer->send($email) works as of Symfony 6.2.

$mailer->send($email) を呼び出す前に電子メールをレンダリングする次の例は、Symfony 6.2 で機能します。

When sending an email asynchronously, its instance must be serializable. This is always the case for Email instances, but when sending a TemplatedEmail, you must ensure that the context is serializable. If you have non-serializable variables, like Doctrine entities, either replace them with more specific variables or render the email before calling $mailer->send($email):

電子メールを非同期で送信する場合、そのインスタンスはシリアライズ可能である必要があります。これは常に電子メール インスタンスの場合ですが、テンプレート化された電子メールを送信する場合は、コンテキストがシリアライズ可能であることを確認する必要があります。 Doctrine エンティティのようにシリアル化できない変数がある場合は、それらをより具体的な変数に置き換えるか、$mailer->send($email) を呼び出す前にメールをレンダリングしてください:
1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\BodyRendererInterface;

public function action(MailerInterface $mailer, BodyRendererInterface $bodyRenderer)
{
    $email = (new TemplatedEmail())
        ->htmlTemplate($template)
        ->context($context)
    ;
    $bodyRenderer->render($email);

    $mailer->send($email);
}

You can configure which bus is used to dispatch the message using the message_bus option. You can also set this to false to call the Mailer transport directly and disable asynchronous delivery.

message_bus オプションを使用して、メッセージのディスパッチに使用するバスを構成できます。これを false に設定して、Mailer トランスポートを直接呼び出し、非同期配信を無効にすることもできます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/mailer.yaml
framework:
    mailer:
        message_bus: app.another_bus

Note

ノート

In cases of long-running scripts, and when Mailer uses the SmtpTransport you may manually disconnect from the SMTP server to avoid keeping an open connection to the SMTP server in between sending emails. You can do so by using the stop() method.

実行時間の長いスクリプトの場合、および Mailer が SmtpTransport を使用する場合、SMTP サーバーから手動で切断して、電子メールの送信の間に SMTP サーバーへの接続を開いたままにしておくことを避けることができます。これは、stop() メソッドを使用して行うことができます。

6.1

6.1

The stop() method was made public in Symfony 6.1.

stop() メソッドは Symfony 6.1 で公開されました。

You can also select the transport by adding an X-Bus-Transport header (which will be remove automatically from the final message):

X-Bus-Transport ヘッダーを追加してトランスポートを選択することもできます (最終メッセージから自動的に削除されます)。
1
2
3
// Use the bus transport "app.another_bus":
$email->getHeaders()->addTextHeader('X-Bus-Transport', 'app.another_bus');
$mailer->send($email);

6.2

6.2

The X-Bus-Transport header support was introduced in Symfony 6.2.

X-Bus-Transport ヘッダーのサポートは Symfony 6.2 で導入されました。

Adding Tags and Metadata to Emails

Certain 3rd party transports support email tags and metadata, which can be used for grouping, tracking and workflows. You can add those by using the TagHeader and MetadataHeader classes. If your transport supports headers, it will convert them to their appropriate format:

特定のサード パーティ トランスポートは、グループ化、追跡、およびワークフローに使用できる電子メール タグとメタデータをサポートしています。これらは、TagHeader クラスと MetadataHeader クラスを使用して追加できます。トランスポートがヘッダーをサポートしている場合、ヘッダーを適切な形式に変換します。
1
2
3
4
5
6
use Symfony\Component\Mailer\Header\MetadataHeader;
use Symfony\Component\Mailer\Header\TagHeader;

$email->getHeaders()->add(new TagHeader('password-reset'));
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));

If your transport does not support tags and metadata, they will be added as custom headers:

トランスポートがタグとメタデータをサポートしていない場合、それらはカスタム ヘッダーとして追加されます。
1
2
3
X-Tag: password-reset
X-Metadata-Color: blue
X-Metadata-Client-ID: 12345

The following transports currently support tags and metadata:

次のトランスポートは現在、タグとメタデータをサポートしています。
  • MailChimp
    メールチンプ
  • Mailgun
    メイルガン
  • Postmark
    消印
  • Sendgrid
    センドグリッド
  • Sendinblue
    センディンブルー

The following transports only support tags:

次のトランスポートはタグのみをサポートします。
  • MailPace
    メールペース

The following transports only support metadata:

次のトランスポートは、メタデータのみをサポートします。
  • Amazon SES (note that Amazon refers to this feature as "tags", but Symfony calls it "metadata" because it contains a key and a value)
    Amazon SES (Amazon ではこの機能を「タグ」と呼んでいますが、キーと値が含まれているため、Symfony では「メタデータ」と呼んでいます)

6.1

6.1

Metadata support for Amazon SES was introduced in Symfony 6.1.

Amazon SES のメタデータ サポートは、Symfony 6.1 で導入されました。

Draft Emails

6.1

6.1

Symfony\Component\Mime\DraftEmail was introduced in 6.1.

Symfony\Component\Mime\DraftEmail は 6.1 で導入されました。

DraftEmail is a special instance of Email. Its purpose is to build up an email (with body, attachments, etc) and make available to download as an .eml with the X-Unsent header. Many email clients can open these files and interpret them as draft emails. You can use these to create advanced mailto: links.

DraftEmail は、Email の特別なインスタンスです。その目的は、電子メール (本文、添付ファイルなどを含む) を作成し、X-Unsent ヘッダーを含む .eml としてダウンロードできるようにすることです。多くの電子メール クライアントは、これらのファイルを開いて、下書き電子メールとして解釈できます。これらを使用して、高度な mailto: リンクを作成できます。

Here's an example of making one available to download:

ダウンロードできるようにする例を次に示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// src/Controller/DownloadEmailController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Mime\DraftEmail;
use Symfony\Component\Routing\Annotation\Route;

class DownloadEmailController extends AbstractController
{
    #[Route('/download-email')]
    public function __invoke(): Response
    {
        $message = (new DraftEmail())
            ->html($this->renderView(/* ... */))
            ->attach(/* ... */)
        ;

        $response = new Response($message->toString());
        $contentDisposition = $response->headers->makeDisposition(
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
            'download.eml'
        );
        $response->headers->set('Content-Type', 'message/rfc822');
        $response->headers->set('Content-Disposition', $contentDisposition);

        return $response;
    }
}

Note

ノート

As it's possible for DraftEmail's to be created without a To/From they cannot be sent with the mailer.

To/From なしで DraftEmail が作成される可能性があるため、メーラーで送信することはできません。

Mailer Events

MessageEvent

Event Class: MessageEvent

イベント クラス: MessageEvent

MessageEvent allows to change the Mailer message and the envelope before the email is sent:

MessageEvent を使用すると、電子メールが送信される前にメーラー メッセージとエンベロープを変更できます。
1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\MessageEvent;
use Symfony\Component\Mime\Email;

public function onMessage(MessageEvent $event): void
{
    $message = $event->getMessage();
    if (!$message instanceof Email) {
        return;
    }
    // do something with the message
}

Tip

ヒント

When using a MessageEvent listener to sign the email contents, run it as late as possible (e.g. setting a negative priority for it) so the email contents are not set or modified after signing them.

MessageEvent リスナーを使用して電子メールの内容に署名する場合は、できるだけ遅く実行して (たとえば、負の優先度を設定するなど)、電子メールの内容が署名後に設定または変更されないようにします。

Execute this command to find out which listeners are registered for this event and their priorities:

このコマンドを実行して、このイベントに登録されているリスナーとその優先度を確認します。
1
$ php bin/console debug:event-dispatcher "Symfony\Component\Mailer\Event\MessageEvent"

QueuingMessageEvent

Event Class: QueuingMessageEvent

イベント クラス: QueuingMessageEvent

6.2

6.2

The QueuingMessageEvent class was introduced in Symfony 6.2.

QueueingMessageEvent クラスは Symfony 6.2 で導入されました。

QueuingMessageEvent allows to add some logic before the email is sent to the Messenger bus (this event is not dispatched when no bus is configured); it extends MessageEvent to allow adding Messenger stamps to the Messenger message sent to the bus:

QueueingMessageEvent を使用すると、電子メールが Messenger バスに送信される前にいくつかのロジックを追加できます (バスが構成されていない場合、このイベントはディスパッチされません)。バスに送信される Messenger メッセージに Messenger スタンプを追加できるように MessageEvent を拡張します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\QueuingMessageEvent;
use Symfony\Component\Mime\Email;

public function onMessage(QueuingMessageEvent $event): void
{
    $message = $event->getMessage();
    if (!$message instanceof Email) {
        return;
    }
    // do something with the message (logging, ...)

    // and/or add some Messenger stamps
    $event->addStamp(new SomeMessengerStamp());
}

This event lets listeners do something before a message is sent to the queue (like adding stamps or logging) but any changes to the message or the envelope are discarded. To change the message or the envelope, listen to MessageEvent instead.

このイベントにより、リスナーは、メッセージがキューに送信される前に何らかの処理 (スタンプの追加やログ記録など) を実行できますが、メッセージまたはエンベロープへの変更は破棄されます。メッセージまたはエンベロープを変更するには、代わりに MessageEvent をリッスンします。

Execute this command to find out which listeners are registered for this event and their priorities:

このコマンドを実行して、このイベントに登録されているリスナーとその優先度を確認します。
1
$ php bin/console debug:event-dispatcher "Symfony\Component\Mailer\Event\QueuingMessageEvent"

SentMessageEvent

Event Class: SentMessageEvent

イベント クラス: SentMessageEvent

6.2

6.2

The SentMessageEvent event was introduced in Symfony 6.2.

SentMessageEvent イベントは Symfony 6.2 で導入されました。

SentMessageEvent allows you to act on the SentMessage class to access the original message (getOriginalMessage()) and some debugging information (getDebug()) such as the HTTP calls made by the HTTP transports, which is useful for debugging errors:

SentMessageEvent を使用すると、SentMessage クラスを操作して、元のメッセージ (getOriginalMessage()) とデバッグ情報 (getDebug()) にアクセスできます。たとえば、エラーのデバッグに役立ちます。
1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\SentMessageEvent;
use Symfony\Component\Mailer\SentMessage;

public function onMessage(SentMessageEvent $event): void
{
    $message = $event->getMessage();
    if (!$message instanceof SentMessage) {
        return;
    }

    // do something with the message
}

Execute this command to find out which listeners are registered for this event and their priorities:

このコマンドを実行して、このイベントに登録されているリスナーとその優先度を確認します。
1
$ php bin/console debug:event-dispatcher "Symfony\Component\Mailer\Event\SentMessageEvent"

FailedMessageEvent

Event Class: FailedMessageEvent

イベント クラス: FailedMessageEvent

6.2

6.2

The FailedMessageEvent event was introduced in Symfony 6.2.

FailedMessageEvent イベントは Symfony 6.2 で導入されました。

FailedMessageEvent allows acting on the the initial message in case of a failure:

FailedMessageEvent を使用すると、失敗した場合に最初のメッセージに対処できます。
1
2
3
4
5
6
7
8
9
10
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\FailedMessageEvent;

public function onMessage(FailedMessageEvent $event): void
{
    // e.g you can get more information on this error when sending an email
    $event->getError();

    // do something with the message
}

Execute this command to find out which listeners are registered for this event and their priorities:

このコマンドを実行して、このイベントに登録されているリスナーとその優先度を確認します。
1
$ php bin/console debug:event-dispatcher "Symfony\Component\Mailer\Event\FailedMessageEvent"

Development & Debugging

Enabling an Email Catcher

When developing locally, it is recommended to use an email catcher. If you have enabled Docker support via Symfony recipes, an email catcher is automatically configured. In addition, if you are using the Symfony local web server, the mailer DSN is automatically exposed via the symfony binary Docker integration.

ローカルで開発する場合は、メール キャッチャーを使用することをお勧めします。 Symfony レシピを介して Docker サポートを有効にしている場合、メール キャッチャーが自動的に設定されます。さらに、Symfony ローカル Web サーバーを使用している場合、メーラー DSN は、symfony バイナリ Docker 統合を介して自動的に公開されます。

Sending Test Emails

Symfony provides a command to send emails, which is useful during development to test if sending emails works correctly:

Symfony はメールを送信するコマンドを提供します。これは、開発中にメール送信が正しく機能するかどうかをテストするのに役立ちます。
1
2
3
# the only mandatory argument is the recipient address
# (check the command help to learn about its options)
$ php bin/console mailer:test someone@example.com

This command bypasses the Messenger bus, if configured, to ease testing emails even when the Messenger consumer is not running.

このコマンドは、構成されている場合、Messenger バスをバイパスし、Messenger コンシューマが実行されていない場合でも電子メールのテストを容易にします。

6.2

6.2

The mailer:test command was introduced in Symfony 6.2.

mailer:test コマンドは Symfony 6.2 で導入されました。

Disabling Delivery

While developing (or testing), you may want to disable delivery of messages entirely. You can do this by using null://null as the mailer DSN, either in your .env configuration files or in the mailer configuration file (e.g. in the dev or test environments):

開発中 (またはテスト中) に、メッセージの配信を完全に無効にしたい場合があります。これを行うには、.env 構成ファイルまたはメーラー構成ファイル (開発環境またはテスト環境など) で、メーラー DSN として null://null を使用します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/dev/mailer.yaml
framework:
    mailer:
        dsn: 'null://null'

Note

ノート

If you're using Messenger and routing to a transport, the message will still be sent to that transport.

Messenger を使用してトランスポートにルーティングしている場合でも、メッセージはそのトランスポートに送信されます。

Always Send to the same Address

Instead of disabling delivery entirely, you might want to always send emails to a specific address, instead of the real address:

配信を完全に無効にする代わりに、実際のアドレスではなく、常に特定のアドレスにメールを送信したい場合があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
# config/packages/dev/mailer.yaml
framework:
    mailer:
        envelope:
            recipients: ['youremail@example.com']

Write a Functional Test

To functionally test that an email was sent, and even assert the email content or headers, you can use the built in assertions:

電子メールが送信されたことを機能的にテストし、電子メールのコンテンツまたはヘッダーをアサートするために、組み込みのアサーションを使用できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// tests/Controller/MailControllerTest.php
namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\MailerAssertionsTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class MailControllerTest extends WebTestCase
{
    use MailerAssertionsTrait;

    public function testMailIsSentAndContentIsOk()
    {
        $client = $this->createClient();
        $client->request('GET', '/mail/send');
        $this->assertResponseIsSuccessful();

        $this->assertEmailCount(1);

        $email = $this->getMailerMessage();

        $this->assertEmailHtmlBodyContains($email, 'Welcome');
        $this->assertEmailTextBodyContains($email, 'Welcome');
    }
}