league/mime-type-detection
Fast, reliable MIME type detection for PHP. Detects from file extensions and binary signatures using shared databases, with a simple API and customizable mappings. Ideal for uploads, validation, and content-type handling in Laravel and other PHP apps.
Install the package via Composer: composer require league/mime-type-detection. It requires the ext-fileinfo extension — ensure it’s enabled (check via php -i | grep fileinfo). Start with the default detector for file-based detection:
use League\MimeTypeDetection\FinfoMimeTypeDetector;
$detector = new FinfoMimeTypeDetector();
$mimeType = $detector->detectMimeType('/path/to/file.jpg'); // 'image/jpeg'
For Laravel, register it as a singleton in AppServiceProvider or use it directly in services. First use case: validating file uploads in a form request by detecting MIME type from the uploaded file’s content (not just the extension).
FormRequest:
protected function withValidator($validator)
{
$validator->after(function ($validator) {
$detector = new FinfoMimeTypeDetector();
$file = $this->file('document');
if ($file && !in_array($detector->detectMimeType($file->getPathname()), ['application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'])) {
$validator->errors()->add('document', 'Invalid file type.');
}
});
}
league/flysystem v3+, this package is used internally via MimetypeDetectionExtension. You rarely interact with it directly — Flysystem auto-detects MIME on writes.UploadedFile::getSize() > 0), use:
$detector->detectMimeTypeFromBuffer(file_get_contents($request->file('avatar')->getPathname()));
Or more efficiently, pass a limited buffer size to avoid memory spikes:
new FinfoMimeTypeDetector(null, 8192); // 8KB sample
$extensions = $detector->getExtensionsForMimeType('image/webp'); // ['webp']
$filename = "download." . ($extensions[0] ?? 'dat');
ChainMimeTypeDetector to prioritize content-based detection but fall back to extension mapping if finfo fails:
$detector = new ChainMimeTypeDetector([
new FinfoMimeTypeDetector(),
new ExtensionToMimeTypeMap(),
]);
finfo extension is mandatory: If detectMimeType() returns false, verify extension=fileinfo is in php.ini (commonly missing in minimal Docker images)..txt containing JSON), the detector may return text/plain — configure treatInconclusiveAs in constructor (e.g., 'application/octet-stream') for stricter handling.false from buffer-based detection. Test first or use full-file detection.?string returns where possible. Avoid ?string type-hinting in your code relying on its return values until you’re confident on deprecation behavior.application/x-myapp) for internal services? Wrap the map:
$map = new OverridingExtensionToMimeTypeMap(
new ExtensionToMimeTypeMap(),
['myapp' => 'application/x-myapp']
);
composer update league/mime-type-detection periodically — recent changelogs show frequent lookup updates (1.11.0 through 1.16.0).array_shift() calls:
$ext = $detector->getExtensionsForMimeType($mimeType)[0] ?? 'bin';
How can I help you explore Laravel packages today?