I have an existing method:
public function dbQuery(
string $query,
bool $flag1 = false,
int $flag2 = SOME_DEFAULT,
bool $flag3 = false
)
Now I want to adapt it so it is possible to pass in binding values as variadic arguments, but without breaking the current interface (I know arg flags are an anti-pattern), to be:
public function dbQuery(
string $query,
bool $flag1 = false,
int $flag2 = SOME_DEFAULT,
bool $flag3 = false,
mixed ...$params
)
How can I then call dbQuery while keeping the default flags while passing in params?
I've tried:
->dbQuery('my query', params: [1, 2, 3]);
but it comes through as an array in the first variadic arg e.g. $params = [[1, 2, 3]]
->dbQuery('my query', params: ...[1, 2, 3]);
is invalid syntax->dbQuery('my query', ...['params' => [1, 2, 3]]);
same result as option 1Nothing with quite this usage is shown in: https://wiki.php.net/rfc/variadics or https://wiki.php.net/rfc/named_params
Although in the later RFC it explictly shows that default named arguments before variadics is a valid signature, but not how to access the variadics.
A comment on this related question leads me to an interesting workaround, with caveats: you can populate named entries in the variadic argument by using names that don't match parameters in the signature.
This works because the named parameters RFC specified:
Functions declared as variadic using the ...$args syntax will also collect unknown named arguments into $args.
So in your example, this would be a valid call:
$whatever->dbQuery('my query', params1: 1, param2: 2, param3: 3);
Which would result in var_dump($params)
looking like this:
array(3) {
["params1"]=>
int(1)
["param2"]=>
int(2)
["param3"]=>
int(3)
}
You could then use array_values
or loop over the array ignoring keys if you wanted a positional array.