Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mimey Laravel Package

xantios/mimey

xantios/mimey is a PHP MIME type helper for converting file extensions to MIME types and back. It offers a lightweight API for detection and validation, simplifying file upload and content-type handling in Laravel or plain PHP apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and pull in the façade/service provider:

composer require xantios/mimey

If the package ships a publishable config, publish it once so your mapping is versioned in the repo:

php artisan vendor:publish --tag=mimey

Before writing any code, open vendor/xantios/mimey/src and read the main class and the service provider registration. This package is a thin wrapper around Mimey, and the exact public method names have shifted between Mimey versions (e.g. getMimeType/getExtension vs. older getMimeType/getExtensions). Ten minutes of reading the source will save you guessing at the API.

Your first real use case: resolve a MIME type from a file extension so you can set a Content-Type header on a response, or look up the conventional extension for a MIME type you already know:

use Xantios\Mimey\Facades/Mimey; // verify exact namespace in source

$mime = Mimey::getMimeType('csv');        // text/csv
$ext  = Mimey::getExtension('image/png'); // png

That's the whole minimal path — no config required, no detection of file contents, no external dependencies to boot.

Implementation Patterns

Header resolution in controllers. The most reliable pattern is using Mimey when you already know the file name or extension and just need the canonical MIME string:

return response()->file($path, [
    'Content-Type' => Mimey::getMimeType(pathinfo($path, PATHINFO_EXTENSION)),
]);

This pairs well with storage-backed downloads where you don't want to hit finfo on every request.

Falling back from a stored extension. When users upload a file, persist the extension, then resolve the MIME type at read time. This keeps the DB schema simple and lets you update the mapping without rewriting stored rows.

Custom type registration in a service provider. Register organisation-specific types in AppServiceProvider::boot() rather than in controllers, so the mapping is applied once per request and is testable:

public function boot()
{
    Mimey::setCustomMimeType('myext', 'application/x-myext');
}

If the package exposes a config file for custom mappings, prefer that route — it survives config:cache and is visible to other developers without hunting through provider code.

Resolving MIME → extension for generated filenames. Use the reverse lookup to produce a safe download name:

$ext = Mimey::getExtension($record->mime_type) ?? 'bin';
return $record->downloadAs("export.{$ext}");

Enriching validation feedback. Laravel's mimes: rule already validates extensions internally. Mimey is better used after validation to generate friendly messages ("we accept PNG and PDF") or to populate a MIME allowlist config.

Batch lookups. In loops over many files, resolve the class once (app(MimeTypes::class) or the facade) and reuse it. The mapping data is internal; repeatedly resolving from the container is wasteful in bulk imports.

Gotchas and Tips

  • This is extension→MIME only. It reads the name, not the bytes. Never use it as a security gate for uploads — a .jpg containing PHP will happily report image/jpeg. Use finfo, File::mimeType(), or Symfony's MimeTypes (which uses magic-byte detection) for any trust decision.
  • Round-trips are lossy. Many MIME types share extensions and one extension maps to multiple MIME types (.jpg → image/jpeg or image/pjpeg). getExtension() returns the first match; don't assume getExtension(getMimeType('x')) === 'x'.
  • Unknown values return null, not exceptions. Always null-coalesce (?? 'application/octet-stream') when writing headers — passing null to a Content-Type header produces a silently wrong response.
  • Lowercase everything. Extension lookups are typically case-sensitive against a lowercase map. Normalise with strtolower(pathinfo($f, PATHINFO_EXTENSION)) before passing in.
  • Custom registrations are per-request. Anything set at runtime vanishes on the next boot. If you rely on custom types in queued jobs or console commands, register them in a provider that both HTTP and CLI paths hit, then clear php artisan config:cache after deploying config changes.
  • Package age. Last release was mid-2021. Confirm the composer.json constraint admits your Laravel version, and that auto-discovery works — if Xantios\Mimey\MimeyServiceProvider isn't found in bootstrap/cache/packages.php after composer install, register it manually in config/app.php. Run php artisan package:discover as a first debugging step for "facade root not set" errors.
  • Don't duplicate Mimey. If you already depend on symfony/mime (it ships with Laravel), you have Symfony\Component\Mime\MimeTypes available with a bigger, actively maintained map plus real detection. This package's value is the thin Laravel façade over a small static map; if that façade is all you need, consider whether the dependency earns its place.
  • Verify the API surface before committing to it. Because the docs are thin, add a small test asserting your two or three used methods against known values — it will catch a breaking upgrade immediately.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager