精华内容
下载资源
问答
  • Laravel 容器是完全独立的,即使你的项目不是基于 Laravel 框架的,依然可以使用 Laravel 的服务容器,只要通过 Composer 安装 illuminate/container 就好了。想了解更多关于容器的知识?去读源码吧!容器在底层只有...

    laravel-container

    Laravel 容器是完全独立的,即使你的项目不是基于 Laravel 框架的,依然可以使用 Laravel 的服务容器,只要通过 Composer 安装 illuminate/container 就好了。想了解更多关于容器的知识?去读源码吧!容器在底层只有一个类 Illuminate\Container\Container 读完了你就会对容器如何工作有更深的理解。

    初始化composer.json

    vi composer.json

    {
        "name": "laravel/container",
        "description": "Laravel Container.",
        "keywords": ["container", "laravel"],
        "license": "MIT",
        "type": "project",
        "require": {
            "php": "^7.0.0"
        },
        "autoload": {
        },
        "minimum-stability": "dev",
        "prefer-stable": true
    }
    

    安装laravel-container

    composer require illuminate/container
    

    psr-4 autoload

    vi composer.json

    {
        "autoload": {
            "files": [
                "app/Support/helpers.php"
            ],
            "psr-4": {
                "App\\": "app/"
            }
        }
    }
    

    App\Application

    vi app/Application.php

    namespace App;
    
    use Illuminate\Container\Container;
    
    class Application extends Container
    {
    
        public function __construct()
        {
            static::setInstance($this);
        }
    
    }
    

    helpers.php

    vi app/Support/helpers.php

    function app($abstract = null, array $parameters = [])
    {
        if (is_null($abstract)) {
            return Illuminate\Container\Container::getInstance();
        }
    
        return Illuminate\Container\Container::getInstance()->make($abstract, $parameters);
    }
    

    index.php

    vi public/index.php

    require __DIR__ . '/../vendor/autoload.php';
    
    $app = new App\Application();
    
    $app->instance('name', 'Cuber');
    s($app->make('name'));
    s(app('name'));
    s(app());
    
    展开全文
  • laravel 容器

    千次阅读 2017-02-14 10:18:00
    laravel IoC 容器
    部分摘自:https://www.insp.top/article/learn-laravel-container
    
    Laravel 的核心就是一个 IoC 容器,根据文档,称其为“服务容器”,顾名思义,该容器提供了整个框架中需要的一系列服务。
    面向对象编程,有以下几样东西无时不刻的接触:接口、类还有对象。这其中,接口是类的原型,一个类必须要遵守其实现的接口;对象则是一个类实例化后的产物,我们称其为一个实例。


    依赖:
    class Superman
    {
        protected $power;
     
        public function __construct()
        {
            $this->power = new Power(999, 100);
        }
    }




    依赖:构造函数初始化
    class Flight
    {
        protected $speed;
        protected $holdtime;
        public function __construct($speed, $holdtime) {}
    }
     
    class Force
    {
        protected $force;
        public function __construct($force) {}
    }
     
    class Shot
    {
        protected $atk;
        protected $range;
        protected $limit;
        public function __construct($atk, $range, $limit) {}
    }
    class Superman
    {
        protected $power;
     
        public function __construct()
        {
            $this->power = new Fight(9, 100);
            // $this->power = new Force(45);
            // $this->power = new Shot(99, 50, 2);
            /*
            $this->power = array(
                new Force(45),
                new Shot(99, 50, 2)
            );
            */
        }
    }




    依赖:工厂模式--就是一个类所依赖的外部事物的实例,都可以被一个或多个 “工厂” 创建的这样一种开发模式。
    class Superman
    {
        protected $power;
     
        public function __construct(array $modules)
        {
            // 初始化工厂
            $factory = new SuperModuleFactory;
     
            // 通过工厂提供的方法制造需要的模块
            foreach ($modules as $moduleName => $moduleOptions) {
                $this->power[] = $factory->makeModule($moduleName, $moduleOptions);
            }
        }
    }
     
    // 创建超人
    $superman = new Superman([
        'Fight' => [9, 100], 
        'Shot' => [99, 50, 2]
        ]);




    控制反转IoC是Inversion of Control的缩写,即由外部负责其依赖需求(获取依赖对象的方式由内部改成外部),比如IoC容器和配置文件。
    依赖注入DI是Dependency Injection缩写,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。依赖,只要不是由内部生产(比如初始化、构造函数__construct 中通过工厂方法、自行手动 new 的),而是由外部以参数或其他形式注入的,都属于依赖注入(DI)。DI一般利用反射机制完成。


    DI的方式由3种: 构造函数、setter注入、函数注入

    展开全文
  • Laravel 容器解析

    千次阅读 2017-09-21 16:18:10
    laravel容器laravel容器负责存放所需要的各种类,当需要的时候再从容器中解析。下面我们对容器进行分析,如果有谬误,欢迎指正。入口文件laravel入口文件在public目录下面的index.php。然后进入index.php。require _...
    laravel容器

    laravel容器负责存放所需要的各种类,当需要的时候再从容器中解析。下面我们对容器进行分析,如果有谬误,欢迎指正。


    入口文件

    laravel入口文件在public目录下面的index.php。然后进入index.php。

    require __DIR__.'/../bootstrap/autoload.php';
    
    
    $app = require_once __DIR__.'/../bootstrap/app.php';
    类的自动加载可以看我的另一篇博文:  http://blog.csdn.net/qq_16877261/article/details/77707453

    查看app.php代码如下,然后进入laravel容器。

    $app = new Illuminate\Foundation\Application(
        realpath(__DIR__.'/../')
    );

    直接查看容器的构造函数如下:

    注册路径

    public function __construct($basePath = null)
    {
        if ($basePath) {
            $this->setBasePath($basePath);
        }
    
        //注册容器基本实例
        $this->registerBaseBindings();
        $this->registerBaseServiceProviders();
        //注册核心的容器类别名
        $this->registerCoreContainerAliases();
    }
    首先我们先查看setBasePath 这个函数,最终发现通过bindPathsInContainer这个函数将一些常用的路径绑定到容器。关于绑定函数instance 请查看博文:http://blog.csdn.net/qq_16877261/article/details/78189673

    instance 绑定其实就是将绑定的对象放入容器中的$instances 数组中,我打印这个数组结果如下,发现laravel绑定路径其实和其他框架里将路径定义为常量的效果是一样的。



    绑定容器实例

    接着我看下一个函数registerBaseBindings,代码如下:

    在该方法中,首先将当前的类设置为全局的容器实例,然后将app与容器实例进行绑定,方便以后通过访问app属性来访问容器。最后将Container类的访问也绑定到容器实例。

    绑定所谓的服务提供者

    找到 registerBaseServiceProviders函数如下

    protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));
        $this->register(new LogServiceProvider($this));
        $this->register(new RoutingServiceProvider($this));
    }
    以EventServiceProvider 为例,然后查看register函数如下

    public function register($provider, $options = [], $force = false)
    {
        //检查是否已经注册
        if (($registered = $this->getProvider($provider)) && ! $force) {
            return $registered;
        }
        // If the given "provider" is a string, we will resolve it, passing in the
        // application instance automatically for the developer. This is simply
        // a more convenient way of specifying your service provider classes.
        if (is_string($provider)) {
            $provider = $this->resolveProvider($provider);
        }
        //通过这一步实现服务提供者的绑定,然后查看具体服务提供者的
        //register 函数
    if (method_exists($provider, 'register')) { $provider->register(); } $this->markAsRegistered($provider); // If the application has already booted, we will call this boot method on // the provider class so it has an opportunity to do its boot logic and // will be ready for any usage by this developer's application logic. if ($this->booted) { $this->bootProvider($provider); } return $provider;}

    EventServiceProvider 类下的register函数如下

    public function register()
    {
        $this->app->singleton('events', function ($app) {
            return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
                return $app->make(QueueFactoryContract::class);
            });
        });
    }
    于是我们去查看容器中的singleton 函数如下,发现singleton函数其实只是bind函数最后一个参数为为true。

    /**
     * Register a shared binding in the container.
     *  绑定到容器的对象只会被解析一次,之后的调用都返回相同的实例:
     * @param  string|array  $abstract
     * @param  \Closure|string|null  $concrete
     * @return void
     */
    public function singleton($abstract, $concrete = null)
    {
        $this->bind($abstract, $concrete, true);
    }
    


    于是查看bind函数如下:

    public function bind($abstract, $concrete = null, $shared = false)
    {
        // If no concrete type was given, we will simply set the concrete type to the
        // abstract type. After that, the concrete type to be registered as shared
        // without being forced to state their classes in both of the parameters.
    
        //移除旧的实例
        $this->dropStaleInstances($abstract);
        if (is_null($concrete)) {
            $concrete = $abstract;
        }
        // If the factory is not a Closure, it means it is just a class name which is
        // bound into this container to the abstract type and we will just wrap it
        // up inside its own Closure to give us more convenience when extending.
        if (! $concrete instanceof Closure) {
    
    // 绑定的时候,如果$concrete 是具体的类名,通过下面的函数封装成闭包
    闭包里面的内容一般是这样的            return  $this->make($concrete);或者$this->build($concrete);
     $concrete = $this->getClosure($abstract, $concrete);
        }
        // 创建一个包含变量与其值的数组。
        //对每个参数,compact() 在当前的符号表中查找该变量名并将它添加到输出的数组中,变量名成为键名而变量的内容成为该键的值。简单说,它做的事和 extract() 正好相反。返回将所有变量添加进去后的数组。
        $this->bindings[$abstract] = compact('concrete', 'shared');
    
        // If the abstract type was already resolved in this container we'll fire the
        // rebound listener so that any objects which have already gotten resolved
        // can have their copy of the object updated via the listener callbacks.
    
    //检查是否解析过 或则 已经存在所要绑定对象对应的实例
     if ($this->resolved($abstract)) { $this->rebound($abstract); }}
    由于 events 是第一次绑定,不会进行  $this->rebound($abstract); 最后singleton 函数执行后的结果是  打印$this->bindings 如下


    singleton 函数 在对象第一次进行绑定时,只是进行对象的绑定,而不会执行额外的操作,例如 不会对绑定的匿名函数进行执行。

    服务容器解析

    下面我们分析下对象的解析,以入口文件这行代码进行讲解

    dd(

    Illuminate\Contracts\Http\Kernel::class
    )   //   Illuminate\Contracts\Http\Kernel    绑定的类名为  
    "App\Http\Kernel"

    $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
    
     make 函数如下

    /**
     * Resolve the given type from the container.
     *
     *  从容器中解析实例
     * @param  string  $abstract
     * @return mixed
     */
    public function make($abstract)
    {
        $needsContextualBuild = ! is_null(
            $this->getContextualConcrete($abstract = $this->getAlias($abstract))
        );
        // If an instance of the type is currently being managed as a singleton we'll
        // just return an existing instance instead of instantiating new instances
        // so the developer can keep using the same objects instance every time.
        if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
            return $this->instances[$abstract];
        }
    
        //获取具体实现,一般从容器中的$this->bingdings 数组中获取,如果没有,直接返回类名
     $concrete = $this->getConcrete($abstract);
    
        // We're ready to instantiate an instance of the concrete type registered for
        // the binding. This will instantiate the types, as well as resolve any of
        // its "nested" dependencies recursively until all have gotten resolved.
        if ($this->isBuildable($concrete, $abstract)) {
            $object = $this->build($concrete);
        } else {
            $object = $this->make($concrete);
        }
    
        // If we defined any extenders for this type, we'll need to spin through them
        // and apply them to the object being built. This allows for the extension
        // of services, such as changing configuration or decorating the object.
        foreach ($this->getExtenders($abstract) as $extender) {
            $object = $extender($object, $this);
        }
    
        // If the requested type is registered as a singleton we'll want to cache off
        // the instances in "memory" so we can return it later without creating an
        // entirely new instance of an object on each subsequent request for it.
        if ($this->isShared($abstract) && ! $needsContextualBuild) {
            $this->instances[$abstract] = $object;
        }
    
        $this->fireResolvingCallbacks($abstract, $object);
    
        $this->resolved[$abstract] = true;
    
        return $object;
    }
    按照程序执行,由于是第一次解析,执行

     $this->build($concrete); 
    于是我又去查看build函数

    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.
        //是否是闭包(匿名函数),在本例中由于是闭包,就直接返回闭包执行的结果。由于这个闭包是自动封装的闭包,格式如下
    // $this->make($concrete);  其实就是直接解析绑定的类,在本例中就是  App\Http\Kernel  于是又需要查看make函数
    
     if ($concrete instanceof Closure) {
            return $concrete($this);
        }
    
        $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);}




























    展开全文
  • octohost 的 Laravel 容器。 将此 repo 推送到您的 octohost: git clone https://github.com/octohost/laravel.git cd laravel git remote add octohost git@ip.address.here:laravel.git git push octohost ...
  • laravel容器

    2018-07-27 17:01:09
    https://laravel-china.org/articles/789/laravel-learning-notes-the-magic-of-the-service-container
    展开全文
  • 主要介绍了laravel容器延迟加载以及auth扩展详解,需要的朋友可以参考下
  • Laravel容器

    2018-01-16 08:46:54
    http://blog.csdn.net/nuli888/article/details/51884156这个大牛写的很赞,手动赞~
  • 不管在构造方法中还是在普通方法中,通过对变量使用类的类型提示,容器会自动创建一个实例并赋给这个变量,比如一个 Work 类的构造函数: public function __construct(Service $service) { $this->service = ...
  • laravel容器管理理解

    2018-07-03 03:32:08
    1.laravel容器的基本认识 在bootstrap/app.php内进行实例化,$app为容器管理工具,负责所有的服务组件的实例化以及实例化生命周期的管理。 优点:很好对代码进行解耦,写业务代码时,不用担心服务组件的对象从何而来,...
  • laravel服务容器 laravel服务容器可以理解为是一个自动产生类的工厂。 电脑有键盘,比方:雷蛇,双飞燕。 有时候使用双飞燕,有时候雷蛇 这两个统称为键盘,所以写一个接口类 textlaravel.cc\laravel5\app\...
  • Laravel容器和装订

    2018-05-18 11:29:25
    <p><a href="https://laravel.com/docs/5.6/container#binding" rel="nofollow noreferrer">Laravel 5.6 Documentation</a> says: <p>There is no need to bind classes into the container if they do not ...
  • 本文转载与https://www.insp.top/learn-laravel-container 容器,字面上理解就是装东西的东西。常见的变量、对象属性等都可以算是容器。一个容器能够装什么,...IoC 容器laravel 的核心 Laravel 的核心就是一个 I
  • 今天抽时间又仔细看了一下laravel的container,记录一下。 所谓容器,听名字就知道,是一个仓库,装东西用的,所以,container所有的功能,都围绕一个主题:管理装。 类名称:Illuminate\Container\Container ...
  • laravel 容器/构建方式

    2019-11-15 20:13:44
    # make $content = OrderRenderService::make($allocation->Order)->render(); # () (new OrderRenderService($allocation->Order))->render();...$a = new OrderRenderService($allocation->...
  • laravel容器(精简版)

    2020-07-11 11:24:25
    容器 <?php class Container { protected $bindings = []; //绑定接口和生成相应实例的回调函数 "traveller", "Traveller" public function bind($abstract, $concrete = null, $shared = false) { if (! $...
  • 深入理解Laravel容器概念,DI依赖注入,IOC控制反转 IOC - 控制反转 DI - 依赖注入 这两个存在的目的都是为了解耦! 解耦可以理解为,原本紧密结合的两个磁铁,现在我们在他们中间加一层木板,强行将他们分开,却不...
  • 容器类调用make方法时,如果没有已注册的key,那么会自动通过反射类实例化具体类 make /** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters *...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,857
精华内容 2,342
关键字:

laravel容器的使用