Hi

On 3/9/26 21:47, Máté Kocsis wrote:
Same situation as above, but basically the whole section is a big question
mark:
I couldn't come up with a good enough idea how arrays could be handled
efficiently and ergonomically, and in the same time, how to (mostly) conform
to WHATWG URL.

The internal storage should not know about arrays. It should represent things as a list of key-value pairs, with arrays only being materialized for the methods that are intended to deal with arrays.

Given that the class is generic, matching the WHATWG API 1:1 is not necessary in my opinion.

Some of my problems:
- How should $params->get("foo[bar]") behave? Should we try to parse the
supplied key as an array and return the
nested item if it exists? I suppose, we would internally store the query
params as an array (just like how $_GET does),
so then we would definitely need parsing in order to be able to return item
"bar" stored within array "foo".

`->get()` does not currently exist within the RFC. The WHATWG `get()` is equivalent to `->getFirst()`.

- However, what should a $params->append("foo[bar]") call do when the query
param "foo" is already added with a string value?
Should it modify the existing item to be an array (but then how?) or we
should just add "foo[bar]" to the query params as-is?

It should add `foo[bar]` as-is. `foo` and `foo[bar]` are different keys. The square-bracket syntax is something that is specific to PHP.

- How to recompose list parameters? Ideally, we should not append [] to
these parameters (e.g.

The recomposition should be "dumb" and just use the keys as-is. The complex logic should happen in the getter or setter. Only the 'array' getters and setters deal with the PHP-specific square-bracket syntax.

To give an example:

    "k=1&k=2"
    [['k', '1'], ['k', '2']]
    getAll('k')   // ['1', '2']
    getArray('k') // UriException: 'k' is not an array.

    "k[]=1&k[]=2"
    [['k[]', '1'], ['k[]', '2']]
    getAll('k')   // []
    getAll('k[]') // ['1', '2']
    getArray('k') // ['1', '2']

    "k[a]=1&k[b]=2"
    [['k[a]', '1'], ['k[b]', '2']]
    getAll('k')    // []
    getAll('k[a]') // ['1']
    getArray('k')  // ['a' => '1', 'b' => '2']

    "k=1&k[]=2"
    [['k', '1'], ['k[]', '2']]
    getAll('k')   // ['1']
    getAll('k[]') // ['2']
    getArray('k') // UriException: 'k' is not an array.

    "k[]=2&k=3";
    [['k[]', '2'], ['k', '3']];
    getAll('k')   // ['3']
    getAll('k[]') // ['2']
    getArray('k') // UriException: 'k' is not an array.

The string should internally be represented something like the arrays and the getters should work as indicated in the comment.

And then for the setters:

    // []
    append('k', '1')   // [['k', '1']]
    append('k', '2')   // [['k', '1'], ['k', '2']]
    append('k[]', '3') // [['k', '1'], ['k', '2'], ['k[]', '3']]
    set('k', '4')      // [['k[]', '3'], ['k', '4']]

The `setArray()` method would then create a number of entries with square brackets added as appropriate (and delete all entries that would be returned by `getArray()`). The `appendArray()` method should probably be dropped to avoid issues with "mixing non-array with array keys". So:

    // []
    setArray('k', ['1'])             // [['k[]', '1']]
    setArray('k', ['1', '2'])        // [['k[]', '1'], ['k[]', '2']]
    setArray('k', ['a' => '1', '2']) // [['k[a]', '1'], ['k[0]', '2']]
    append('k', 'x')                 // [
                                     //  ['k[a]', '1'],
                                     //  ['k[0]', '2'],
                                     //  ['k', 'x'],
                                     // ]
    setArray('k', ['1'])             // [['k[]', '1']]

Does that make sense?

Best regards
Tim Düsterhus

Reply via email to