CallableReflection.php
62 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Invoker\Reflection; |
| 4 | |
| 5 | use Invoker\Exception\NotCallableException; |
| 6 | |
| 7 | /** |
| 8 | * Create a reflection object from a callable. |
| 9 | * |
| 10 | * @author Matthieu Napoli <matthieu@mnapoli.fr> |
| 11 | */ |
| 12 | class CallableReflection |
| 13 | { |
| 14 | /** |
| 15 | * @param callable $callable |
| 16 | * |
| 17 | * @return \ReflectionFunctionAbstract |
| 18 | * |
| 19 | * @throws NotCallableException |
| 20 | * |
| 21 | * TODO Use the `callable` type-hint once support for PHP 5.4 and up. |
| 22 | */ |
| 23 | public static function create($callable) |
| 24 | { |
| 25 | // Closure |
| 26 | if ($callable instanceof \Closure) { |
| 27 | return new \ReflectionFunction($callable); |
| 28 | } |
| 29 | |
| 30 | // Array callable |
| 31 | if (is_array($callable)) { |
| 32 | list($class, $method) = $callable; |
| 33 | |
| 34 | if (! method_exists($class, $method)) { |
| 35 | throw NotCallableException::fromInvalidCallable($callable); |
| 36 | } |
| 37 | |
| 38 | return new \ReflectionMethod($class, $method); |
| 39 | } |
| 40 | |
| 41 | // Callable object (i.e. implementing __invoke()) |
| 42 | if (is_object($callable) && method_exists($callable, '__invoke')) { |
| 43 | return new \ReflectionMethod($callable, '__invoke'); |
| 44 | } |
| 45 | |
| 46 | // Callable class (i.e. implementing __invoke()) |
| 47 | if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) { |
| 48 | return new \ReflectionMethod($callable, '__invoke'); |
| 49 | } |
| 50 | |
| 51 | // Standard function |
| 52 | if (is_string($callable) && function_exists($callable)) { |
| 53 | return new \ReflectionFunction($callable); |
| 54 | } |
| 55 | |
| 56 | throw new NotCallableException(sprintf( |
| 57 | '%s is not a callable', |
| 58 | is_string($callable) ? $callable : 'Instance of ' . get_class($callable) |
| 59 | )); |
| 60 | } |
| 61 | } |
| 62 |