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é

Reply via email to