webignition/internet-media-type-interface
PHP interface package defining contracts for representing internet media types (MIME types). Provides a shared API for parsing, validating, and comparing media type strings so implementations can interoperate across the webignition ecosystem.
Package: webignition/internet-media-type-interface — release 1.0 (previously 0.4)
Architecture fit. This is an interface-only package: it ships PHP contracts (InternetMediaTypeInterface, ParameterInterface) that model an internet media type (e.g. text/html; charset=utf-8) as an object with typed parameters. It contains no Laravel service provider, no config, no facade, and no runtime logic — it is a domain contract layer. That means it does not "integrate" with Laravel in the conventional package sense; it becomes visible to us only where a concrete implementation (ours or a third party's) is bound into the container or used inside a domain service. Fit is therefore conditional: it is a good fit if we are building media-type-aware code (content negotiation, upload validation, API response typing, mail attachment handling) and want an implementation-agnostic seam. It is a poor fit if what we actually want is a working MIME parser — for that, symfony/mime is the mainstream, Laravel-adjacent choice and does far more.
Integration feasibility. Low effort. Adoption is a single Composer requirement plus writing or selecting a concrete implementation, since interfaces alone do nothing. The real work is not installing the package, it is conforming our implementation and call sites to the 1.0 contract shape.
Technical risk — the 1.0 release is a breaking change on both interfaces:
ParameterInterface setters were removed outright (PR #17).InternetMediaTypeInterface setters were replaced with withers (PR #19) — i.e. setX(...) methods become withX(...) methods returning new instances.Implications a TPM must price in:
->set...() on either interface will fatal at runtime, not at install time. This is a silent-until-executed break.static/self clones). Interface changes propagate to implementors even though the package itself changed no logic.Key questions.
webignition/* library? If transitive, our migration is gated on that library's 1.0-compatible release.set* on them?symfony/mime (already in the Laravel dependency graph) remove this package and its BC churn entirely?Stack fit. Laravel-agnostic and PHP-native, so it drops into any Laravel 9/10/11 application without version gymnastics — no provider to register, no publishable assets, no framework coupling to test. The trade-off is that it also gives us nothing for free: no validation rules, no cast, no container binding. Value is realised only through the implementation we pair it with. Note the naming: despite "internet media type," this overlaps heavily with what symfony/mime (MediaType, MimeTypes) and Laravel's UploadedFile::getMimeType() / ->mimetypes() validation rule already provide. Justifying a second media-type abstraction requires a concrete reason — typically a domain layer that must stay framework-free and testable in isolation.
Migration path. Treat 1.0 as a code migration, not a dependency bump:
->set calls on media-type and parameter objects — these are the fatal-at-runtime sites.$type->withCharset('utf-8'); must become $type = $type->withCharset('utf-8');. This is the step most likely to be done mechanically and wrongly.phpstan/psalm) to catch missed call sites that tests do not exercise.Compatibility. Two distinct compatibility surfaces. First, PHP/platform: unverified from the notes — confirm the required PHP version before committing. Second, dependency-graph: if any other package in our tree pins ^0.4, we have a conflict and must either hold at 0.4 (and accept the setter API) or upgrade the dependent package in lockstep. Because 0.4 → 1.0 is BC-breaking with no deprecation bridge, there is no dual-support window — it is a hard cutover.
Sequencing. Recommended order: (a) decide build-vs-adopt vs symfony/mime — do this first, because it can make the entire migration moot; (b) if adopting, upgrade in a single dedicated PR with no feature work mixed in; (c) if transitively coupled, wait on the upstream library's compatible release and pin ^0.4 in the interim; (d) if we are mid-flight on 0.4 code, finish that work on 0.4 and schedule the 1.0 cutover as isolated follow-up rather than combining the two.
Maintenance. Very low steady-state burden. The package is a handful of interfaces with no runtime code, no I/O, no configuration, and no scheduled jobs — nothing to monitor, nothing to tune. The maintenance cost is concentrated entirely in the upgrade event and in the ongoing discipline of keeping our implementation in step with the contracts. Bus factor is a consideration: this is a single-maintainer GitHub project, so treat the interfaces as a spec we can vendor or re-declare locally if the upstream stalls.
Support. No commercial support, no SLA, community issue tracker only. Acceptable for a contracts package of this size; unacceptable if it were load-bearing business logic. We should record internally which version we pin and why, since the answer to "why can't we take 1.0 yet" will be non-obvious to a future engineer.
Scaling. Effectively a non-issue — interface definitions impose no runtime overhead beyond normal autoloading. Object allocation for withers does mean each mutation creates a new instance; for media-type parsing at high request volume this is negligible, but it is a behavioural difference from setters worth stating explicitly to reviewers who may otherwise flag "extra objects" in profiling.
Failure modes. Ranked by likelihood and blast radius:
ParameterInterface setters. Loud and immediate; caught by any test that touches the path, but only if that path is covered.^0.4 blocks our upgrade; the failure is a Composer resolution error at install time — visible and safe, but it can stall an unrelated release.Ramp-up. Minimal for any PHP developer — the concepts (immutable value object, withers) are standard and the surface area is tiny. The genuine ramp-up cost is one-time and organisational: making sure the team knows the API is now immutable and that return values must be captured. Budget a short internal note or PR-comment callout alongside the upgrade; it will save more time than it costs.
TPM recommendation. Do not schedule this as a routine dependency bump. First resolve the make-or-buy question against symfony/mime (already available in the Laravel stack). If we keep this package, treat 1.0 as a scoped migration ticket with an explicit call-site audit, a dedicated PR, and a stated rollback position of pinning ^0.4 — and confirm the PHP version floor and any transitive ^0.4 constraints before committing the sprint.
How can I help you explore Laravel packages today?