The Mime Component ¶
The Mime component allows manipulating the MIME messages used to send emails and provides utilities related to MIME types.
Mime コンポーネントは、電子メールの送信に使用される MIME メッセージの操作を可能にし、MIME タイプに関連するユーティリティを提供します。
Installation ¶
1 |
$ composer require symfony/mime
|
Note
If you install this component outside of a Symfony application, you must
require the vendor/autoload.php
file in your code to enable the class
autoloading mechanism provided by Composer. Read
this article for more details.
Introduction ¶
MIME (Multipurpose Internet Mail Extensions) is an Internet standard that extends the original basic format of emails to support features like:
- Headers and text contents using non-ASCII characters;非 ASCII 文字を使用したヘッダーとテキスト コンテンツ。
- Message bodies with multiple parts (e.g. HTML and plain text contents);複数の部分を持つメッセージ本文 (例: HTML とプレーン テキストのコンテンツ)。
- Non-text attachments: audio, video, images, PDF, etc.テキスト以外の添付ファイル: オーディオ、ビデオ、画像、PDF など。
The entire MIME standard is complex and huge, but Symfony abstracts all that complexity to provide two ways of creating MIME messages:
- A high-level API based on the Email class
to quickly create email messages with all the common features;すべての一般的な機能を備えた電子メール メッセージをすばやく作成するための、Email クラスに基づく高レベル API。
- A low-level API based on the Message class
to have absolute control over every single part of the email message.Message クラスに基づく低レベル API で、電子メール メッセージのすべての部分を完全に制御できます。
Usage ¶
Use the Email class and their chainable methods to compose the entire email message:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use Symfony\Component\Mime\Email;
$email = (new Email())
->from('fabien@symfony.com')
->to('foo@example.com')
->cc('bar@example.com')
->bcc('baz@example.com')
->replyTo('fabien@symfony.com')
->priority(Email::PRIORITY_HIGH)
->subject('Important Notification')
->text('Lorem ipsum...')
->html('<h1>Lorem ipsum</h1> <p>...</p>')
;
|
The only purpose of this component is to create the email messages. Use the Mailer component to actually send them.
Twig Integration ¶
The Mime component comes with excellent integration with Twig, allowing you to create messages from Twig templates, embed images, inline CSS and more. Details on how to use those features can be found in the Mailer documentation: Twig: HTML & CSS.
But if you're using the Mime component without the Symfony framework, you'll need to handle a few setup details.
Twig Setup ¶
To integrate with Twig, use the BodyRenderer class to render the template and update the email message contents with the results:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// ...
use Symfony\Bridge\Twig\Mime\BodyRenderer;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
// when using the Mime component inside a full-stack Symfony application, you
// don't need to do this Twig setup. You only have to inject the 'twig' service
$loader = new FilesystemLoader(__DIR__.'/templates');
$twig = new Environment($loader);
$renderer = new BodyRenderer($twig);
// this updates the $email object contents with the result of rendering
// the template defined earlier with the given context
$renderer->render($email);
|
Inlining CSS Styles (and other Extensions) ¶
To use the inline_css filter, first install the Twig extension:
1 |
$ composer require twig/cssinliner-extra
|
Now, enable the extension:
1 2 3 4 5 6 |
// ...
use Twig\Extra\CssInliner\CssInlinerExtension;
$loader = new FilesystemLoader(__DIR__.'/templates');
$twig = new Environment($loader);
$twig->addExtension(new CssInlinerExtension());
|
The same process should be used for enabling other extensions, like the MarkdownExtension and InkyExtension.
Creating Raw Email Messages ¶
This is useful for advanced applications that need absolute control over every email part. It's not recommended for applications with regular email requirements because it adds complexity for no real gain.
Before continuing, it's important to have a look at the low level structure of an email message. Consider a message which includes some content as both text and HTML, a single PNG image embedded in those contents and a PDF file attached to it. The MIME standard allows structuring this message in different ways, but the following tree is the one that works on most email clients:
1 2 3 4 5 6 7 |
multipart/mixed
├── multipart/related
│ ├── multipart/alternative
│ │ ├── text/plain
│ │ └── text/html
│ └── image/png
└── application/pdf
|
This is the purpose of each MIME message part:
multipart/alternative
: used when two or more parts are alternatives of the same (or very similar) content. The preferred format must be added last.multipart/alternative: 2 つ以上の部分が同じ (または非常に類似した) コンテンツの代替である場合に使用されます。優先フォーマットは最後に追加する必要があります。multipart/mixed
: used to send different content types in the same message, such as when attaching files.multipart/mixed: ファイルを添付する場合など、同じメッセージで異なるコンテンツ タイプを送信するために使用されます。multipart/related
: used to indicate that each message part is a component of an aggregate whole. The most common usage is to display images embedded in the message contents.multipart/related: 各メッセージ部分が集合全体の構成要素であることを示すために使用されます。最も一般的な使用法は、メッセージの内容に埋め込まれた画像を表示することです。
When using the low-level Message class to create the email message, you must keep all the above in mind to define the different parts of the email by hand:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
use Symfony\Component\Mime\Header\Headers;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\Part\Multipart\AlternativePart;
use Symfony\Component\Mime\Part\TextPart;
$headers = (new Headers())
->addMailboxListHeader('From', ['fabien@symfony.com'])
->addMailboxListHeader('To', ['foo@example.com'])
->addTextHeader('Subject', 'Important Notification')
;
$textContent = new TextPart('Lorem ipsum...');
$htmlContent = new TextPart('<h1>Lorem ipsum</h1> <p>...</p>', null, 'html');
$body = new AlternativePart($textContent, $htmlContent);
$email = new Message($headers, $body);
|
Embedding images and attaching files is possible by creating the appropriate email multiparts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// ...
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\MixedPart;
use Symfony\Component\Mime\Part\Multipart\RelatedPart;
// ...
$embeddedImage = new DataPart(fopen('/path/to/images/logo.png', 'r'), null, 'image/png');
$imageCid = $embeddedImage->getContentId();
$attachedFile = new DataPart(fopen('/path/to/documents/terms-of-use.pdf', 'r'), null, 'application/pdf');
$textContent = new TextPart('Lorem ipsum...');
$htmlContent = new TextPart(sprintf(
'<img src="cid:%s"/> <h1>Lorem ipsum</h1> <p>...</p>', $imageCid
), null, 'html');
$bodyContent = new AlternativePart($textContent, $htmlContent);
$body = new RelatedPart($bodyContent, $embeddedImage);
$messageParts = new MixedPart($body, $attachedFile);
$email = new Message($headers, $messageParts);
|
Serializing Email Messages ¶
Email messages created with either the Email
or Message
classes can be
serialized because they are simple data objects:
1 2 3 4 5 6 |
$email = (new Email())
->from('fabien@symfony.com')
// ...
;
$serializedEmail = serialize($email);
|
A common use case is to store serialized email messages, include them in a message sent with the Messenger component and recreate them later when sending them. Use the RawMessage class to recreate email messages from their serialized contents:
1 2 3 4 5 6 7 |
use Symfony\Component\Mime\RawMessage;
// ...
$serializedEmail = serialize($email);
// later, recreate the original message to actually send it
$message = new RawMessage(unserialize($serializedEmail));
|
MIME Types Utilities ¶
Although MIME was designed mainly for creating emails, the content types (also known as MIME types and "media types") defined by MIME standards are also of importance in communication protocols outside of email, such as HTTP. That's why this component also provides utilities to work with MIME types.
The MimeTypes class transforms between MIME types and file name extensions:
1 2 3 4 5 6 7 8 9 10 11 12 |
use Symfony\Component\Mime\MimeTypes;
$mimeTypes = new MimeTypes();
$exts = $mimeTypes->getExtensions('application/javascript');
// $exts = ['js', 'jsm', 'mjs']
$exts = $mimeTypes->getExtensions('image/jpeg');
// $exts = ['jpeg', 'jpg', 'jpe']
$types = $mimeTypes->getMimeTypes('js');
// $types = ['application/javascript', 'application/x-javascript', 'text/javascript']
$types = $mimeTypes->getMimeTypes('apk');
// $types = ['application/vnd.android.package-archive']
|
These methods return arrays with one or more elements. The element position indicates its priority, so the first returned extension is the preferred one.
Guessing the MIME Type ¶
Another useful utility allows to guess the MIME type of any given file:
1 2 3 4 5 6 |
use Symfony\Component\Mime\MimeTypes;
$mimeTypes = new MimeTypes();
$mimeType = $mimeTypes->guessMimeType('/some/path/to/image.gif');
// Guessing is not based on the file name, so $mimeType will be 'image/gif'
// only if the given file is truly a GIF image
|
Guessing the MIME type is a time-consuming process that requires inspecting part of the file contents. Symfony applies multiple guessing mechanisms, one of them based on the PHP fileinfo extension. It's recommended to install that extension to improve the guessing performance.
Adding a MIME Type Guesser ¶
You can add your own MIME type guesser by creating a class that implements MimeTypeGuesserInterface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
namespace App;
use Symfony\Component\Mime\MimeTypeGuesserInterface;
class SomeMimeTypeGuesser implements MimeTypeGuesserInterface
{
public function isGuesserSupported(): bool
{
// return true when the guesser is supported (might depend on the OS for instance)
return true;
}
public function guessMimeType(string $path): ?string
{
// inspect the contents of the file stored in $path to guess its
// type and return a valid MIME type ... or null if unknown
return '...';
}
}
|
MIME type guessers must be registered as services
and tagged with the mime.mime_type_guesser
tag.
If you're using the
default services.yaml configuration,
this is already done for you, thanks to autoconfiguration.