Pregunta

While looking through some source code on Github, I noticed some packages use the app container itself to access the IOC, not Facades. Why would you use something like this...

$app = app();
$user = $app['db']->connection()->table('users')->where('name', '=', 'Foo')->first();

...instead of this?

$user = User::where('name', '=', 'Foo')->first();
¿Fue útil?

Solución

Motive 1

Some packages need to.

Usually you are going to see ServiceProviders using it this way:

$this->app['db']

Or inside a closure binding:

$this->app->bindShared('anything', function($app)
{
    return new DatabaseClass($app['db']->connection());
});

Because $app is a property of Illuminate\Support\ServiceProvider and ServiceProviders are the guys who boot up services that will be used by Facades in your app.

So, first Laravel will instantiate and boot all ServiceProviders who provides the IoC binded service, for instance:

$this->app->bindShared('db', function($app)
{
    return new DatabaseManager($app, $app['db.factory']);
});

And after that particular call you have access to the Facade:

DB::table(...);

Before that, what you get is an error telling you that there is no 'db' binded.

And I have to stress that you will mostly see that being used on ServiceProviders that way, because the closure provides the $app variable to use it this way:

$app['db']->connection()...

Of course anyone can get the IoC binding for app and set it to an $app var...

Motive 2

Some others might overuse that to not break their packages easily. Relying on an Alias to make your package work is dangerous, because if the user changes that alias the package could break. That might be a user problem, but it would create some problems to them too, like issues on Github.

Otros consejos

Just to add something to this answer.

There are more types of aliases, through which providers can be resolved out of IoC:

  • Ahort aliases that are bound directly to container (this list can be found in Illuminate\Foundation\Application.php file).e.g $app["db"]

    Aliases that facades are using for "static" access (this list can be found in app/config/app.php file e.g. View::make("index");

    And you can bind with AliasLoader::getInstance() method.

This was confusing to me, because some static aliases names are different from their short provider name. For example Eloquent points to Model and Route facade accessor is router (not route). Or config that is not bound to IoC through its service provider - it points to Repository class in Application.php file. So, a lot of flexibility is offered to us through these simple patterns.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top