league/uri
League URI provides simple, intuitive PHP 8.1+ classes to parse, validate, normalize, and manipulate URIs and related components. Supports PSR-7 interoperability, IDN hosts (intl/polyfill), IPv4 conversion, and HTML URI handling.
Strengths:
Psr\Http\Message\UriInterface), enabling seamless integration with frameworks like Laravel HTTP clients (e.g., Guzzle), middleware, and routing systems.withPath(), withQuery()) mirrors Laravel’s immutable collections and request objects, reducing side effects in stateful operations.UriTemplate enables dynamic URL generation (e.g., API endpoints with query parameters), useful for Laravel’s API resource routes or dynamic redirects.isIpv4Host(), isDomainHost() add robustness to Laravel’s validation logic (e.g., form submissions, webhook endpoints).isSameOrigin(), isCrossOrigin() simplify CORS policy enforcement in Laravel middleware or API gateways.Gaps:
UrlGenerator or Request object (e.g., no direct route() helper support). Requires manual bridging.file:// URI to a local filesystem path in Laravel’s storage system).Uri::resolved or Uri::invalid), though this could be layered via middleware.Laravel Stack Compatibility:
HttpClient via PSR-7/PSR-17 interfaces.Illuminate\Routing\UrlGenerator for advanced URI manipulation (e.g., path normalization, template expansion).Validator for URI-specific rules (e.g., uri|domain validation).HttpTests and Pest/PHPUnit for URI assertion logic.Migration Path:
url()->to() for dynamic routes).league/uri for complex cases (e.g., URI templates) while leveraging Laravel’s built-in methods for simplicity.Key Dependencies:
intl (for IDN) or polyfills (symfony/polyfill-intl-idn), which may need PHP configuration updates.Breaking Changes:
BaseUri (deprecated in v7.6.0) may require refactoring if used in legacy code.Request) may throw exceptions if URI objects don’t fully comply with PSR-7 (e.g., path normalization).Performance:
Edge Cases:
intl extension; fallback polyfills may introduce subtle bugs (e.g., host validation).UrlGenerator handles relative paths differently; manual resolution (e.g., Uri::resolve()) may be needed.toDisplayString() (IRI output) or normalize() (destructive operations) must be audited for XSS or open-redirect risks.Use Case Prioritization:
UrlGenerator entirely, or supplement it for specific cases (e.g., URI templates)?Team Readiness:
intl, GMP) that block adoption?Testing Strategy:
file:// URIs or IPv6 hosts.)league/uri for consistency?Long-Term Maintenance:
Alternatives:
Illuminate\Support\Str::of() or Illuminate\Routing\UrlGenerator suffice?symfony/ux-uri (Symfony’s URI component) a better fit for Laravel’s ecosystem?Laravel Ecosystem:
UriInterface) and Symfony’s HttpClient.UrlGenerator for advanced use cases (e.g., URI templates, path normalization).Validator for custom URI rules (e.g., uri|domain|ipv4).HttpTests and Pest/PHPUnit for URI assertions.Non-Laravel Dependencies:
intl (for IDN) or polyfills (symfony/polyfill-intl-idn), which may need PHP configuration updates.Conflict Areas:
UrlGenerator trims leading slashes in paths, while league/uri preserves them (e.g., /path vs. path). Decide on a canonical approach.Uri::resolve()) may be needed.TrustProxies middleware may conflict with Uri::isSameOrigin() logic.| Phase | Action Items | Dependencies | Risk |
|---|---|---|---|
| Assessment | Audit existing URI handling (e.g., UrlGenerator, Request objects). |
Laravel codebase | Low |
| Validation | Replace manual URI validation (e.g., regex) with league/uri methods. |
league/uri, Laravel Validator |
Medium (edge cases) |
| Generation | Use UriTemplate for dynamic routes (e.g., API endpoints with query params). |
Laravel Route service |
Low |
| Normalization | Add middleware to normalize incoming URIs (e.g., decode paths, reject unsafe schemes). | Laravel middleware pipeline | Medium (performance impact) |
| Testing | Write tests for URI parsing, validation, and generation. | Pest/PHPUnit | Low |
| Full Replace | Replace UrlGenerator with league/uri for all URI operations. |
Laravel UrlGenerator |
High (breaking changes) |
How can I help you explore Laravel packages today?