PHP has had parse_url() for a long time, but it doesn't follow any URL standard, and even the PHP manual warns that it may return wrong results. That can cause bugs, and even security holes when two tools interpret the same URL differently. This RFC from Máté Kocsis adds a new, always-available URI extension that follows two standards: RFC 3986, the general standard for URIs, and the WHATWG URL standard that browsers use.
Show me
There's one class for each standard. Here are some of the RFC's examples:
$uri = new Uri\Rfc3986\Uri("https://example.com"); // throws on a bad URI $uri = Uri\Rfc3986\Uri::parse("invalid uri"); // returns null instead $url = new Uri\WhatWg\Url("HTTPS://////EXAMPLE.com"); echo $url->toAsciiString(); // https://example.com/ $uri = new Uri\Rfc3986\Uri("https://example.com"); echo $uri->resolve("/foo")->toString(); // https://example.com/foo
What you get
- Two classes,
Uri\Rfc3986\UriandUri\WhatWg\Url. Keeping them separate forces you to say which standard you mean. - Two ways to parse. The constructor throws an exception on invalid input, while
parse()returnsnull. The RFC suggestsparse()for untrusted input. - Getters for each component, like
getScheme(),getHost(),getPath()andgetQuery(). The RFC 3986 class also has "raw" versions that return each component exactly as written. - Withers like
withHost(), which return a new object and leave the original alone, since the objects are immutable. equals()to compare two URIs, with or without the#fragment.- Error details. The WHATWG class reports what went wrong through
UrlValidationErrorobjects. - Unicode hosts. The WHATWG class can output a host as ASCII or Unicode with
toAsciiString()andtoUnicodeString().
PHP itself can use the new parsers too. For example, FILTER_VALIDATE_URL, SoapClient and the FTP stream wrapper get an option to choose one.
The RFC 3986 side uses the uriparser library, and the WHATWG side uses Lexbor, which PHP already bundles for HTML5 parsing. Both are written in C, and the RFC says they're slightly slower than parse_url(), but not by much.
What it means for existing code
parse_url() still works. There's one small break: SoapClient::__doRequest() gets a new $uriParserClass parameter, so if you override that method, you need to add it.
The vote
It passed 30 to 1, clearing the two-thirds majority it needed. The poll offered only yes and no, and voting closed on May 22, 2025. It was proposed for PHP 8.5, and the page marks it as implemented.