Description
Description
I report this as bug, but it can also be an feature request.
What is the problem:
A class that defines a optional parameter before an non-optional parameter
- That in the first place is not an issue when running the code, if we not using the class or provide both parameter.
- It becomes an issue when using named parameter. If only the second parameter 'test' is set, an Exception is thrown.
Side Note:
My IDE PHP Storm normally shows an warning: Optional parameter is provided before required
But this only shows up, when both parameter don't have public
That was the reason why i noticed this hole issue.
Reflection does not detect the optional parameter when there are in the wrong order
As you can see in the provided code, the Reflection detects the parameter 'bar' in Foo as not optional.
- This is right, when taken the order of the parameter into account.
- This is wrong, when we just look at the single parameter definition.
Conclusion:
Maybe php should throw an syntax error when an wrong parameter order is detected.
Because this is invalid code, but is only detected at run-time under some special conditions.
That Reflection currently shows the result that is does, is maybe fully correct, but is also not so clear.
We are able to do new Foo(...['test'=>'bar']) and that is why i thing php must throw an error when wrong parameter order is detected in the first place.
The following code:
<?php declare(strict_types=1);
class Foo {
public function __construct(
public string $bar = 'hallo',
public string $test,
)
{}
}
class Bar {
public function __construct(
public string $test,
public string $bar = 'hallo',
)
{}
}
foreach([Foo::class,Bar::class] as $cls){
foreach(new ReflectionClass($cls)->getConstructor()->getParameters() as $parameter){
print $cls.' '.$parameter->name.' '.($parameter->isOptional()?'optional':'').PHP_EOL;
}
}
//no issue
new Foo('Hello','World');
//var_export((array)new Bar(test:'Hello'));
//array ('test' => 'Hello','bar' => 'hallo')
//var_export((array)new Foo(test:'world'));
//PHP Fatal error: Uncaught ArgumentCountError: Foo::__construct(): Argument #1 ($bar) not passed
Resulted in this output:
Foo bar
Foo test
Bar test
Bar bar optional
But I expected this output instead:
//Some kind of syntax error thrown when optional parameter is before an non-optional parameter
PHP Version
PHP 8.4.5
Operating System
No response