Re: [RFC] [Discussion] Followup Improvements for ext/uri

From: Date: Sun, 21 Dec 2025 15:51:18 +0000
Subject: Re: [RFC] [Discussion] Followup Improvements for ext/uri
References: 1 2 3 4 5 6 7 8 9 10  Groups: php.internals 
Request: Send a blank email to internals+get-129669@lists.php.net to get a copy of this message
On Sun, Dec 21, 2025 at 1:13 PM Máté Kocsis <kocsismate90@gmail.com> wrote: > Hi Ignace, > > >> When I talk about data mangling I am talking about this > > >> parse_str('foo.bar=baz', $params); >> var_dump($params); //returns ['foo_bar' => 'baz'] > > > Sure! I just wanted to point it out that name mangling will still be > present due to arrays, and this will have some disadvantages, > namely that adding params and retrieving them won't be symmetric: > > $params = new Uri\Rfc3986\UriQueryParams() > ->append("foo", [2 => "bar", 4 => "baz"]); > > var_dump($params->getFirst("foo")); // NULL > > One cannot be sure if a parameter that was added can really be retrieved > later via a get*() method. > > Another edge cases: > > $params = new Uri\Rfc3986\UriQueryParams() > ->append("foo", ["bar", "baz"]) > // Value is a > list, so "foo" is added without brackets > ->append("foo", [2 => "qux", 4 => "quux"]); // > Value is an array, > so "foo" is added with brackets > > var_dump($params->toRfc3986String()); // > foo=bar&foo=baz&foo%5B2%5D=qux&foo%5B4%5D=quux > > var_dump($params->getLast("foo")) // Should it be > "baz" > or "quux"? > var_dump($params->getAll("foo")) // Should it only > include the params with name "foo", or also "foo[]"? > > And of course this behavior also makes the implementation incompatible > with the WHATWG URL specification: although I do think this part of > the specification is way too underspecified and vague, so URLSearchParams > doesn't seem well-usable in practice... > > So an idea that I'm now pondering about is to keep the append() and set() > methods compatible with WHATWG: and they would only support > scalar values, therefore the param name wasn't mangled. And an extra > appendArray() and setArray() method could be added that would possible > mangle the param names, and they would only support passing arrays. This > solution would hopefully result in a slightly less surprising > behavior: one could immediately know if a previously added parameter is > really retrievable (when append() or set() was used), or extra > checks may be needed (when using appendArray() or setArray()). > > >> This to me should yield the same result as ->append('foo', null); as the >> array construct is only indicative of a repeating parameter name >> if there is no repeat then it means no data is attached to the name. > > > Alright, that seems the least problematic solution indeed, and > http_build_query() also represents empty arrays just like null values > (omitting them). > > So in your implementation it would mean: >> >> allowed type: null, int, float, string, boolean, and Backed Enum (to >> minic json_encode and PHP8.4+ behaviour) >> arrays with values containing valid allowed type or array. are also >> supported to allow complex type support. >> >> Any other type (object, resource, Pure Enum) are disallowed they should >> throw a TypeError >> > > +1 > > >> Maybe in the future scope of this RFC or in this RFC depending on how you >> scope the RFC you may introduce an Interface which will allow serializing >> objects using a representation that >> follows the described rules above. Similar to what the >> JsonSerializable interface is for json_encode. >> > > Hm, good idea! I'm not particularly interested in this feature, but I > agree it's a good way to add support for objects. > > Last but not Last, all this SHOULD not affect how http_buid_query works. >> The function should never have been modified IMHO so it should be left >> untouched by all this except if we allow it >> to opt-in the behaviour once the interface is approved and added to PHP. >> > > +1 > > Regards, > Máté > > Hi Máté, And an extra appendArray() and setArray() method could be added that would > possible > mangle the param names, and they would only support passing arrays. This > solution would hopefully result in a slightly less surprising > behavior: one could immediately know if a previously added parameter is > really retrievable (when append() or set() was used), or extra > checks may be needed (when using appendArray() or setArray()). I believe adding the appendArray and setArray is the way forward as the bracket addition and thus mangling is really a PHP specificity that we MUST keep to avoid hard BC. I would even go a step further and add a getArray and hasArray methods which will lead to the following API $params = (new Uri\Rfc3986\UriQueryParams()) ->append("foo", ["bar", "baz"]) // Value is a list, so "foo" is added without brackets ->appendArray("foo", ["qux", "quux"]); // Value is a list, using PHP serialization "foo" is added with brackets var_dump($params->toRfc3986String()); // foo=bar&foo=baz&foo%5B0%5D=qux&foo%5B1%5D=quux $params->hasArray('foo'); //returns true $params->getArray("foo"); //returns ["qux", "quux"] $params->has('foo'); //returns true $params->getFirst("foo"); //returns "bar" $params->getLast("foo"); //returns "baz" $params->getAll('foo'); //returns ["bar", "baz"] Hope this makes sense Regards, Ignace

« previous php.internals (#129669) next »