rfc:uri_followup

PHP RFC: ext/uri followups

Introduction

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.

Proposal

The following new functionality is introduced in this proposal:

  1. URI builder
  2. Query string manipulation
  3. Retrieving/modifying path segments as an array
  4. Retrieving the host type
  5. Determining if the URL is “special” (per WHATWG)
  6. Dedicated percent-encoding/decoding support

URI Builder

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:

  • Immutable Uri objects as the result
  • Chainable fluent syntax
  • Automatic percent-encoding of each component
  • Validation of scheme, host, and port consistency

Query String Manipulation

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.


Path Segments as an Array

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.


Host Type Detection

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

Determining if a URL is Special

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.


Percent-Encoding and Decoding

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.


Backward Incompatible Changes

None.

All APIs are additive and live in the Uri / Url namespaces without changing existing behavior.

Proposed PHP Version(s)

PHP 8.6

RFC Impact

To the Ecosystem

What effect will the RFC have on IDEs, Language Servers (LSPs), Static Analyzers, Auto-Formatters, Linters and commonly used userland PHP libraries?

To Existing Extensions

Will existing extensions be affected?

To SAPIs

Describe the impact to CLI, Development web server, embedded PHP etc.

Open Issues

Make sure there are no open issues when the vote starts!

Future Scope

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.

Voting Choices

Implement the ext/uri additions as outlined in the RFC?
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Patches and Tests

Implementation

After the RFC is implemented, this section should contain:

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Links to external references, discussions, or RFCs.

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

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.

rfc/uri_followup.txt · Last modified: by kocsismate