阅读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
是将被绑定的对象的别名。但是对象在哪里?
有人可以解释吗?谢谢您的帮助。
答案 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
是一个接口,Cents
和Cheque
是该接口的实现。从字面上看,该示例意味着,如果您在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);