PHP gives you $_GET, parse_str() and http_build_query() for query strings, and they all follow one old format from RFC 1866. There's no built-in way to handle RFC 3986 query strings, or to work with a query string that didn't come from the current request. This RFC from Máté Kocsis adds a Uri\QueryParams class, building on the URI extension added in PHP 8.5.

The RFC also points to app servers like FrankenPHP and Swoole, where one PHP process handles many requests. There, $_GET is global state that has to be reset every time. A QueryParams object is immutable, so that problem goes away.

Show me

Here are a few of the RFC's examples:

$params = Uri\QueryParams::parseRfc3986("foo=bar&foo=baz&qux=quux");

echo $params->getFirst("foo");            // bar
echo $params->getLast("foo");             // baz

$params = Uri\QueryParams::parseRfc3986("foo=bar");
$params = $params->append("baz", "qux");
echo $params->toRfc3986String();          // foo=bar&baz=qux

And moving off $_GET:

// Before
$order = isset($_GET["order"]) ? (string) $_GET["order"] : null;

// After
$queryParams = Uri\QueryParams::parseRfc3986($_SERVER["QUERY_STRING"]);
$order = $queryParams->getFirst("order");

What you get

  • Three parsers: parseRfc1866(), parseRfc3986() and parseWhatWg(), plus fromArray() and an empty constructor.
  • Readers: has(), hasValue(), getFirst(), getLast(), getAll(), list() and count().
  • Modifiers: append(), set(), delete(), deleteValue() and sort(), each returning a new object.
  • Output: toRfc1866String(), toRfc3986String(), toWhatWgString() and toArray().
  • Type handling that works like http_build_query(). For example, true becomes "1".
  • Limits on length and number of parameters, with an exception when you go over.

It also fixes some $_GET surprises. Dots and spaces in names stay as they are instead of turning into underscores, and repeated names keep every value instead of just the last one.

What it means for existing code

Nothing breaks, and $_GET doesn't change. The RFC says superglobals should be phased out over time by offering better alternatives, not by changing them.

Where it stands

The RFC is under discussion. It's dated February 13, 2026, and the page targets the next version after PHP 8.6, likely PHP 8.7. The vote dates are still blank, and while a vote is set up on the page, no one has voted.