Laravel:区别 App::bind 和 App::singleton

2022-01-08 00:00:00 oop php laravel-4 facade ioc-container

我对 laravel 在 IOC 容器和外观方面提供的所有好处感到有些困惑.因为我不是一个经验丰富的程序员,所以学习起来会让人不知所措.

I get a bit confused over all the nice things laravel has to offer in terms of the IOC container and facades. Since I'm not an experienced programmer it gets overwhelming to learn.

我在想,这两个例子有什么区别:

I was wondering, what is the difference between these two examples:

  1. 'Foo' 的外观并通过 App::bind()

'Foo' 的外观并通过 App::singleton()

A facade to 'Foo' and registered in the container via App::singleton()

在我的最佳理解中,Foo::method() 将被重写为 $app->make['foo']->method() 所以在第一个示例将创建 Foo 类的多个实例,而在第二个示例中,因为它是通过 App::singleton() 绑定的,与 的相同实例>Foo 将在每次调用该对象的方法时返回.

In my best understanding Foo::method() will be rewritten as $app->make['foo']->method() so in the first example multiple instances of the Foo class will be created and in the second example, since it's bound via an App::singleton(), the same instance of Foo will be returned every time a Method on that object is called.

如果这个问题的答案很明显,我很抱歉,但我找不到任何关于这个问题的确认,也没有明确解释.

I'm sorry if the answer to this question is to obvious, but I can't find any confirmation on this matter and nowhere this is clearly explained.

推荐答案

就是这样.

一个非常简单的证明是测试行为.由于 Laravel 应用程序只是扩展了 IlluminateContainerContainer,我们将只使用容器(在我的例子中,我什至只将容器作为依赖项添加到我的 composer.json)来进行测试.p>

A very simple proof is to test out the behavior. Since the Laravel Application simply extends IlluminateContainerContainer, we'll use just the container (in my case I even only added the container as a dependency to my composer.json) to test.

require __DIR__ . '/vendor/autoload.php';

class FirstClass
{
    public $value;
}

class SecondClass
{
    public $value;
}

// Test bind()
$container = new IlluminateContainerContainer();

$container->bind('FirstClass');

$instance = $container->make('FirstClass');
$instance->value = 'test';

$instance2 = $container->make('FirstClass');
$instance2->value = 'test2';

echo "Bind: $instance->value vs. $instance2->value
";

// Test singleton()
$container->singleton('SecondClass');

$instance = $container->make('SecondClass');
$instance->value = 'test';

$instance2 = $container->make('SecondClass');
$instance2->value = 'test2'; // <--- also changes $instance->value

echo "Singleton: $instance->value vs. $instance2->value
";

结果如预期:

绑定:test 与 test2

单例:test2 与 test2

可能是一个肮脏的证明,但确实是一个.

Might be a dirty proof, but indeed it is one.

所有的魔力都在于 Container::make 方法.如果绑定注册为共享(即单例),则返回类实例,否则每次都会返回一个新实例.

All the magic lies in the Container::make method. If the binding is registered as shared (which means as singleton), the class instance is returned, otherwise a new instance every time.

来源:https://github.com/laravel/framework/blob/4.2/src/Illuminate/Container/Container.php#L442

顺便说一句,Container::singletonContainer::bind 相同,但第三个参数设置为 true.

BTW, Container::singleton is the same as Container::bind with the third parameter set to true.

相关文章