Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel: Difference App::bind and App::singleton

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. A facade to 'Foo' and registered in the container via App::bind()

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

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.

like image 332
Luuk Van Dongen Avatar asked Aug 10 '14 13:08

Luuk Van Dongen


People also ask

Does Laravel use singleton?

The database layer of Laravel is also implemented using singletons. This means that there is only one database connection per request. This helps to keep the database layer of the application clean and easy to use.

What is bind in Laravel?

If we take a look at the Laravel documentation, binds are registered using the bind() method. The first argument passed in is a class name, followed by a closure that returns an instantiated instance of that class object.


1 Answers

It's exactly like that.

A very simple proof is to test out the behavior. Since the Laravel Application simply extends Illuminate\Container\Container, 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 Illuminate\Container\Container();  $container->bind('FirstClass');  $instance = $container->make('FirstClass'); $instance->value = 'test';  $instance2 = $container->make('FirstClass'); $instance2->value = 'test2';  echo "Bind: $instance->value vs. $instance2->value\n";  // 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\n"; 

The result is as expected:

Bind: test vs. test2

Singleton: test2 vs. test2

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

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.

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

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

like image 103
niclasleonbock Avatar answered Oct 07 '22 23:10

niclasleonbock