为什么使用闭包来分配而不是直接为键赋值?

tar*_*req 6 php closures variable-assignment

我正在观看这个视频,在7:10他正在添加数据库依赖项,并使用闭包来分配值.

我的问题是为什么不直接使用直接赋值,我的意思是不这样做:

$container['db'] = $capsule;
Run Code Online (Sandbox Code Playgroud)

相当于这样做:

$container['db'] = function ($container) use ($capsule) {
    return $capsule;
}
Run Code Online (Sandbox Code Playgroud)

如果没有,有什么区别,哪种方式更好?

Nim*_*ima 2

TLDR是因为将依赖项定义为闭包使得依赖项注入容器可以按需构建它们,因此您无需担心它们的定义顺序并手动管理它们的依赖项。

Pimple 是依赖注入容器,它应该通过以简单方便的方式管理对象的依赖关系来帮助您设置对象。

如果您直接为某个键分配一个值,Pimple 会将该值称为“参数”,当您需要访问该键时,它只会返回该确切值:

$container['sample-param'] = 'foo';
echo $container['sample-param'];
//output: foo
Run Code Online (Sandbox Code Playgroud)

但重点是,这sample-param不需要任何设置,它只是一个值,我们对此很满意。但假设以下服务设置:

$container['myService'] = function($c) {
    $service = new \Some\Complicated\Service();
    //this service depends on cache service
    $service->setCache($c['cache']);
    return $service;
}

$container['cache'] = function($c) {
    $cache = new \Cache\Driver();
    //our cache driver needs a db connection
    $cache->setDbConnection($c['db']);
    return $cache;
}

$container['db'] = function($c) {
    //our database connection requires some parameters
    $dbConnection = new \Database\Connection($c['db-config']);
    return $dbConnection;
}

$container['db-config'] = [
    'username' => 'foo',
    'password' => 'bar',
    'host' => 'localhost'
];

//Now we want to user our service:
$container['myService']->doSomething();
Run Code Online (Sandbox Code Playgroud)

请注意我在容器中定义不同键的顺序。

myService需要cache,但缓存定义在 myService 定义之后。这就是 Pimple 提供帮助的地方,这就是为什么我们将容器传递给每个闭包,因为 Pimple 将按需构建我们的依赖项。当我们需要访问myServicePimple 时,查看其内部数据存储,如果它之前已myService成功构建并存储,它将返回相同的实例,否则它将调用我们的闭包来构建它。当我们的闭包被调用时,它会要求 Pimple($c 是 Pimple 容器)为其提供依赖项(在本例中是cache服务)。Pimple 在缓存上应用相同的东西,如果尚未构建,它将构建它等等......直到它到达需要简单参数的部分,例如db-config将立即返回。在这个闭包调用链中,构建了我们的对象及其所有依赖项。

现在想象一下如果我们使用简单的值而不是闭包会发生什么?在这种情况下,当我们想要构建时,myService 我们必须处理它的依赖关系。在定义服务本身之前,我们必须确保定义其依赖项,并且必须处理与管理依赖项相关的其他问题。在这种情况下,我们不能仅仅定义我们的myService假设cache可用的服务,该服务将在稍后定义。