Call to undefined method ReflectionUnionType::getName() in CConsoleCommand.php
aztechowski opened this issue · 4 comments
What steps will reproduce the problem?
Create an ConsoleCommand with an action having union type parameter, e.g.
public function actionDoSomething( array|string|int|null $unionParameter = null ): int {
Call from shell that action
What is the expected result?
Actions runs w/o error. The method run of CConsoleCommand should detect ReflectionUnionType and call getTypes.
What do you get instead?
The logic doesn't recognize ReflectionUnionType and use getType() method available in other Reflection classes, but not in ReflectionUnionType, which has onlky getTypes() method. This leads to an exception
Call to undefined method ReflectionUnionType::getName() in W:\00.www\sites\dobryslownik.trunk\vendor\yiisoft\yii\framework\cons
ole\CConsoleCommand.php:133
Additional info
Q | A |
---|---|
Yii version | latest |
PHP version | 8.2 |
Operating system | Windows/Linux |
I've build an workaround (written in PHP 8.2 style), which can be adopted here.
Instead of
if(version_compare(PHP_VERSION,'8.0','>=')) {
$isArray=$param->getType() && $param->getType()->getName()==='array';
} else {
$isArray = $param->isArray();
}
I'm using following code
//repleced by
$isArray = $this->isParameterAnArray($param);
//check whenever given parameter is an array, or not. Supports complex types (intersections, unions) from PHP 8 and above
private function isParameterAnArray($param): bool
{
if (PHP_VERSION_ID < 80000) {
return $param->isArray();
}
foreach ($this->getAllTypes($param) as $complexType) {
if ($complexType && $complexType->getName() === 'array') {
return true;
}
}
return false;
}
//Get all available types. In case an Intersection (PHP >= 8.1) or Union Type (PHP > 8.0) is used, then give all defined types
private function getAllTypes($param): array
{
if ((PHP_VERSION_ID >= 81000) && $param->getType() instanceof ReflectionIntersectionType) {
return $param->getType()->getTypes();
}
if ($param->getType() instanceof ReflectionUnionType) {
return $param->getType()->getTypes();
}
return [$param->getType()];
}
Similar to #4516
Yep, it can be combined and solved together.
Fixed by #4519