On Sun, Dec 21, 2025 at 1:13 PM Máté Kocsis <[email protected]> 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

Reply via email to