Laravel 5-如何使用$ this-> app-> when()

时间:2018-10-12 10:28:59

标签: php laravel laravel-5.4

阅读laravel bindings的知识,我理解$this->app->bind$this->app->singleton$this->app->instance,因为它们几乎相同。

但是$this->app->when对我来说有点棘手。

在laravel示例中

$this->app->when('App\Http\Controllers\UserController')
          ->needs('$variableName')
          ->give($value);

据我了解,它会注入一些原始值,App\Http\Controllers\UserController是将被绑定的对象的别名。但是对象在哪里?

有人可以解释吗?谢谢您的帮助。

3 个答案:

答案 0 :(得分:1)

这意味着如果实例化一个NULL类,并且它需要一个名称为UserController的变量,Larvel将自动使用给定值解析此变量,而您不必提供它。

例如:

$variableName

只要需要名称为$value = "Sven" $this->app->when('App\Http\Controllers\UserController') ->needs('$userName') ->give($value); 的变量,它将在用户控制器中插入值“ Sven”

换句话说,如果您有一个类似$userName的函数,Laravel知道要插入什么,因为它知道需要一个public function __construct(Request $request)对象。当您使用Request之类的函数时,Laravel不知道要在此处插入什么,实际上,您告诉Laravel如何使用绑定来解析此变量。

这是原始绑定的示例,有关上下文绑定,请参见@Namoshek的答案

答案 1 :(得分:1)

上下文绑定不适用于变量名,但适用于类型。根据上下文,它用于为使用类或函数的接口提供不同的实现。实际上,您实际上可以读取方法调用,并且它确实可以实现您的期望。为了对此进行详细说明,我将以文档为例并稍作修改:

$this->app->when(Worker::class)
          ->needs(Money::class)
          ->give(function () {
              return new Dollar();
          });

$this->app->when(Boss::class)
          ->needs(Money::class)
          ->give(function () {
              return new Cheque();
          });

在此示例中,Money是一个接口,CentsCheque是该接口的实现。从字面上看,该示例意味着,如果您在Money类上键入Worker,它将解析为Dollar的实例,而它将解析为{{1} }类。为了说明,这里是实现和结果:

Cheque

现在我们键入Boss界面以查看将得到的内容:

interface Money
{
    public function getAmount();
}

class Dollar implements Money
{
    public function getAmount()
    {
        return 1;
    }
}

class Cheque implements Money
{
    public function getAmount()
    {
        return 100000;
    }
}

答案 2 :(得分:0)

万一有人发现这个线程,试图在 app()->make() 或类似情况下实现上下文绑定:

use Closure;
use Illuminate\Container\Container;

class FooBar {

    public function doSomething(): void
    {
       //...do your thing
       $this->getFooObject();
    }

    private function getFooObject(): FooAbstract 
    {
        $class = FooAbstract::class;
        $buildStack = static::class;

        app()->beforeResolving(
                $class,
                Closure::bind(
                    function () use ($buildStack) {
                        $this->buildStack[] = $buildStack;
                    },
                    app(),
                    Container::class,
                )
           );

        return app($class);
    }
}

在上面的例子中,laravel 的应用容器被绑定为 $this 到这个闭包。由于用于标识“需要”正在创建的对象的对象的 buildStack 属性是受保护的,因此我们可以访问它,并且可以将类名添加到堆栈中。

例如:if $buildStack = Bar::class;您可以执行以下操作

app()->when(FooBar::class)->needs(FooAbstract::class)->give(FooImplementation::class);