Symfony’s MIME in 5 minutes

A simple but powerful way to manage messages and file types!

Alexandre Daubois
The SensioLabs Tech Blog

--

Photo by Rodion Kutsaiev from Pexels

Let’s be clear. It is not the most famous component of Symfony. Compared to giants like Form, Security and HttpFoundation, it is clear that MIME can’t compete. Does it mean that it is not as good as them?

Of course not! In fact, it’s super useful. Are you dealing with file uploads or emails in your web application? Well, you may be using this component without realizing it.

This article is about a Symfony component. This means that you can use it and install it in any PHP application, whether you write the whole project with Symfony… or not!

Multipurpose… what?

MIME stands for Multipurpose Internet Mail Extensions. It was described by RFC 4095, in November 1996. Initially, this extension was created to differentiate body and attachments in emails.

MIME types are two-part strings that identify the type of a file. MIME types exist for all types of files: audio, video, applications, images, text files, etc. The IANA (Internet Assigned Numbers Authority) maintains an exhaustive list of known MIME types. There are several hundred of them.

MIME guessing is usually done “by looking for certain sequences of magic bytes at specific positions in the file”, as stated in the PHP documentation.

We try to avoid guessing the MIME type with the file extension as much as possible. It is easier to change a file extension rather than specific bytes in the file without corrupting it. Therefore, even if guessing thanks to byte sequence isn’t perfect, it is considered way more reliable to guess the file type this way rather than using its extension.

If you are handling file uploads in your web application, you are likely to restrict uploads to certain file types by specifying allowed MIME types, and additionally, file extensions. The first one is the most important.

Symfony’s MIME component is there to help you to manage this complexity by providing easy-to-use tools to deal with file types.

A model to govern them all

Before anything else, the main purpose of the MIME component is to provide a model to create complex and advanced emails. What I mean by “advanced” is an email with formatting, multi-part, multiple attachments of different file types (thanks to MIME types!), etc. Keep in mind that at first, emails were only text messages. Nothing more.

The object-oriented model proposed by the MIME component can be used seamlessly with the Mailer component to send emails. Sending e-mails is not the purpose of the MIME component. It only offers a model compatible with systems that are able to actually send the message.

You have many options to write the perfect email: recipients, sender, CC, BCC, attachments, priority, precising the email to reply to (Reply-To), HTML content, alternative plain text content, etc.

On the technical side, you should know that the Email class is the high-level API for creating messages. The Email class directly extends the Message class (the low-level API), which itself extends the RawMessage class. In most use cases, you will probably use the Email class. But whenever you need control and you need access to all the details and parts of your message, your choice will probably go to an instance of Message . In any case, you can use it with the Mailer component, which accepts an instance of RawMessage as an input.

Utils you can’t live without

Even if this model is the main part of the component, the latter also offers useful utils dedicated to help you in managing file types and MIME types we saw in the first section of this article. We can see 3 main utilities here:

  • For a given MIME type, you can ask the component to return a list of possible extensions. Indeed, the same MIME type can correspond to several extensions: image/jpeg will match with .jpeg.and .jpg, text/html will match with .htm and .html, and so on;
  • Get matching MIME types by extension. This is the reverse operation of the util described just above. Again, it returns a list containing the possible MIME types for a given extension. If you go to the list of MIME types, you will see that an extension can correspond to several MIME types ;
  • Guess the MIME type of a given file. Probably the most useful util in this list, this one will try to guess the MIME type. The Symfony MIME component comes with several guesser implementations to be as reliable as possible. Again and as said earlier, there is no perfect solution to guess the MIME type.

Guessers implement the MimeTypeGuesserInterface. I am sure you know what this means: you can implement your very own custom guesser if necessary, if default ones don’t suit your needs. For your information, one of the guessers bundled in the component bases its result on the finfo class of the standard PHP library (SPL). The other bundled guesser is based on the Unix file command, if available.

Isn’t it an amazing component? Personally, I find that this one is exactly the type of component that could have literally saved me hours of development if I knew about it earlier. When used correctly, its simple but stable out-of-the-box model for creating emails (or more generally, so-called messages) provide, once again, an enjoyable and amazing development experience.

I didn’t mention it in this article, but you should know that this component is also able to sign your messages thanks to a Crypto module. Everything is done with algorithms like SHA256 and ED25519. This will further enhance the good impression this component will leave you!

--

--