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

Uri Schemes Laravel Package

league/uri-schemes

A PHP library for working with URI schemes, offering dedicated classes to parse, validate, and manipulate HTTP, FTP, WebSocket, and other scheme-specific URIs. Built on league/uri components for consistent, standards-compliant URI handling.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • league/uri-schemes is not a Laravel component — no service provider, config, facade, or Blade/Eloquent hooks. It is a set of immutable value objects (Http, Ftp, Mailto, etc.) that would live in an app/Support/ or app/Services/Uri/ layer and be resolved through the container only if we wrap it ourselves.
  • Genuine fit is narrow and specific: composing/validating outbound request URLs, enforcing redirect-target allowlists (SSRF defense), normalizing callback URLs, and parsing inbound webhook endpoints. It is a poor fit for anything Laravel or Symfony already covers (routing, request URI access, Guzzle/PSR-7 message construction).
  • Because it is a pure utility, the architectural cost is low to adopt and low to remove — which is also why it should not be allowed to become load-bearing.
  • Nothing in 1.2.1 changes this. The release adds no service provider, no Laravel validation rule, no config surface. It remains bespoke-wrapper-only.

Integration feasibility

  • Composer-installable and PSR-4 autoloaded, so a first integration is trivial. The blocker is dependency resolution, not code.
  • The package still pins the legacy tree: league/uri 5.x plus league/uri-components and league/uri-hostname-parser. 1.2.1 contains no dependency constraint changes, so it still conflicts with league/uri ≥6, which is what most modern Laravel and PHP packages pull in transitively. Installation succeeds only in an isolated legacy application; in a current stack it still hard-fails composer update.
  • No framework glue means no free wins (no validation rule, no cast, no middleware). Everything is bespoke wrapper code we own forever.

Technical risk

  • Still high, but the risk profile has shifted slightly and should be re-stated accurately. The package is no longer strictly dormant: 1.2.1 supersedes the 2018-11-26 release. However, a single patch release after years of inactivity is not a maintenance programme — there is no published roadmap, no stated security-response process, no CVE triage, and no support commitment.
  • The code now tests against PHP 7.3 (added in this release). That marginally widens the supported floor but confirms the ceiling: there is still no PHP 8.x support and no signal that one is planned. Expect deprecation noise and edge-case breakage on PHP 8.2+, with no fix path we control.
  • 1.2.1 is itself evidence for the risk argument. It fixes a regression in scheme resolution (#13) — i.e. the 5.x line had a real parsing defect, in the exact code path we would depend on for SSRF allowlisting and redirect handling. The functional surface sits directly on a security boundary; an intermittently maintained parser in that position remains a compliance and audit finding.
  • Partial mitigation worth noting: Uri::formatRegisteredName now throws UnexpectedValueException when ext-intl is misconfigured, rather than continuing with degraded behaviour. This converts a silent-divergence failure into a loud one — an improvement, but it introduces a new uncaught-exception path at call sites (see Operational Impact).
  • Zero-dependents and low opportunity score remain consistent with functionality absorbed upstream (league/uri ^7). 1.2.1 does not reverse that; it patches a line that the ecosystem has already moved past.

Key questions

  1. Does any application in scope still run PHP ≤7.4, or does any pinned dependency require league/uri 5.x? (composer why-not league/uri ^7 settles this in minutes.) 1.2.1 does not change the answer.
  2. Is this library touching any security-relevant path — outbound HTTP target validation, redirect handling, OAuth callback matching? If yes, escalate from tech debt to risk register.
  3. New: Is 1.2.1 a one-off patch by a passing contributor, or the start of a revival? The release contains no roadmap, no stated support window, and no PHP 8 work. Absent a written commitment, plan on the assumption it is a one-off — and revisit only if a 2.x or an explicit maintenance statement appears.
  4. Do we need IDN/IRI support, and is ext-intl correctly configured everywhere? The new UnexpectedValueException will surface misconfiguration as a runtime error rather than silent misbehaviour, so environment parity must be verified before rollout.
  5. What is the actual cost of replacing versus wrapping? If the call sites are few, replacement is cheaper than a permanent exception.
  6. Who is named owner of this dependency if we keep it, and what is the documented removal date?

Integration Approach

Stack fit

  • Composer-native and framework-agnostic, so it slots into a Laravel service layer without friction — but it also gives back nothing Laravel-specific. Modern league/uri ^7 provides the same value-object model with maintained code, so the "fit" argument still does not justify the legacy version.
  • Overlaps with existing capability (Guzzle PSR-7, Symfony HttpFoundation) already present in a standard Laravel install. Net new capability is small.

Migration path

  • Unchanged by 1.2.1 — the release introduces no deprecations and no breaking changes, so no additional migration work is created or avoided.
  • Straightforward and mechanical: the scheme classes moved from League\Uri\Schemes\Http to League\Uri\Http in league/uri 6, and the accessor API (getHost, withQuery, getPath, and friends) is largely preserved. Expect a rename pass plus adjustment to the exception contract (League\Uri\Contracts\UriException) and stricter default validation.
  • Realistic effort: 1–3 engineer-days per service for the swap and regression tests. That remains cheaper than a permanent abandoned dependency.

Compatibility

  • Hard blocker wherever league/uri ≥6 is already resolved. Because a Composer install is all-or-nothing, one legacy consumer can force the entire monorepo back onto the 5.x line — check this before any per-service plan.
  • PHP 8.2+ compatibility is unverified and unowned; 1.2.1 testing only up to PHP 7.3 confirms it is unsupported rather than "probably fine."
  • If we are forced to stay on the legacy line, pin 1.2.1 specifically rather than a version range — it is the only release containing the scheme-resolution fix, and that is a correctness defect in a security-relevant code path.

Sequencing

  1. Inventory: run composer why league/uri and composer why-not league/uri ^7 across every service and lockfile. Produce the blast-radius list.
  2. Decide per service: replace (default) vs. isolate (only where a hard legacy pin exists).
  3. Where isolation is unavoidable, pin the exact version (1.2.1), document a dated removal plan, and add the package to the dependency-approval exception list with named owner.
  4. Build contract tests first: golden cases for scheme handling, userinfo, ports, trailing slashes, IDN hosts, and malformed input. These are the safety net for both the swap and future upgrades — and they are the regression test that issue #13 should have caught.
  5. Add an explicit test for ext-intl misconfiguration/absence, asserting our wrapper handles the new UnexpectedValueException gracefully rather than emitting a 500.
  6. Migrate to league/uri ^7 behind a thin internal UriFactory/UrlValidator interface so call sites never reference the vendor namespace.
  7. Remove the wrapper's legacy branch and delete league/uri-schemes from every lockfile. Verify with composer audit.

Operational Impact

Maintenance and support

  • No support channel and no published process. Documentation still points at v6+, so anything we build on this API is effectively undocumented from day one.
  • The 1.2.1 release means we cannot honestly describe the package as "abandoned since 2018" any more — the accurate framing is "intermittently maintained, unsupported, and past end-of-life for the PHP versions we run." That distinction matters for the ADR: it weakens the strongest argument for removal (total dormancy) while leaving the operational conclusion intact.
  • We still absorb all PHP-version compatibility work and security triage. Budget this as a recurring cost, not a one-time integration cost.

Scaling

  • Not a scaling concern. These are stateless CPU-bound value objects parsing short strings — microseconds per operation. No I/O, no memory growth, no connection state. If URL normalization ever appears in a hot path, memoize the parsed result at the boundary rather than micro-optimizing the library.

Failure modes to design around

  • Resolution failure: CI or a fresh deploy breaks when a transitive dependency bumps to league/uri ≥6. Still the most likely production incident, and still a build-time rather than runtime failure — which is the good news.
  • Uncaught parse exceptions: invalid or adversarial input will throw rather than return null. Every call site needs a try/catch at the trust boundary, otherwise malformed webhook/callback URLs become 500s.
  • New in 1.2.1 — Intl configuration exception: Uri::formatRegisteredName now throws UnexpectedValueException on a misconfigured ext-intl. This is a net improvement over silent divergence, but it is a newly reachable exception in production paths where the environment differs from staging. Verify ext-intl presence and configuration across all environments before deploying 1.2.1.
  • Validation drift: the legacy parser's leniency versus the modern one can create host-confusion bypasses if only one code path is upgraded — hence the golden-case tests in step 4. The scheme-resolution regression fixed in 1.2.1 is a concrete example of this class of defect.
  • PHP 8 deprecation noise polluting logs until the package is removed.

Ramp-up

  • Low for engineers: the API surface is small and idiomatic (get*/with* accessors), so productivity arrives in hours. The cost is institutional rather than individual — stale docs, blog posts and Stack Overflow answers describe the 5.x API, and new hires will not know the package is effectively unsupported unless we tell them. Put that fact in the ADR and in a code comment on the wrapper, not in tribal knowledge.

Recommendation

  • Unchanged in direction: do not adopt for new work. Adopt league/uri ^7 directly and route all call sites through a thin internal interface.
  • For existing usage, 1.2.1 slightly improves the picture — a real parsing defect is fixed and Intl misconfiguration now fails loudly — but it does not deliver league/uri 6/7 compatibility, PHP 8 support, a support commitment, or a roadmap. Treat this as a scheduled replacement, not a maintained dependency.
  • If a hard legacy pin forces us to stay, pin 1.2.1, add the Intl-exception test, and attach a named owner and dated removal plan. Do not read a single patch release as a revival; revisit only if an explicit maintenance statement or PHP 8-compatible release appears.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route