我一直在研究 laravel 4 容器,以获取更多关于 laravel 内部的知识,并提升自己编写更好代码的技能。
但是我无法理解 3 段类似的代码。我将使用最小的片段来保持这个问题的清洁。
类似的问题可以在下面的链接中找到。尽管人们已经回答了正确的答案,但我并不满足于简单的“知道如何使用它,但不知道它是如何运作的”。所以我真的希望有人可以对这一切做出解释。
<?php namespace Illuminate\Container; use Closure, ArrayAccess, ReflectionParameter;
class BindingResolutionException extends \Exception {}
class Container implements ArrayAccess {
/**
* Wrap a Closure such that it is shared.
*
* @param Closure $closure
* @return Closure
*/
public function share(Closure $closure)
{
return function($container) use ($closure)
{
// We'll simply declare a static variable within the Closures and if
// it has not been set we'll execute the given Closure to resolve
// the value and return it back to the consumers of the method.
static $object;
if (is_null($object))
{
$object = $closure($container);
}
return $object;
};
}
}
共享方法如何知道该函数中的 $container 变量实际上是 Illuminate\Container 的一个实例?它没有在该函数的范围内定义。它也没有在以下示例用例中定义(无论如何都无济于事)
class AuthServiceProvider extends ServiceProvider{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app['auth'] = $this->app->share(function($app)
{
// Once the authentication service has actually been requested by the developer
// we will set a variable in the application indicating such. This helps us
// know that we need to set any queued cookies in the after event later.
$app['auth.loaded'] = true;
return new AuthManager($app);
});
}
}
我期待一个不同的实现,所以来了
class MyContainer{
public function share(Closure $closure)
{
$container = $this;
return function() use ($closure, $container)
{
static $object;
if(is_null($object))
{
$object = $closure($container);
}
return $object;
};
}
}
$closure = function($container)
{
var_dump($container);
};
$container = new MyContainer();
call_user_func($container->share($closure));
//dumps an instance of MyContainer -> which is the wanted behaviour
$container = new Illuminate\Container\Container();
call_user_func($container->share($closure));
//Throws a warning AND a notice
//Warning: Missing argument 1 for Illuminate\Container\Container::Illuminate\Container\{closure}() in /Users/thomas/Sites/Troll/vendor/illuminate/container/Illuminate/Container/Container.php on line 128
//NOTICE: Notice: Undefined variable: container in /Users/thomas/Sites/Troll/vendor/illuminate/container/Illuminate/Container/Container.php on line 137
//and even worse the output of the var_dump is NULL
我在理解 extend 和 bind 方法时遇到了同样的问题,它们都具有将不存在的参数作为闭包参数传递的相同实现,但我无法理解它是如何解析为容器实例本身的?