Re: [RFC] [Discussion] Query Parameter Manipulation Support

From: Date: Wed, 08 Jul 2026 21:28:04 +0000
Subject: Re: [RFC] [Discussion] Query Parameter Manipulation Support
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to internals+get-131825@lists.php.net to get a copy of this message
Hello Tim et All, I managed to implement a considerable part of the proposal efficiently, as I planned. However, I came to a different conclusion regarding the "Array API" (https://wiki.php.net/rfc/query_params#array_api) than what I originally wrote: First and foremost, I wasn't happy that the Array API would try to mimic native array handling. For example, QueryParams::getArray("foo[bar][baz]") would try to parse the supplied array dimensions and then find index "baz" of index "bar" of array "foo". QueryParams::appendArray() and QueryParams::setArray() would need a similar behavior. I wasn't keen on reimplementing array operations within query params. In order to solve this Gordian knot, I want to simplify the Array API to only two (or maybe three) methods: - QueryParams::fromArray(): Creates a new QueryParams object from an array - QueryParams::withArray(): Does the same as above, but from an existing instance (I'm not 100% sure about this method yet) - QueryParams::toArray(): Creates an array from the QueryParams instance If someone wants to do any kind of array modifications, then they can do it by retrieving the query params array first via toArray(), change what's needed by using PHP's native array manipulation functionalities, and finally, convert the.array back to a QueryParams instance. I think this behavior is simple, clear, and also extensible later, if we learn about a better approach... Besides, I also realized that supporting some kind of configuration will also be necessary mostly for security reasons. These are the options I'm considering to add: - parsingMaxQueryStringLength: the maximum length of the input query string that can be parsed by the parse*() methods - parsingMaxParamCount: The maximum number of parameters that the input query string can contain when calling any parse*() methods (similar to the "max_input_vars" php.ini option). - parsingMaxNestingLevel: The maximum nesting level of arrays that can be parsed when calling any parse*() methods (similar to the "max_input_nesting_level" php.ini option) I figured that it might be useful to control how some specific type of query parameter values are represented when adding a new query parameter via calling e.g. QueryParams::append("param", $value). - boolean values: by default, true would be represented as "1" and false would be represented as "0" - null values: there are three ways to handle them: 1) omitting these; 2) adding them without a "=", containing only the param name (e.g. "?foo"); 3) and converting the null value to an empty string (e.g. "?foo=") I'm not really sure how useful these options are, so I'm curious to get feedback about them. It's also an option to only accept string or null values by the manipulator methods, but I think it would provide a better UX to support all valid types (e.g. an int is a valid one, but an object isn't). It's also a question how and where these configs should be passed. Currently, I group them together in a dedicated QueryParamOptions object which has the following signature: final readonly class QueryParamOptions { public function __construct( public int $parsingMaxQueryStringLength = 10000, public int $parsingMaxParamCount = 1000, public int $parsingMaxNestingLevel = 64, public string $trueValue = "0", public string $falseValue = "0", public bool $useNullAsEmptyString = false ) {}} However, the properties prefixed by "parsing" are only applicable during parsing, so maybe they should be passed separately to the parse*() methods? What are your thoughts? Regards, Máté

« previous php.internals (#131825) next »