【问题标题】:Laravel core method confusionLaravel 核心方法混淆
【发布时间】:2013-03-23 10:36:21
【问题描述】:

我一直在挖掘 Laravel 的核心,因为我想了解它是如何工作的。但是我想出了一个方法,即使在 3 天后我也无法理解。 在 start.php 中,应用程序绑定到自身。到目前为止,一切都很好。但是当我检查 $app->share 方法时,我迷路了。

    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;
    };
}

此方法返回一个匿名函数,该函数在执行时会返回应用程序的一个实例。我看对了吗?为什么是这样?为什么要返回闭包而不仅仅是实例。这似乎是一种奇怪的方式,但我很确定这是有原因的 ;) ??

更新 start.php 中的那一行:

$app['app'] = $app->share(function($app) { return $app; });

所以我认为 $app['app'] 是一个闭包对象。但是,如果我做 get_class 类是 Illuminate\Foundation\Application 。 此外,也没有办法执行它,因为 $app'app' 显然不起作用。

【问题讨论】:

  • 这似乎是单例和控制反转 (IoC) 设计模式的组合。当然这是为了可扩展性,但我不知道为什么它是这样构建的。

标签: laravel laravel-4


【解决方案1】:

$app不是普通数组,它实际上是Illuminate\Foundation\Application1的一个实例,是Illuminate\Container\Container2的扩展,它实现了ArrayAccess。但是您已经知道这一点,因为这就是 share() 方法所在的地方。

容器将键绑定到闭包,当访问键时,从内存中获取值,或者在第一次访问时,调用绑定的闭包并返回结果值。当一个键被设置在容器上时,它被包裹在一个闭包中,除非它已经是一个闭包。

这为容器提供了一致的内部接口,因此代码不会不断地检查其内容。它也只会将您实际使用的引用加载到内存中 - 人们认为闭包的占用空间比完全加载的类实例的占用空间要轻。但是一旦加载,您就可以在请求的其余部分使用同一个实例。

虽然我不知道为什么应用程序没有使用 instance() 在容器上注册 - 也许它会在跟踪和转储输出中产生递归引用。

【讨论】:

  • 非常感谢!真的很好的答案。当我读到它时,我意识到我已经接近了我的理论,但你的回答肯定让我更清楚了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多