league/uri-components
Immutable value objects for concrete URI components (host, path, query, etc.) in the League URI ecosystem. Requires PHP 8.1+. Supports IDN hosts with intl (or polyfill) and IPv4 conversion via GMP/BCMath or 64-bit PHP.
Installation:
composer require league/uri-components
Requires PHP 8.1+ and extensions like intl (for IDN) or GMP/BCMath (for IPv4).
First Use Case: Parse and manipulate a URL:
use League\Uri\Components\Uri;
$uri = Uri::createFromString('https://example.com/path?query=value#fragment');
$scheme = $uri->scheme(); // Returns "https"
$host = $uri->host(); // Returns "example.com"
Key Classes to Explore:
Uri (top-level container)Query (for query strings)Modifier (for fluent URI modifications)Domain, Path, Fragment (individual components)// From string
$uri = Uri::createFromString('https://api.example.com/v1/users?id=123');
// From components
$uri = Uri::create()
->withScheme('https')
->withHost('api.example.com')
->withPath('/v1/users')
->withQuery('id=123');
$query = $uri->query();
$query->with('page', 2); // Append/update
$query->without('sort'); // Remove
$query->appendList('tags', ['php', 'laravel']); // Handle arrays
Modifier$modifiedUri = $uri->modifier()
->withPath('/v2/users')
->appendQuery('limit=10')
->redactUserInfo()
->toUri();
$domain = $uri->host()->domain();
$domain->isSubdomainOf('example.com'); // true
$path = $uri->path();
$path->prepend('api/'); // "/api/v1/users"
$uri->scheme()->isHttp(); // true
$uri->host()->normalized(); // IDN/ASCII conversion
Request URI Handling:
use League\Uri\Components\Uri;
use Illuminate\Http\Request;
$requestUri = Uri::createFromString(request()->getUri());
$query = $requestUri->query()->all(); // Convert to array
Route Generation:
$uri = Uri::create()
->withScheme('https')
->withHost(config('app.url'))
->withPath(route('users.index'));
Form Data to Query:
$query = Query::fromFormData(request()->all());
$uri->withQuery($query);
use League\Uri\Components\Modifier;
use Psr\Http\Message\UriInterface;
$modifier = Modifier::wrap($psr7Uri);
$modifiedPsr7Uri = $modifier->withPath('/new-path')->unwrap();
Immutable Objects:
All components (e.g., Query, Path) are immutable. Use modifier methods (e.g., with(), append()) to create new instances.
// ❌ Won't work (no setter)
$query->set('key', 'value');
// ✅ Correct
$newQuery = $query->with('key', 'value');
Query String Encoding:
Use Query::encoded() or Modifier::encodeQuery() for safe URL encoding.
$query->with('search', 'Laravel & PHP')->encoded();
// Output: "search=Laravel+%26+PHP"
IDN Hosts:
Requires intl extension or symfony/polyfill-intn-idn. Fallback to ASCII if unavailable.
try {
$uri->withHost('例子.测试'); // IDN
} catch (\InvalidArgumentException $e) {
// Handle missing intl
}
Path Segments:
Leading/trailing slashes matter. Use Path::normalized() to standardize.
$path = Path::create('/users/')->normalized(); // "/users"
Backward Compatibility:
Methods like Modifier::uri() are deprecated. Use Modifier::unwrap() or Modifier::toUri().
Inspect Components:
$uri->toString(); // Full URI
$uri->query()->all(); // Query as array
$uri->path()->segments(); // ["users", "123"]
Query Validation:
$query->has('page'); // Check existence
$query->get('page', 1); // Default value
Modifier Debugging:
Use Modifier::wrap() to inspect intermediate states:
$modifier = Modifier::wrap($uri);
$modifier->withPath('/debug')->toString();
Custom Query Parsing:
Override Query::fromString() or use Query::fromPairs() with custom logic.
Domain Validation:
Extend Domain to add custom rules (e.g., regex validation).
Modifier Chaining: Create reusable modifier chains:
$modifier = Modifier::wrap($uri)
->withScheme('https')
->withHost('api.example.com')
->appendPath('/v1');
PSR-7 Bridge:
Use Modifier::wrap() to integrate with frameworks like Lumen or Symfony.
Route Parameters:
Use Uri::create()->withPath(route('name', $params)) to avoid manual string concatenation.
Asset URLs:
Combine with Laravel’s asset() helper:
$uri = Uri::create()->withPath(asset('images/logo.png'));
Redirects:
return redirect()->to(
Uri::create()
->withScheme('https')
->withHost(request()->getHost())
->withPath('/new-location')
);
How can I help you explore Laravel packages today?