Uri\QueryParams query parameter proposal
Under discussion; not accepted. The RFC page (version 1.0, dated 2026-02-13, last edited 2026-10-06 at 13:08 UTC according to the wiki's change feed) and the official RFC index both list it as Under Discussion. It proposes the "next minor version after PHP 8.6 (likely PHP 8.7)". Acceptance would need a 2/3 majority.
The proposal was split out of the accepted
ext/uri follow-up RFC and builds on the URI extension
that PHP 8.5 added (Uri\Rfc3986\Uri and
Uri\WhatWg\Url). It would add one immutable class, Uri\QueryParams, that stores query
parameters as an ordered list of name-value pairs, with no global request state. It has:
- parsers for RFC 1866 form encoding, RFC 3986 and the WHATWG URL rules, plus
fromArray(). Parsing percent-decodes the input. It does not require a syntactically valid query component; strings are percent-encoded again when the to*String() methods recompose them; getFirst(),getLast(),getAll()andlist()retrieval, and modifiers (append(),set(),delete(),sort()) that return new instances;- default parsing limits of 10,000 input bytes and 1,000 parameters. These can be configured,
and exceeding them throws
Uri\InvalidQueryParamsException; - configurable mappings for boolean values and a
Uri\QueryParamNullPolicyenum fornullvalues (SkipTuple,KeyOnlyas the default,EmptyString), and an array API for PHP's bracket notation.toArray()takes a nesting limit (default 64). The RFC saystoArray()is not a general inverse offromArray(); getQueryParams()andwithQueryParams()methods onUri\Rfc3986\UriandUri\WhatWg\Url;- different empty-field rules per parser.
parseRfc1866()andparseRfc3986()keep empty fields (for example the one after a trailing&) and give a field without=anullvalue.parseWhatWg()drops empty fields and gives such a field an empty string. The RFC says that recomposing and reparsing a list is not guaranteed to reproduce every possible list.
The RFC presents the class as an alternative to $_GET, which it does not propose to change.
It lists the differences someone migrating would see: $_GET replaces dots and spaces in
names with underscores, keeps only the last value of a repeated name, and drops input beyond
max_input_vars with a warning. QueryParams keeps the names as given, keeps all
occurrences, and throws when its own limit is exceeded. The RFC states that the change is
backward compatible.
Evidence and limitations
- The implementation, php-src PR #22551, was an open draft when checked on 2026-10-04. It was last updated 2026-07-05.
- The discussion thread opened in February. Its newest public message was dated 2026-07-16 when checked on 2026-10-04, and no reply mentions the 1, 3 or 4 October page edits. The wiki revision history requires a login, so what those edits changed is unknown. After the 4 October edit, the status, version, open issues ("None"), parsing limits and the vote placeholder were unchanged.
- The wiki change feed shows another edit on 2026-10-06 at 09:21 UTC; the internals feed has no new message on the thread. Afterwards the header still read version 1.0, Under Discussion, and the default parsing limits were still 10,000 bytes and 1,000 parameters. The page and its raw export were truncated at 18,000 characters, so the open issues and vote block were not re-checked.
- The page's vote block still has placeholder dates ("2026-xx-xx") and is marked closed, but its widget carries a 2026-10-30 close date. This page treats the vote as not opened; a close date in a template is not a vote announcement.
- The opening message noted unresolved points (the array API, and whether the class should be
readonly). The current page lists no open issues and declares the class
final readonly. - On 2026-10-06 at 13:37 UTC the author posted a changelog
of the reworked RFC: readonly class,
QueryParamNullPolicyreplacing a boolean option, parsing limits applying only during parsing with the nesting limit belonging totoArray(), documented type conversions, decided array-API questions, the Uri/Url integration methods and specified handling of empty fields, malformed percent-encoding and invalid UTF-8. The author wrote that they would like to "bring this proposal to a vote as soon as possible (but not sooner)". No vote has been announced. The null-policy enum,toArray()nesting default and Uri/Url methods were checked on the page; the rest of the changelog was not checked individually because the page is truncated at 18,000 characters. - The wiki change feed shows a further edit on 2026-10-08 at 11:44 UTC, with no edit summary and no new message on the thread. Afterwards the header still read version 1.0, dated 2026-02-13, Under Discussion, with PR #22551 as the implementation, and the default parsing limits were unchanged. What the edit changed is unknown, and no vote has been announced.
- On 2026-10-09 at 12:05 UTC Tim Düsterhus posted a 14-point review
of the reworked RFC. They called most points minor and said they are "super happy" with the RFC. The
suggestions include: dropping
$maxQueryStringLength(a manualstrlen()check is enough) and perhaps turning the parameter-count limit into a plain argument; passing building options to theto*()methods instead of storing them; droppingparseRfc3986(), because RFC 3986 does not define query-parameter handling; renamingparseWhatWg()to something likeparseUrlSearchParams(); questioninghasValue(),deleteValue()andwithArray(); and noting that the backward compatibility section should mention the new class name in theUrinamespace. They also called accepting invalid percent-encoding sequences risky, without describing a concrete issue. No author reply or page change was seen by 16:02 UTC.
Related: support windows.