league/uri-interfaces
RFC 3986-compliant URI interfaces for PHP 8.1+. Defines contracts for URI objects and related components used across the League URI ecosystem. Supports IDN hosts (intl or polyfill) and IPv4 conversion (GMP/BCMath/64-bit).
Installation:
composer require league/uri-interfaces
Ensure PHP ≥ 8.1 and required extensions (intl, GMP, or BCMath) are installed.
First Use Case: Validate a URI string or parse it into components:
use League\Uri\Contracts\UriInterface;
use League\Uri\UriString;
$uriString = new UriString('https://example.com/path?query=value');
$uri = $uriString->parse(); // Returns UriInterface
// Access components
echo $uri->getScheme(); // "https"
echo $uri->getHost(); // "example.com"
Key Classes to Explore:
UriString: Parse/validate strings.UriInterface: Core URI operations (e.g., resolve(), relativize()).QueryString: Parse/query string manipulation.HostRecord: Validate/normalize hosts (e.g., isValid(), isSubdomainOf()).$uriString = new UriString($rawUri);
if ($uriString->isValid()) {
$uri = $uriString->parse();
// Work with $uri (UriInterface)
}
$uriString->isValidScheme('https'); // Check scheme validity
$uriString->isValidHost('example.com'); // Validate host
$query = new QueryString('key=value&foo=bar');
$query->compose(['new_key' => 'new_value']); // Build query string
$query->extract(); // Parse into key-value pairs
$query->toFormData(); // Convert to array
QueryString::fromFormData(['key' => 'value']); // Create from array
$baseUri = (new UriString('https://example.com/base'))->parse();
$relativeUri = (new UriString('path/to/resource'))->parse();
$resolved = $baseUri->resolve($relativeUri); // Full URI
$baseUri->relativize($resolvedUri); // Relative path
$host = new HostRecord('sub.example.com');
$host->isSubdomainOf('example.com'); // true
use League\Uri\IPv4\Converter;
Converter::toIPv6Using6to4('192.168.1.1'); // IPv6 representation
$encoder = new Encoder();
$encoder->normalizePath('/path with spaces'); // RFC3986-encoded
$encoder->decodeNecessary('%20'); // Decodes to ' '
use Illuminate\Http\Request;
$uri = new UriString(request()->getUri());
// Manipulate URI components before processing.
$uri = route('profile', ['user' => 'john']);
$uriString = new UriString($uri);
// Validate or modify before redirecting.
$this->assertTrue($uriString->isValid());
$this->assertEquals('https', $uri->getScheme());
$this->assertEquals(['key' => 'value'], $query->extract());
IDN Hosts Without intl Extension:
MissingFeature if intl or a polyfill (e.g., symfony/polyfill-intl-idn) is missing.intl or add the polyfill to composer.json:
composer require symfony/polyfill-intl-idn
IPv4 Conversion Requirements:
GMP, BCMath, or 64-bit PHP. Throws ConversionFailed otherwise.Query String Parsing Quirks:
QueryString::extract() may misparse malformed queries (e.g., key=&value).QueryComposeMode::STRICT for strict parsing:
$query->extract(QueryExtractMode::STRICT);
Host Validation Strictness:
HostRecord::isValid() rejects IPv4 addresses without port numbers (e.g., 192.168.1.1).HostType::IPV4 for explicit validation:
$host->isValid(HostType::IPV4);
URI Resolution Edge Cases:
UriInterface::resolve() may fail with circular references or malformed URIs.isValid() before resolving.Deprecated Methods:
UriInterface::getComponents() (use toComponents()).QueryInterface::withoutPair() (use withoutPairByKey()).Component Inspection:
$uri->toComponents(); // Associative array of all components
$uri->toNormalizedString(); // Canonical string representation
Query String Debugging:
$query->composeFromValue(['key' => ['nested' => 'value']], QueryComposeMode::STRICT);
// Outputs: key[nested]=value
Host Resolution:
$host = new HostRecord('example.com');
$host->isValid(); // true
$host->encoded(); // RFC3986-encoded host
Custom Query Composition:
QueryString by implementing QueryComposeMode enums for custom separators/encodings.Host Validation Logic:
HostRecord::isValid() for custom domain rules (e.g., allow local IPs).URI Normalization:
Transformable for custom URI transformations (e.g., rewrite schemes).Encoding Strategies:
Encoder subclass to override normalization rules.HostRecord caches DNS lookups. Disable with:
$host = new HostRecord('example.com', false); // Disable caching
QueryExtractMode::LOOSE for faster (but less strict) parsing.Middleware URI Manipulation:
public function handle(Request $request, Closure $next) {
$uri = new UriString($request->getUri());
if ($uri->getHost() === 'admin.example.com') {
$uri->withHost('internal-admin.example.com');
$request->setRequestUri($uri->toString());
}
return $next($request);
}
Route Model Binding:
public function bindRequest(Route $route, $value) {
$uri = new UriString($value);
return User::where('slug', $uri->getPath())->firstOrFail();
}
API Response URIs:
return response()->json($data, 200, [
'Location' => (new UriString(url('/resource')))->toString()
]);
How can I help you explore Laravel packages today?