为PHP对象类型参数提供默认值

时间:2008-12-18 02:33:22

标签: php unit-testing dependency-injection

我正在编写一个考虑了可测试性的PHP应用程序,所以我的类总是在它们的构造函数中询问它们所依赖的“协作者对象”,就依赖注入模式而言。

这样,我就可以在单元测试中传入模拟或测试实现。

我想要实现的是,能够实例化一个传递给其构造函数参数的null值的类,以便触发一个回退机制,为每个协作者实例化一个默认的实现类。

因为在PHP中不能给对象类型参数赋予默认值,所以我必须在构造函数中执行它。以下代码是我目前使用的方法的一个示例:

class Engine
{
    private $loader;
    private $logger;

    public function __construct(ResourceLoader $loader = null, Logger $logger = null)
    {
        if ($loader == null) $loader = new DefaultResourceLoader;
        if ($logger == null) $logger = new DefaultLogger;

        $this->loader = $loader;
        $this->logger = $logger;
    }
}

你怎么看待这个?我应该使用IoC容器吗?还是有另一种方法可以给对象类型参数一个默认值?

2 个答案:

答案 0 :(得分:2)

当然,您最好使用IoC / DIP容器来完成这项工作。上面的代码(if语句)增加了类的耦合。客户端类(Engine)不应该关心实现加载器和记录器角色的内容。那是工厂或DIP容器的工作来了解这一点。通过在代码中放置一个具体的类名并将这些类绑定在一起,使您的代码不那么灵活(敏捷),减少可重用性,从而减少维护。

答案 1 :(得分:0)

在这种情况下,您可以使用我的小型库ValueResolver,例如:

$logger = ValueResolver::resolve($logger, new DefaultLogger);

并且不要忘记使用命名空间use LapaLabs\ValueResolver\Resolver\ValueResolver;

还可以进行类型转换,例如,如果变量的值应该是integer,那么请使用:

$id = ValueResolver::toInteger('6 apples', 1); // returns 6
$id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value)

查看docs了解更多示例