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 Laravel Package

sabre/uri

sabre/uri is a lightweight PHP library for working with URIs per RFC3986. It offers resolve, normalize, parse, build, and split functions for handling relative URLs, comparing URLs, and Windows-style paths. Fully unit tested, with many tests drawn from RFC3986 examples.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy on URL/URI handling. Any roadmap item that involves manipulating URLs — webhook registration, connector/integration setup, sitemap or crawler ingestion, link rewriting, signed-URL validation, asset/CDN path handling, URL shorteners — currently gets solved either with parse_url() + string concatenation or with a hand-rolled helper class. This package is the "buy" answer: five pure functions (parse, build, resolve, normalize, split) that are RFC3986-conformant and unit-tested against the RFC's own examples. The decision is less "adopt a library" and more "stop owning URI edge cases as a product risk."

  • Security posture and open-redirect / SSRF-adjacent surface. Wherever we resolve a user-supplied or third-party-supplied URL against a base (OAuth return URLs, magic-link flows, "redirect back to" parameters, webhook target validation), normalize() + resolve() gives us a deterministic canonical form to compare against an allowlist before issuing a redirect. That is a defensible control to point at during a security review or pen test, and it closes a class of bugs that regex-based allowlists reliably miss.

  • Canonicalization as a data contract. Duplicate detection, cache keys, analytics attribution, and "same resource or not?" comparisons all need a single canonical URI form. normalize() turns this from a per-team convention into a shared primitive. This is the highest-leverage use case in a Laravel monolith with several teams, because inconsistency here silently corrupts metrics rather than throwing errors.

  • Edge-case correctness our current code gets wrong. The changelog documents real, recurring PHP failure modes: parse_url() corrupting non-ASCII (Chinese/Hebrew) strings, triple-slash URIs, relative URIs containing an unencoded colon, mailto: resolution, file:// URIs, Windows-style paths (file:///C:/path), and paths consisting only of "0". If any of those appear in imported data, partner payloads, or uploaded link lists, we are already shipping incorrect behavior. This is a bug-fix decision, not a greenfield one.

  • Dependency and platform hygiene. 3.1.0 (Apr 2026) requires PHP 8.2+ and matches our Laravel baseline; 3.0.x continues to receive backports for PHP 7.4–8.1. BSD-3-Clause, no transitive dependencies, no framework coupling, no service provider to register. That makes it a low-friction item to bundle into a PHP-version upgrade epic rather than a standalone initiative.

  • What it should not drive. Treat this as infrastructure, not a differentiator. It does not unlock a new customer-facing capability on its own, and it should not appear on a roadmap slide as a feature. Frame it as risk reduction and technical-debt paydown inside an existing initiative.

  • Diligence caveat for the decision record. The package has ~297 stars and the registry reports zero dependents, which understates reality (its provenance is sabre/dav, and sabre/http before that — a long-lived, widely deployed codebase). Stars are a weak proxy here; the stronger signals are RFC-derived test coverage, PHPStan enforcement, Rector adoption, Dependabot, and a maintainer group still shipping in 2026. Still, this is a small-team project with a real bus-factor, mitigated by the fact that it is ~5 functions of pure PHP with no dependencies — we can fork and vendor it in an afternoon if the upstream ever stalls.

When to Consider This Package

Adopt when:

  • You need relative-URI resolution (resolve). Laravel's url() / UrlGenerator builds absolute URLs; it does not implement RFC3986 §5.2 reference resolution. If you are doing anything with crawled pages, HTML <base> tags, feed entries with relative links, or link rewriting, this is the gap it fills.
  • You need URI normalization for comparison (normalize). Laravel has no equivalent. Case-folding scheme/host, removing default ports, and dot-segment removal are exactly what allowlist checks and dedupe keys require.
  • parse_url() is demonstrably insufficient for your input population — non-ASCII paths, triple-slash URIs, file:// forms, Windows paths, or relative references with colons. Verify against your own data first; don't adopt speculatively.
  • You want split() (dirname/basename for URLs) and don't want to reason about pathinfo() quirks on query strings.
  • You want a tiny, dependency-free, framework-agnostic primitive that will still work if the surrounding stack changes, and you're comfortable calling namespaced functions (Splitshade\... — actually sabre\Uri\parse(), etc.) directly rather than injecting an interface.

Look elsewhere / don't adopt when:

  • You're on a recent Laravel and only need the basics. Illuminate\Support\Uri and the Url façade already cover parsing, query manipulation, and host/scheme inspection idiomatically. Adding a second URI library for cases Laravel handles creates two conventions in one codebase — worse than the problem.
  • You need object-modeled, rich URI values. league/uri gives you immutable component objects, PSR-7 interop, IDN/punycode handling, URI templates, and strict validation with precise exceptions. If you need IDN, templating ({var} expansion), data:/urn: handling, or per-component validation errors surfaced to users, league/uri is the right buy — sabre/uri will not get you there.
  • You need per-request mocking or DI. These are static global functions with no interface and no container binding. If your test strategy depends on swapping a URL resolver, wrap it in a thin first-party adapter — but at that point, ask whether the abstraction is earning its keep.
  • You need an HTTP message abstraction. guzzlehttp/psr7 and symfony/http-foundation already ship Uri classes; don't add a third if one is already in the tree.
  • Strict RFC validation with user-facing error messages is the requirement. parse() throws InvalidUriException, but this is a parsing library, not a validator with a rule/message API. Keep using Laravel validation rules for form-level feedback and use this only for the transformation layer.

Adoption gate before committing: inventory the actual call sites. If you cannot point to at least two or three places where parse_url() or custom string logic produces wrong or inconsistent output, the ROI is speculative and this should sit in the backlog.

How to Pitch It (Stakeholders)

To executives (30 seconds): We have URL-handling logic scattered across teams, written four or five different ways, and it has produced real bugs with non-English characters, relative links, and redirected URLs. This package replaces that with one small, standards-compliant, zero-dependency library that is already a de facto standard in the PHP ecosystem. It costs roughly a day or two of engineering, has no licensing or hosting cost, and directly reduces a security exposure (unvalidated redirects) while cleaning up a data-quality problem in our analytics. It is not a feature — it's a de-risking item we should fold into the next PHP upgrade or integration work already on the roadmap.

To engineering (the technical case):

  • Five functions, RFC3986-faithful, tested against the RFC's own examples: resolve (relative reference resolution), normalize (canonical comparison), parse (a parse_url() replacement that handles non-ASCII, triple-slash, and Windows paths), build, split (URL-safe dirname/basename).
  • No dependencies, no Laravel coupling, no service provider. Composer-install and call.
  • 3.1.0 targets PHP 8.2+ and matches our baseline; 3.0.x stays supported for older runtimes, so there's no forced upgrade cliff.
  • The real win is resolve and normalize — the two things neither parse_url() nor Laravel's Uri helper gives us. Everything else is incremental.
  • Trade-off to accept: namespaced functions, not injectable objects. We wrap them behind one small first-party service if we need test seams. And if we need IDN, URI templates, or rich component objects, we go to league/uri instead — this is deliberately the smaller tool.

Risks to name up front:

  • Small maintainer group and modest public visibility → bus-factor risk. Mitigation: it is ~5 functions of pure PHP with no dependencies and a permissive license; vendoring or forking is trivial.
  • Function-based API is less testable out of the box → mitigation: single thin adapter, adopted once, not per call site.
  • Behavioral changes have historically shipped as major versions (notably the Windows-path handling, which was deliberately reverted in 2.2.4 and re-landed in 3.0.0). Mitigation: pin the major version and read the changelog before any bump — treat this like any other dependency with a real upgrade policy, not like a utility we can float.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console