From 52cea7602b6a07522cce1926eaec487e643a1ff2 Mon Sep 17 00:00:00 2001 From: Matthieu Napoli Date: Sun, 8 Sep 2013 22:01:47 +0200 Subject: [PATCH] Fix for #96 Handle optional parameters for constructor/method injection --- src/DI/Factory.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/DI/Factory.php b/src/DI/Factory.php index 5b70899e0..09c0f6099 100644 --- a/src/DI/Factory.php +++ b/src/DI/Factory.php @@ -15,7 +15,9 @@ use DI\Definition\PropertyInjection; use Exception; use ReflectionClass; +use ReflectionMethod; use ReflectionProperty; +use ReflectionParameter; /** * Factory class, responsible of instantiating classes @@ -104,14 +106,22 @@ private function injectConstructor(ReflectionClass $classReflection, MethodInjec . "$nbRequiredParameters parameters, " . count($parameterInjections) . " defined or guessed"); } + // No parameters if (count($parameterInjections) === 0) { return $classReflection->newInstance(); } + $parameters = $this->getMethodReflectionParameters($constructorReflection); + $args = array(); foreach ($parameterInjections as $parameterInjection) { $entryName = $parameterInjection->getEntryName(); + if ($entryName === null) { + // If the parameter is optional and wasn't specified, then we skip all next parameters + if ($parameters[$parameterInjection->getParameterName()]->isOptional()) { + break; + } throw new DefinitionException("The parameter '" . $parameterInjection->getParameterName() . "' of the constructor of '{$classReflection->name}' has no type defined or guessable"); } @@ -168,10 +178,17 @@ private function injectMethod($object, MethodInjection $methodInjection) return; } + $parameters = $this->getMethodReflectionParameters($methodReflection); + $args = array(); foreach ($parameterInjections as $parameterInjection) { $entryName = $parameterInjection->getEntryName(); + if ($entryName === null) { + // If the parameter is optional and wasn't specified, then we skip all next parameters + if ($parameters[$parameterInjection->getParameterName()]->isOptional()) { + break; + } throw new DefinitionException("The parameter '" . $parameterInjection->getParameterName() . "' of {$classReflection->name}::$methodName has no type defined or guessable"); } @@ -222,4 +239,22 @@ private function injectProperty($object, PropertyInjection $propertyInjection) $property->setValue($object, $value); } + /** + * @param ReflectionMethod $reflectionMethod + * @return ReflectionParameter[] + */ + private function getMethodReflectionParameters(ReflectionMethod $reflectionMethod) + { + $parameters = $reflectionMethod->getParameters(); + + $keys = array_map( + function (ReflectionParameter $parameter) { + return $parameter->getName(); + }, + $parameters + ); + + return array_combine($keys, $parameters); + } + }