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.
Installation:
composer require league/uri
Requires PHP 8.1+ and extensions: intl (for IDN), dom (for HTML), and either GMP, BCMath, or 64-bit PHP (for IPv4).
First Use Case: Parse and manipulate a URI:
use League\Uri\Uri;
$uri = Uri::new('https://example.com/path?query=value');
echo $uri->getHost(); // "example.com"
echo $uri->getPath(); // "/path"
Key Classes:
Uri: Core class for URI manipulation (RFC 3986).Http: PSR-7 compliant HTTP URI subclass.UriTemplate: For URI template expansion (RFC 6570).Urn: For URN (Uniform Resource Name) handling (RFC 8141).Documentation: Start with the official docs for API references and examples.
$uri = Uri::new('https://example.com');
$uri = Uri::fromComponents([
'scheme' => 'https',
'host' => 'example.com',
'path' => '/api/v1',
]);
$_SERVER):
$uri = Uri::fromServer($_SERVER);
$newUri = $uri->withPath('/new-path');
$newUri = $uri->withQuery(['key' => 'value']);
$baseUri = Uri::new('https://example.com/base');
$relativeUri = Uri::new('/relative');
$resolved = $baseUri->resolve($relativeUri);
// Resolves to: https://example.com/relative
$normalized = $uri->normalize(); // Decodes %-encoded chars, normalizes paths.
$template = UriTemplate::new('https://api.example.com/{user}');
$uri = $template->expand(['user' => 'john-doe']);
// Expands to: https://api.example.com/john-doe
$uri = Uri::new('https://example.com')
->when($isAdmin, fn($u) => $u->withPath('/admin'))
->when($isGuest, fn($u) => $u->withPath('/guest'));
$httpUri = Http::new('https://example.com');
$psr7Uri = $httpUri->toPsr7Uri(); // Returns a PSR-7 UriInterface.
$isSameOrigin = $uri->isSameOrigin($otherUri);
$isCrossOrigin = $uri->isCrossOrigin($otherUri);
if ($uri->getScheme() === 'https') { ... }
$uri->isIpv4Host(); // true/false
$uri->isDomainHost(); // true/false
$uri->isSameDocument($otherUri); // Ignores fragment.
$uri->equals($otherUri); // Includes fragment.
use Illuminate\Http\Request;
$uri = Uri::fromServer(request()->server());
$routeUri = Uri::new(route('profile', ['user' => 'john']));
return redirect()->to($uri->toString());
$template = UriTemplate::new('https://api.example.com/v1/{resource}/{id}');
$uri = $template->expand(['resource' => 'users', 'id' => 123]);
$fileUri = Uri::fromFileContents(__FILE__);
$fileUri->isLocalFile(); // true
Register a global URI helper:
// app/Providers/AppServiceProvider.php
use League\Uri\Uri;
use Illuminate\Support\Facades\URL;
public function boot()
{
URL::macro('parse', function ($uri) {
return Uri::parse($uri);
});
}
Usage:
$uri = URL::parse('https://example.com');
Validate URIs in Laravel forms:
use League\Uri\Uri;
use Illuminate\Validation\Rule;
$request->validate([
'redirect_url' => [
'required',
Rule::function('valid_uri', function ($attribute, $value) {
return Uri::tryNew($value) !== null;
}),
],
]);
Set Location headers with URIs:
return response()->header('Location', $uri->toString())->setStatusCode(302);
Generate cache keys from URIs:
$cacheKey = 'uri:' . md5($uri->toAsciiString());
Mock URIs in tests:
$mockUri = Mockery::mock(Uri::class);
$mockUri->shouldReceive('getHost')->andReturn('test.com');
withPath() return a new instance.
$uri->withPath('/new'); // Does NOT modify $uri!
$uri = $uri->withPath('/new');
intl extension throws exceptions for non-ASCII hosts (e.g., 例子.测试).intl or use a polyfill like symfony/polyfill-intl-idn:
composer require symfony/polyfill-intl-idn
[2001:db8::1]).Uri::new('http://[2001:db8::1]') or validate with:
$uri->isIpv6Host();
normalize() or Uri::fromComponents() for consistency:
$uri = Uri::fromComponents(['path' => '/path/to/resource']);
withQuery() with an ordered array:
$uri->withQuery(['page' => 1, 'sort' => 'asc']);
isSameDocument() ignores fragments, while equals() includes them.$uri->isSameDocument($otherUri); // Ignores #fragment
$uri->equals($otherUri); // Considers #fragment
Uri::fromBaseUri).// Old (deprecated)
Uri::fromBaseUri($base, $relative);
// New
$base->resolve($relative);
Http class is PSR-7 compliant but may behave differently than Uri.Http for HTTP-specific logic and Uri for general cases.How can I help you explore Laravel packages today?