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]; } } } } }
Output for 8.0.1 - 8.0.30, 8.1.0 - 8.1.30, 8.2.0 - 8.2.25, 8.3.0 - 8.3.13
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"

preferences:
56.15 ms | 406 KiB | 5 Q