Cam Scott

Using Symfony's MimeTypeGuesser Class to Get Server-Side Mimetypes

Different file types may need to be processed in different ways. Rather than reaching for JavaScript, try Symfony's MimeTypeGuesser.

Recently, in my work at Clockwise, I ran into a scenario where I needed to figure out the mimetype of an uploaded file. That file had to be run through ImageMagick, and the parameters we passed to that command would vary depending on the file type. Trying to guess the image type based on file extensions was proving unreliable, so we had to find another way.

As it turns out, Symfony's Mime component has a utility to guess mime types, and since Laravel is built on top of Symfony, there was no additional installation required! Just import the class at the top of your file:

1namespace App\Http\Controllers\ImageController;
2 
3use Symfony\Component\Mime\MimeTypes;
4 
5class ImageController extends Controller
6{
7}

All you need to do is instantiate the MimeTypes class, and pass the filepath to its guessMimeType() function.

$mimeTypes = new MimeTypes();
$mimeType = $mimeTypes->guessMimeType(Storage::disk('public')->path($filePath));

The function will return the file's mimetype as a string like image/jpeg. In the unlikely event that the guesser cannot determine the file's mimetype, it will simply return null.

This function provides a super nice wrapper of PHP's finfo_file function, which is part of the fileinfo extension:

// Symfony/Component/Mime/FileinfoMimeTypeGuesser.php
42public function guessMimeType(string $path): ?string
43{
44 if (!is_file($path) || !is_readable($path)) {
45 throw new InvalidArgumentException(sprintf('The "%s" file does not exist or is not readable.', $path));
46 }
47 
48 if (!$this->isGuesserSupported()) {
49 throw new LogicException(sprintf('The "%s" guesser is not supported.', __CLASS__));
50 }
51 
52 if (false === $finfo = new \finfo(FILEINFO_MIME_TYPE, $this->magicFile)) {
53 return null;
54 }
55 
56 return $finfo->file($path);
57}

This guessMimeType function accepts the file path, confirms it's readable, and then confirms that the PHP installation has the fileinfo extension is installed.

Once confirmed, it creates a new instance of finfo, and passes the FILEINFO_MIME_TYPE constant, which tells the class to return the mimetype of the file in question.

Finally, we pass the file in question to the file() function, and return the file's mimetype as the result. It's this string value that gets returned all the way up to our controller—Symfony just wraps it up nicely for us.

Last updated on August 7, 2022

Now listening: Kelly Lee Owens, "S.O"