Skip to content
This repository has been archived by the owner on Feb 6, 2020. It is now read-only.

Use default values for type-hinted arguments if type not found in container #243

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/AbstractFactory/ReflectionBasedAbstractFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,11 @@ private function resolveParameter(ReflectionParameter $parameter, ContainerInter
$type = $parameter->getClass()->getName();
$type = isset($this->aliases[$type]) ? $this->aliases[$type] : $type;

if (! $container->has($type)) {
if ($container->has($type)) {
return $container->get($type);
}

if (! $parameter->isOptional()) {
throw new ServiceNotFoundException(sprintf(
'Unable to create service "%s"; unable to resolve parameter "%s" using type hint "%s"',
$requestedName,
Expand All @@ -227,6 +231,8 @@ private function resolveParameter(ReflectionParameter $parameter, ContainerInter
));
}

return $container->get($type);
// Type not available in container, but the value is optional and has a
// default defined.
return $parameter->getDefaultValue();
}
}
17 changes: 17 additions & 0 deletions test/AbstractFactory/ReflectionBasedAbstractFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace ZendTest\ServiceManager\AbstractFactory;

use ArrayAccess;
use Interop\Container\ContainerInterface;
use PHPUnit\Framework\TestCase;
use Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;
Expand Down Expand Up @@ -154,4 +155,20 @@ public function testFactoryWillUseDefaultValueWhenPresentForScalarArgument()
$this->assertInstanceOf(TestAsset\ClassWithScalarDependencyDefiningDefaultValue::class, $instance);
$this->assertEquals('bar', $instance->foo);
}

/**
* @see https://github.com/zendframework/zend-servicemanager/issues/239
*/
public function testFactoryWillUseDefaultValueForTypeHintedArgument()
{
$this->container->has('config')->willReturn(false);
$this->container->has(ArrayAccess::class)->willReturn(false);
$factory = new ReflectionBasedAbstractFactory();
$instance = $factory(
$this->container->reveal(),
TestAsset\ClassWithTypehintedDefaultValue::class
);
$this->assertInstanceOf(TestAsset\ClassWithTypehintedDefaultValue::class, $instance);
$this->assertNull($instance->value);
}
}
20 changes: 20 additions & 0 deletions test/AbstractFactory/TestAsset/ClassWithTypehintedDefaultValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* @see https://github.com/zendframework/zend-2018 for the canonical source repository
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-2018/blob/master/LICENSE.md New BSD License
*/

namespace ZendTest\ServiceManager\AbstractFactory\TestAsset;

use ArrayAccess;

class ClassWithTypehintedDefaultValue
{
public $value;

public function __construct(ArrayAccess $value = null)
{
$this->value = null;
}
}