This RFC proposes a follow-up to the URL Parsing API RFC, extending the URI
and URL
classes with additional capabilities for constructing, analyzing, and manipulating URIs.
The goal is to provide a more complete and developer-friendly API for URI handling, consistent with both the WHATWG URL Standard and RFC 3986.
The following new functionality is introduced in this proposal:
A fluent API is introduced for programmatically constructing and modifying URIs:
$uri = (new UriBuilder()) ->scheme('https') ->host('example.com') ->path('/foo/bar') ->query(['a' => 1, 'b' => 2]) ->fragment('section1') ->build(); echo $uri; // "https://example.com/foo/bar?a=1&b=2#section1"
This builder makes URI creation and modification easier and less error-prone than manually concatenating strings or repeatedly invoking Uri::with*()
methods.
Design goals:
Uri
objects as the result
Uri
and Url
classes now expose getQueryParams()
/ setQueryParams()
methods for working directly with parsed query parameters:
$uri = new Uri('https://example.com/?foo=bar&x=1'); $params = $uri->getQueryParams(); $params['y'] = '2'; $uri = $uri->withQueryParams($params); echo $uri->getQuery(); // "foo=bar&x=1&y=2"
A dedicated UriQuery
helper object also offers a structured interface similar to JavaScript’s URLSearchParams
.
getPathSegments()
and withPathSegments()
provide convenient access to the path component as an array:
$uri = new Uri('https://example.com/foo/bar/baz'); $segments = $uri->getPathSegments(); // ['foo', 'bar', 'baz'] $uri = $uri->withPathSegments(['a', 'b']); echo $uri->getPath(); // "/a/b"
This is useful for frameworks and routers that manipulate paths dynamically.
The new getHostType()
method returns the type of the host component:
$uri = new Uri('https://192.168.0.1/'); echo $uri->getHostType(); // UriHostType::IPv4 $uri = new Uri('https://[2001:db8::1]/'); echo $uri->getHostType(); // UriHostType::IPv6 $uri = new Uri('https://example.com/'); echo $uri->getHostType(); // UriHostType::Domain
Possible return values include:
UriHostType::Domain
UriHostType::IPv4
UriHostType::IPv6
UriHostType::Opaque
UriHostType::None
The WHATWG URL Standard defines *special* schemes (http
, https
, ftp
, file
, ws
, wss
), which have distinct parsing and serialization rules.
The new isSpecial()
method allows checking this:
$url = new Url('https://example.com'); var_dump($url->isSpecial()); // true $url = new Url('custom:example'); var_dump($url->isSpecial()); // false
This enables low-level control for applications that need to mirror WHATWG behaviors in parsing or normalization.
Dedicated static methods provide precise control over percent-encoding and decoding according to RFC 3986 rules:
Uri::encodeComponent('a b'); // "a%20b" Uri::decodeComponent('a%20b'); // "a b"
These utilities respect the character sets defined in RFC 3986 and may later be extended to support application/x-www-form-urlencoded
semantics as used in HTML forms.
None.
All APIs are additive and live in the Uri
/ Url
namespaces without changing existing behavior.
PHP 8.6
What effect will the RFC have on IDEs, Language Servers (LSPs), Static Analyzers, Auto-Formatters, Linters and commonly used userland PHP libraries?
Will existing extensions be affected?
Describe the impact to CLI, Development web server, embedded PHP etc.
Make sure there are no open issues when the vote starts!
This section should outline areas that you are not planning to work on in the scope of this RFC, but that might be iterated upon in the future by yourself or another contributor.
This helps with long-term planning and ensuring this RFC does not prevent future work.
After the RFC is implemented, this section should contain:
Links to external references, discussions, or RFCs.
Keep this updated with features that were discussed on the mail lists.
If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.