Completed
Push — master ( fd7b1f...70ced9 )
by Rasmus
21s queued 14s
created

Reflection::getParameterType()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 11.8436

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 5
cts 11
cp 0.4545
rs 8.9777
c 0
b 0
f 0
cc 6
nc 5
nop 1
crap 11.8436
1
<?php
2
3
namespace mindplay\unbox;
4
5
use Closure;
6
use ReflectionFunction;
7
use ReflectionFunctionAbstract;
8
use ReflectionMethod;
9
use ReflectionParameter;
10
11
/**
12
 * Pseudo-namespace for some common reflection helper-functions.
13
 */
14
abstract class Reflection
15
{
16
    /**
17
     * @type string pattern for parsing an argument type from a ReflectionParameter string
18
     *
19
     * @see Reflection::getParameterType()
20
     */
21
    const ARG_PATTERN = '/(?:\<required\>|\<optional\>)\\s+([\\w\\\\]+)/';
22
23
    /**
24
     * Create a Reflection of the function references by any type of callable (or object implementing `__invoke()`)
25
     *
26
     * @param callable|object $callback
27
     *
28
     * @return ReflectionFunctionAbstract
29
     *
30
     * @throws InvalidArgumentException
31
     */
32 1
    public static function createFromCallable($callback)
33
    {
34 1
        if (is_object($callback)) {
35 1
            if ($callback instanceof Closure) {
36 1
                return new ReflectionFunction($callback);
37 1
            } elseif (method_exists($callback, '__invoke')) {
38 1
                return new ReflectionMethod($callback, '__invoke');
39
            }
40
41 1
            throw new InvalidArgumentException("class " . get_class($callback) . " does not implement __invoke()");
42 1
        } elseif (is_array($callback)) {
43 1
            if (is_callable($callback)) {
44 1
                return new ReflectionMethod($callback[0], $callback[1]);
45
            }
46
47 1
            throw new InvalidArgumentException("expected callable");
48 1
        } elseif (is_callable($callback)) {
49 1
            return new ReflectionFunction($callback);
50
        }
51
52 1
        throw new InvalidArgumentException("unexpected value: " . var_export($callback, true) . " - expected callable");
53
    }
54
55
    /**
56
     * Obtain the type-hint of a `ReflectionParameter`, but avoid triggering autoload (as a performance optimization)
57
     *
58
     * @param ReflectionParameter $param
59
     *
60
     * @return string|null fully-qualified type-name (or NULL, if no type-hint was available)
61
     */
62 1
    public static function getParameterType(ReflectionParameter $param)
63
    {
64 1
        if (method_exists($param, "getType")) {
65
            $type = $param->getType();
66
67
            if ($type === null || $type->isBuiltin()) {
68
                return null; // ignore scalar type-hints
69
            }
70
71
            return method_exists($type, "getName")
72
                ? $type->getName() // PHP >= 7.1
73
                : $type->__toString(); // PHP < 7.1
74
        }
75
76 1
        if (preg_match(self::ARG_PATTERN, $param->__toString(), $matches) === 1) {
77 1
            return $matches[1];
78
        }
79
80 1
        return null; // no type-hint is available
81
    }
82
}
83