diff --git a/src/CallableResolver.php b/src/CallableResolver.php index 7002823..c51cb31 100644 --- a/src/CallableResolver.php +++ b/src/CallableResolver.php @@ -62,12 +62,10 @@ private function resolveFromContainer($callable) return $callable; } - $isStaticCallToNonStaticMethod = false; - // If it's already a callable there is nothing to do if (is_callable($callable)) { - $isStaticCallToNonStaticMethod = $this->isStaticCallToNonStaticMethod($callable); - if (! $isStaticCallToNonStaticMethod) { + // TODO with PHP 8 that should not be necessary to check this anymore + if (! $this->isStaticCallToNonStaticMethod($callable)) { return $callable; } } @@ -95,17 +93,8 @@ private function resolveFromContainer($callable) if ($this->container->has($callable[0])) { throw $e; } - if ($isStaticCallToNonStaticMethod) { - throw new NotCallableException(sprintf( - 'Cannot call %s::%s() because %s() is not a static method and "%s" is not a container entry', - $callable[0], - $callable[1], - $callable[1], - $callable[0] - )); - } throw new NotCallableException(sprintf( - 'Cannot call %s on %s because it is not a class nor a valid container entry', + 'Cannot call %s() on %s because it is not a class nor a valid container entry', $callable[1], $callable[0] )); diff --git a/src/ParameterResolver/Container/TypeHintContainerResolver.php b/src/ParameterResolver/Container/TypeHintContainerResolver.php index 3a6b0d8..ca31d7f 100644 --- a/src/ParameterResolver/Container/TypeHintContainerResolver.php +++ b/src/ParameterResolver/Container/TypeHintContainerResolver.php @@ -5,6 +5,7 @@ use Invoker\ParameterResolver\ParameterResolver; use Psr\Container\ContainerInterface; use ReflectionFunctionAbstract; +use ReflectionNamedType; /** * Inject entries from a DI container using the type-hints. @@ -39,10 +40,24 @@ public function getParameters( } foreach ($parameters as $index => $parameter) { - $parameterClass = $parameter->getClass(); + $parameterType = $parameter->getType(); + if (!$parameterType) { + // No type + continue; + } + if ($parameterType->isBuiltin()) { + // Primitive types are not supported + continue; + } + if (!$parameterType instanceof ReflectionNamedType) { + // Union types are not supported + continue; + } + + $parameterClass = $parameterType->getName(); - if ($parameterClass && $this->container->has($parameterClass->name)) { - $resolvedParameters[$index] = $this->container->get($parameterClass->name); + if ($this->container->has($parameterClass)) { + $resolvedParameters[$index] = $this->container->get($parameterClass); } } diff --git a/src/ParameterResolver/TypeHintResolver.php b/src/ParameterResolver/TypeHintResolver.php index a46e998..3f1baf4 100644 --- a/src/ParameterResolver/TypeHintResolver.php +++ b/src/ParameterResolver/TypeHintResolver.php @@ -3,6 +3,7 @@ namespace Invoker\ParameterResolver; use ReflectionFunctionAbstract; +use ReflectionNamedType; /** * Inject entries using type-hints. @@ -26,10 +27,24 @@ public function getParameters( } foreach ($parameters as $index => $parameter) { - $parameterClass = $parameter->getClass(); + $parameterType = $parameter->getType(); + if (!$parameterType) { + // No type + continue; + } + if ($parameterType->isBuiltin()) { + // Primitive types are not supported + continue; + } + if (!$parameterType instanceof ReflectionNamedType) { + // Union types are not supported + continue; + } + + $parameterClass = $parameterType->getName(); - if ($parameterClass && array_key_exists($parameterClass->name, $providedParameters)) { - $resolvedParameters[$index] = $providedParameters[$parameterClass->name]; + if (array_key_exists($parameterClass, $providedParameters)) { + $resolvedParameters[$index] = $providedParameters[$parameterClass]; } } diff --git a/tests/InvokerTest.php b/tests/InvokerTest.php index 566edc0..1595c79 100644 --- a/tests/InvokerTest.php +++ b/tests/InvokerTest.php @@ -314,7 +314,7 @@ public function positioned_parameters_have_the_highest_priority() */ public function should_not_invoke_statically_a_non_static_method() { - $this->expectExceptionMessage("Cannot call Invoker\Test\InvokerTestFixture::foo() because foo() is not a static method and \"Invoker\Test\InvokerTestFixture\" is not a container entry"); + $this->expectExceptionMessage("Cannot call foo() on Invoker\Test\InvokerTestFixture because it is not a class nor a valid container entry"); $this->expectException(NotCallableException::class); $this->invoker->call([InvokerTestFixture::class, 'foo']); }