league/uri-query-parser
A standalone PHP library for parsing and building RFC 3986 query strings. It preserves key order and duplicate parameters, handles configurable separators and encoding, and provides the query-string parsing foundation used by league/uri.
Architecture fit. league/uri-query-parser is a small, single-purpose library: it converts a URI query string into a structured collection and serializes that collection back into a query string, with stricter RFC 3986 handling than PHP's native parse_str/http_build_query. It slots in as a leaf dependency at the edge of an application — typically in HTTP client middleware, webhook signature verification, OAuth/OIDC callback handling, or link-rewriting services. It is not an architectural component; it will never influence system boundaries, data models, or service topology. For a Laravel codebase, that means the decision is low-blast-radius but also low-leverage: adopting it buys correctness in a narrow string-manipulation concern and nothing more.
Integration feasibility. Mechanically trivial. It is a Composer package with a PSR-4 autoloader, no service provider, no config, no facades. Integration is composer require plus a handful of call sites; no framework wiring is needed unless we choose to wrap it in a container-bound helper. The real feasibility question is not "can we install it" but "should we install something that is already end-of-life."
Technical risk. This is where the package fails as a candidate:
league/uri rewrite. Expect friction on PHP 8.1+ (implicit nullable parameter deprecations, dynamic property deprecations) and near-certain breakage on PHP 8.3/8.4.league/uri-components (the QueryString class) and subsequently into the league/uri v6/v7 line. Adopting the standalone archived package means adopting a known-obsolete branch of a family we would otherwise want to be current on.Key questions for the maintainer/architect:
composer.lock.)parse_str behavior are we trying to avoid — dot/space mangling in keys, max_input_vars truncation, duplicate-key collapse, bracket-array ambiguity? If we cannot name the failure mode, we do not have a requirement.league/uri instead?Stack fit. Laravel already ships well-tested query-string primitives through Symfony's HTTP foundation and PHP core. The gap this package fills is real but narrow — RFC-correct handling of edge cases like keys containing ., [, ], spaces, and repeated parameters without PHP's silent key rewriting. If our application processes third-party query strings (payment provider callbacks, OAuth redirects, analytics UTM payloads, signed URLs), that gap matters; if we only ever read query strings we ourselves generated, it does not.
Migration path. There is nothing to migrate from in our stack given zero dependents, so this is a pure greenfield decision. The recommended path is: do not adopt league/uri-query-parser. Instead, evaluate league/uri (v7 line) as the maintained successor, which exposes query-string parsing/serialization alongside a broader, actively released URI toolkit. If the full league/uri is heavier than warranted, wrap PHP's parse_str in a small, tested internal helper that normalizes keys before parsing — a bounded, owned piece of code with no supply-chain exposure.
Compatibility. Verify before any spike: the package's composer.json PHP constraint versus our runtime matrix, and whether its tests pass on our CI. Expect to pin or patch. Note that pinning an archived package is a permanent tax: every future PHP upgrade reopens the question, and composer audit will keep flagging it, which creates friction with any automated dependency policy.
Sequencing.
league/uri, archived package) against the failure-mode list. Do not build production code.league/uri or the owned wrapper. If not, close the ticket as "no action" and document parse_str as the sanctioned approach.composer audit plus an explicit denylist) that blocks archived packages from entering production dependencies.Maintenance. An archived dependency is a permanent, low-grade maintenance liability. It generates no upgrade work in a quiet quarter and then generates a fire drill the moment a PHP minor release changes a deprecation into an error, or the moment a security scanner escalates. The expected cost is not the patch itself but the recurring decision overhead: every dependency review, every PHP upgrade RFC, every SOC 2 / vendor questionnaire will surface "why are we on an archived package?" Budget roughly 4–8 hours per year in the calm case, and a multi-day unplanned fork-and-patch in the bad case — for a library whose entire job is string parsing.
Support. No upstream maintainer, no issue triage, no CVE response. Internal support burden falls entirely on whichever engineer last touched the call site. With zero dependents and 37 stars, there is effectively no community to lean on — Stack Overflow answers will be sparse, and the knowledge walks out the door with the person who integrated it.
Scaling. Runtime scaling is a non-issue; parsing is O(n) in query-string length and negligible against any realistic request volume. The scaling concern is organizational: the number of archived dependencies in a codebase tends to grow monotonically because each individual addition looks harmless. One archived package is a footnote; twelve is a platform risk and a blocker on framework major-version upgrades. Set the precedent now.
Failure modes. Enumerate and mitigate:
app/Support with our own tests.Ramp-up. Near-zero engineering ramp-up — the API surface is small and self-explanatory, and a competent Laravel developer is productive in under an hour. The ramp-up that actually matters is organizational: socializing why an archived package is rejected despite being technically easy to install, and establishing the review heuristic (archived = default no; superseded = use the successor; zero dependents + low stars = no external validation). That heuristic is the durable output of this evaluation and is worth more than the library itself.
Recommendation. Reject for adoption. Low technical score (0.15), archived status, dead release cadence, and a maintained upstream successor all point the same direction. Redirect effort to league/uri or a small owned helper, and use this evaluation to justify an archived-dependency policy in CI.
How can I help you explore Laravel packages today?