league/uri-interfaces
Interface definitions for RFC 3986-compliant URI objects. Targets PHP 8.1+, with optional intl (or polyfill) for IDN handling and GMP/BCMath or 64-bit PHP for IPv4 conversion. Part of the League URI project; docs at uri.thephpleague.com.
Installation:
composer require league/uri-interfaces
Requires PHP 8.1+ and extensions like intl (for IDN) or GMP/BCMath (for IPv4/IPv6).
First Use Case: Parse a URI string 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
Key Classes to Explore:
UriString: Parses/validates URI strings.UriInterface: Core URI contract (scheme, host, path, etc.).QueryString: Handles query parameters.HostRecord: Normalizes host resolution (e.g., example.com).UriString for parsing and validation.
$uriString = new UriString('https://user:pass@example.com:8080/path?query=value#frag');
$uri = $uriString->parse(); // Throws \League\Uri\Exception\SyntaxError if invalid
if ($uriString->isValid()) {
$uri = $uriString->parse();
}
QueryString for query manipulation.
$query = new QueryString('key1=value1&key2=value2');
$query->addPair('key3', 'value3'); // Adds a new pair
$query->withoutPairByKey('key1'); // Removes a pair
$queryString = $query->toString(); // 'key2=value2&key3=value3'
$formData = ['key1' => 'value1', 'key2' => ['sub1', 'sub2']];
$query = QueryString::fromFormData($formData);
HostRecord for host normalization and domain checks.
$host = new HostRecord('sub.example.com');
$host->isSubdomainOf('example.com'); // true
$host->parentHost(); // 'example.com'
use League\Uri\IPv4\Converter;
use League\Uri\IPv6\Converter;
$ipv4 = Converter::toDecimal('192.168.1.1'); // 3232235777
$ipv6 = Converter::normalize('2001:db8::1'); // '2001:db8:0:0:0:0:0:1'
$baseUri = (new UriString('https://example.com/base/'))->parse();
$relativeUri = (new UriString('subpath'))->parse();
$resolvedUri = $baseUri->resolve($relativeUri); // 'https://example.com/base/subpath'
$resolvedUri->relativize($baseUri); // 'subpath'
Encoder for component-specific encoding.
use League\Uri\Encoder;
$encoder = new Encoder();
$encodedPath = $encoder->encodePath('/path with spaces'); // '/path%20with%20spaces'
$decodedPath = $encoder->decodePath($encodedPath); // '/path with spaces'
// In a Laravel service provider:
$this->app->bind(
UriInterface::class,
fn() => (new UriString(request()->fullUrl()))->parse()
);
use League\Uri\Contracts\UriInterface;
$uri = app(UriInterface::class);
$query = $uri->getQuery(); // QueryString object
UriInterface for unit tests.
$mockUri = Mockery::mock(UriInterface::class);
$mockUri->shouldReceive('getScheme')->andReturn('https');
$mockUri->shouldReceive('getHost')->andReturn('example.com');
IDN (Internationalized Domain Names):
intl extension or symfony/polyfill-intl-idn.League\Uri\Exception\MissingFeature if unsupported.composer require symfony/polyfill-intl-idn
IPv4/IPv6 Conversion:
GMP, BCMath, or 64-bit PHP.League\Uri\Exception\ConversionFailed if unsupported.Query String Parsing:
QueryString::extract() may behave unexpectedly with malformed input (e.g., key=value&key=).QueryComposeMode::RFC3986 for strict RFC compliance.Host Validation:
HostRecord::isValid() rejects IPv4/IPv6 without ports (e.g., 192.168.1.1 is invalid; 192.168.1.1:80 is valid).HostType::IPV4 or HostType::IPV6 explicitly.Deprecated Methods:
UriInterface::getComponents() (use toComponents() instead).QueryInterface::withoutPair() (use withoutPairByKey()).Stringable Support:
UriString::parseAuthority()) accept Stringable objects (PHP 8.0+).Stringable objects directly without casting to strings.Caching:
HostRecord caches DNS resolutions. Clear cache manually if needed:
$hostRecord = new HostRecord('example.com');
$hostRecord->clearCache();
Validate URIs Early:
if (!$uriString->isValid()) {
throw new \InvalidArgumentException('Invalid URI: ' . $uriString->getError());
}
Inspect Components:
$uri = $uriString->parse();
dd($uri->toComponents()); // Associative array of all components
Query Debugging:
QueryString::toFormData() to inspect parsed query parameters:
$query = new QueryString('key1=value1&key2[]=val1&key2[]=val2');
dd($query->toFormData());
// Output: ['key1' => 'value1', 'key2' => ['val1', 'val2']]
Host Debugging:
$host = new HostRecord('example.com');
dd($host->getType(), $host->getFormat());
Custom Query Composers:
QueryString by implementing QueryComposeMode:
$query = new QueryString('key=value');
$query->compose(['key' => 'newValue'], QueryComposeMode::RFC3986);
Custom Encoders:
League\Uri\Contracts\EncoderInterface for custom encoding rules.Domain Logic:
DomainHostInterface for custom domain checks (e.g., TLD validation):
class CustomDomainHost implements DomainHostInterface {
public function isValid(): bool {
// Custom validation logic
}
}
URI Normalization:
UriInterface::toNormalizedString() for project-specific normalization.Cache Host Resolutions:
HostRecord caches DNS lookups. Reuse instances for repeated host checks.Avoid Parsing Repeatedly:
UriInterface object:
How can I help you explore Laravel packages today?