3v4l.org

run code in 300+ PHP versions simultaneously
<?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]; } } } } }

preferences:
26.07 ms | 402 KiB | 5 Q