为什么在在 Laravel 容器中依然可以获取未手动绑定的实例

1.在laravel 的服务容器中,需要先在容器绑定实例,然后通过容器app('xxx')获取对应的实例(简单的实例获取);
2.但是我新建一个类,没有在服务容器中手动绑定该实例;却依然可以通过容器app(xxx::class)获取该对象的实例;
3.没有理解laravel 是在什么时候就自动绑定了这个类的实例,
新建的测试类:
关于在laravel容器获取实例的疑问
在controller内直接打印改对象(如下):

关于在laravel容器获取实例的疑问

打印结果显示如下:

关于在laravel容器获取实例的疑问
先感谢各位了.

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
Sparkfly
最佳答案

app()->make() 源码中:

// 不存在构造方法:
 if (is_null($constructor)) {
     array_pop($this->buildStack);
     return new $concrete;
}

// 存在构造方法:
$reflector = new ReflectionClass($concrete);
return  $reflector->newInstanceArgs($instances);

Container.php 源码如下:

 /**
    * Instantiate a concrete instance of the given type.
    *
    * @param  string  $concrete
    * @return mixed
    *
    * @throws \Illuminate\Contracts\Container\BindingResolutionException
    */
public function build($concrete)
{
    // If the concrete type is actually a Closure, we will just execute it and
    // hand back the results of the functions, which allows functions to be
    // used as resolvers for more fine-tuned resolution of these objects.
    if ($concrete instanceof Closure) {
        return $concrete($this, $this->getLastParameterOverride());
    }

    $reflector = new ReflectionClass($concrete);

    // If the type is not instantiable, the developer is attempting to resolve
    // an abstract type such as an Interface of Abstract Class and there is
    // no binding registered for the abstractions so we need to bail out.
    if (! $reflector->isInstantiable()) {
        return $this->notInstantiable($concrete);
    }

    $this->buildStack[] = $concrete;

    $constructor = $reflector->getConstructor();

    // If there are no constructors, that means there are no dependencies then
    // we can just resolve the instances of the objects right away, without
    // resolving any other types or dependencies out of these containers.
    if (is_null($constructor)) {
        array_pop($this->buildStack);

        return new $concrete;
    }

    $dependencies = $constructor->getParameters();

    // Once we have all the constructor's parameters we can create each of the
    // dependency instances and then use the reflection instances to make a
    // new instance of this class, injecting the created dependencies in.
    $instances = $this->resolveDependencies(
        $dependencies
    );

    array_pop($this->buildStack);

    return $reflector->newInstanceArgs($instances);
}
5年前 评论
讨论数量: 4
leo

如果没有在容器中绑定,则等价于 new $class,如果这个类的构造函数需要参数,则会从容器中解析出对应的对象传入。

5年前 评论
Sparkfly

app()->make() 源码中:

// 不存在构造方法:
 if (is_null($constructor)) {
     array_pop($this->buildStack);
     return new $concrete;
}

// 存在构造方法:
$reflector = new ReflectionClass($concrete);
return  $reflector->newInstanceArgs($instances);

Container.php 源码如下:

 /**
    * Instantiate a concrete instance of the given type.
    *
    * @param  string  $concrete
    * @return mixed
    *
    * @throws \Illuminate\Contracts\Container\BindingResolutionException
    */
public function build($concrete)
{
    // If the concrete type is actually a Closure, we will just execute it and
    // hand back the results of the functions, which allows functions to be
    // used as resolvers for more fine-tuned resolution of these objects.
    if ($concrete instanceof Closure) {
        return $concrete($this, $this->getLastParameterOverride());
    }

    $reflector = new ReflectionClass($concrete);

    // If the type is not instantiable, the developer is attempting to resolve
    // an abstract type such as an Interface of Abstract Class and there is
    // no binding registered for the abstractions so we need to bail out.
    if (! $reflector->isInstantiable()) {
        return $this->notInstantiable($concrete);
    }

    $this->buildStack[] = $concrete;

    $constructor = $reflector->getConstructor();

    // If there are no constructors, that means there are no dependencies then
    // we can just resolve the instances of the objects right away, without
    // resolving any other types or dependencies out of these containers.
    if (is_null($constructor)) {
        array_pop($this->buildStack);

        return new $concrete;
    }

    $dependencies = $constructor->getParameters();

    // Once we have all the constructor's parameters we can create each of the
    // dependency instances and then use the reflection instances to make a
    // new instance of this class, injecting the created dependencies in.
    $instances = $this->resolveDependencies(
        $dependencies
    );

    array_pop($this->buildStack);

    return $reflector->newInstanceArgs($instances);
}
5年前 评论

谢谢各位,确实是在源码里通过反射解析出来,理解了, 谢谢

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!