Skip to content

Commit 354c663

Browse files
committed
Avoid a E_DEPRECATED in _checkTypehint on PHP8
PHP8's reflection API changed to make room for handling of union-types. As one of the consequences `ReflectionParameter::getClass` got marked as deprecated. This commit moves the legacy path behind a version-check for PHP versions before 8 and adds a new more complex path for PHP8+.
1 parent f5b16a4 commit 354c663

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

src/functions.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,47 @@ function _checkTypehint(callable $callback, $object)
343343

344344
$expectedException = $parameters[0];
345345

346-
if (!$expectedException->getClass()) {
346+
// PHP before v8 used an easy API:
347+
if (PHP_VERSION_ID < 80000) {
348+
if (!$expectedException->getClass()) {
349+
return true;
350+
}
351+
352+
return $expectedException->getClass()->isInstance($object);
353+
}
354+
355+
// Extract the type of the argument and handle different possibilities
356+
$type = $expectedException->getType();
357+
$types = [];
358+
359+
switch (true) {
360+
case $type === null:
361+
break;
362+
case $type instanceof \ReflectionNamedType:
363+
$types = [$type];
364+
break;
365+
case $type instanceof \ReflectionUnionType;
366+
$types = $type->getTypes();
367+
break;
368+
default:
369+
throw new \LogicException('Unexpected return value of ReflectionParameter::getType');
370+
}
371+
372+
// If there is no type restriction, it matches
373+
if (empty($types)) {
347374
return true;
348375
}
349376

350-
return $expectedException->getClass()->isInstance($object);
377+
// Search for one matching named-type for success, otherwise return false
378+
// A named-type can be either a class-name or a built-in type like string, int, array, etc.
379+
foreach ($types as $type) {
380+
$matches = ($type->isBuiltin() && \gettype($object) === $type->getName())
381+
|| (new \ReflectionClass($type->getName()))->isInstance($object);
382+
383+
if ($matches) {
384+
return true;
385+
}
386+
}
387+
388+
return false;
351389
}

0 commit comments

Comments
 (0)