cardinalby/content-disposition
A small PHP library for parsing and generating HTTP Content-Disposition headers, including attachment/inline types, quoted filenames, and RFC 5987/6266 filename* encoding for safe, browser-compatible file downloads.
Architecture fit. This is a single-purpose, framework-agnostic PHP class for parsing and constructing Content-Disposition header values — a leaf utility with no service provider, no config, no facades, and no Laravel coupling. That means it does not "integrate" with Laravel so much as sit underneath it, at the HTTP-serialization boundary. The architectural problem is redundancy: every Laravel app already carries symfony/http-foundation, whose HeaderUtils::makeDisposition() and BinaryFileResponse handle RFC 6266 filename encoding for response()->download() and response()->file(). Adopting this package therefore means introducing a second source of truth for the same header, which is a net-negative for architectural coherence unless a specific capability gap is proven.
Integration feasibility. Mechanically trivial: composer require, PSR-4 autoload, no migrations, no publishable assets, no bootstrapping. Realistic engineering effort is under a day including tests. The constraint is not technical difficulty but justification — a 7-star, zero-dependent package must clear a higher bar than "it works," because the TPM is trading ecosystem support for a marginal gain over an in-tree Symfony dependency.
Technical risk. The dominant risk is lifecycle, not code quality. Last release 2023-05-23, a single maintainer, no dependent packages, and an opportunity score of ~48 all point to a project with no downstream pressure to keep pace with PHP or Symfony releases. Specific exposures:
composer.json constraint could block an upgrade to PHP 8.3/8.4 or Laravel 12.Content-Disposition values frequently derive from user-supplied filenames. If parsing or building does not strip \r\n and control characters, that is a response-splitting vector. This is the one question worth blocking on.filename*, ASCII fallback behavior, and browser-specific divergence (older Safari, IE-mode) are exactly where hand-rolled implementations fail.Key questions for the maintainer/evaluation spike.
Symfony\Component\HttpFoundation\HeaderUtils does not?multipart/form-data Content-Disposition parsing, or build-only?Stack fit. Treat it as a library, not a Laravel package. If adopted, wrap it behind an application-owned interface (e.g. App\Support\Http\ContentDispositionEncoder) registered as a singleton, so call sites never reference the vendor namespace directly. This is the single highest-leverage decision: it converts an unmaintained dependency into a swappable implementation detail.
Migration path. There is no migration to perform — zero dependents means no ecosystem precedent and no existing footprint in our codebase. The realistic path is inverted: baseline on Symfony's HeaderUtils, write characterization tests around every download/file endpoint (especially non-ASCII filenames), and only reach for the package if a test demonstrably fails. If a gap is found, the cheaper move may be to vendor the ~class file into app/Support/Http/ under MIT attribution rather than carry a Composer dependency — same code, no supply-chain surface, no version-constraint drift.
Compatibility. Namespacing is unlikely to collide with Symfony or Laravel. Framework-version risk is low in principle (no bindings), but the real compatibility gate is the PHP constraint in composer.json versus our target runtime. Verify before any spike; a stale constraint can silently pin the platform and block unrelated upgrades via dependency resolution.
Sequencing.
Content-Disposition (downloads, exports, streamed responses, multipart ingestion).HeaderUtils coverage against those tests; document any gap explicitly.Maintenance. Assume unmaintained and price it accordingly. The package is small enough that "we own it" is a viable posture — but only if we fork or vendor, so that patches (CRLF hardening, PHP compatibility) can actually ship. Consuming it as an upstream dependency means our fix latency is bounded by a volunteer's availability, which is effectively unbounded.
Support. No SLA, no vendor, no user community to draw on at 7 stars. The escalation path is "read the source and patch it ourselves." That is acceptable for a ~200-line utility; it is not acceptable if the package ever accretes scope.
Scaling. A non-issue. Pure string manipulation, no I/O, no state, no caching concerns. Runtime cost is immeasurable against response serialization and file streaming. No horizontal-scaling or concurrency considerations.
Failure modes.
filename* encoding yields a correct-looking download with a corrupted name in Safari or older clients; tests on Chrome will not catch it.download or mojibake for users on legacy clients.Ramp-up. Negligible for any PHP developer — single class, likely README-only documentation, no concepts to learn. The real ramp-up cost is organizational: teaching reviewers that this header has exactly one owner in the codebase. That discipline cost exceeds the package's technical value, which is the crux of the recommendation.
TPM recommendation. Do not add this as a production dependency. Baseline on symfony/http-foundation HeaderUtils, close any gaps by vendoring this MIT-licensed class behind an application-owned interface, and revisit only if the project shows sustained maintenance and test coverage. The package is fine code solving a solved problem; the correct TPM move is to avoid owning an unmaintained dependency for capability we already have.
How can I help you explore Laravel packages today?