Laravel - 使用$ app而不是Facades

时间:2013-12-03 23:45:48

标签: laravel inversion-of-control facade

在浏览Github上的一些源代码时,我注意到一些软件包使用app容器本身来访问IOC,而不是Facades。你为什么要用这样的东西......

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

......而不是这个?

$user = User::where('name', '=', 'Foo')->first();

2 个答案:

答案 0 :(得分:5)

动机1

有些包需要。

通常你会看到ServiceProviders以这种方式使用它:

$this->app['db']

或者在封闭绑定中:

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

因为$appIlluminate\Support\ServiceProvider的属性,而ServiceProviders是启动将在您的应用中使用Facades的服务的人。

因此,首先,Laravel将实例化并启动所有提供IoC绑定服务的ServiceProviders,例如:

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

在特定电话之后,您可以访问Facade:

DB::table(...);

在此之前,你得到的是一个错误,告诉你没有'db'绑定。

我必须强调一点,你会看到在ServiceProviders上使用这种方式,因为闭包提供$app变量以这种方式使用它:

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

当然,任何人都可以获得app的IoC绑定并将其设置为$app var ......

动机2

其他一些人可能会过度使用,以免轻易破坏他们的包裹。依靠别名来使您的包工作是危险的,因为如果用户更改该别名,则包可能会中断。这可能是一个用户问题,但它也会给他们带来一些问题,比如Github上的问题。

答案 1 :(得分:0)

只是为这个答案添加一些东西。

有更多类型的别名,通过这些别名可以解析IoC提供商:

  • 直接绑定到容器的Ahort别名(此列表可以是 可在 Illuminate \ Foundation \ Application.php 文件中找到).e.g $应用[ “DB”]

    外墙用于“静态”访问的别名(此列表可以是 可在 app / config / app.php文件中找到,例如视图::使( “索引”);

    你可以用AliasLoader :: getInstance()方法绑定。

这让我感到困惑,因为一些静态别名的名称不同 从他们的短提供者名称。例如,Eloquent指向模型和路径外观访问器是路由器(不是路由)。或者通过其服务提供者未绑定到IoC的配置 - 它指向 Application.php 文件中的Repository类。因此,通过这些简单的模式为我们提供了很多灵活性。