<?php
class A {}
class B {}
class C {}
class D {}
class Z {
use ConstructorParamDeprecationHelper;
public function __construct(
protected A $a,
protected C|B $c,
protected D|C $d,
) {
$this->deprecateParam(B::class, 'c', func_get_args());
var_dump(get_class($this->a));
var_dump(get_class($this->c));
var_dump(get_class($this->d));
}
}
new Z(new A(), new B(), new C(), new D());
new Z(new A(), new C(), new D());
trait ConstructorParamDeprecationHelper {
function deprecateParam($className, $paramName, $args) {
if ($this->$paramName instanceof $className) {
trigger_error('A, B, C, D is deprecated, pass A, C, D instead', E_USER_DEPRECATED);
$constructor = new ReflectionMethod($this, '__construct');
$params = $constructor->getParameters();
$position = array_search($paramName, array_column($params, 'name'));
$move = array_slice($params, $position);
foreach ($move as $i => $param) {
if ($constructor->getNumberOfParameters() > ($i + $position + 1)) {
$next = $move[$i + 1];
$this->{$param->getName()} = $this->{$next->getName()};
}
else {
$this->{$param->getName()} = $args[$i + $position + 1];
}
}
}
}
}
Deprecated: A, B, C, D is deprecated, pass A, C, D instead in /in/kWEm7 on line 28
string(1) "A"
string(1) "C"
string(1) "D"
string(1) "A"
string(1) "C"
string(1) "D"