美文网首页laravel核心
laravel服务提供者与门面的使用

laravel服务提供者与门面的使用

作者: 云龙789 | 来源:发表于2018-09-03 20:55 被阅读3次

    推荐网站https://www.codecasts.com/
    具体哪个视频我忘了,视频是收费的

    • 1.先写一个类
    <?php
    
    namespace App;
    class Billing{
        public function test()
        {
            return 'test';
        }
    }
    
    • 2.然后写一个服务提供者 php artisan make:provider BillingProvider
      会在生成app/Providers/BillingProvider.php
    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    class BillingProvider extends ServiceProvider
    {
       
        public function boot()
        {
            //
        }
    
       // 此处我们绑定Billing 函数
        public function register()
        {
            $this->app->bind('billing',function (){
                return new \App\Billing();
            });
    // 框架中很多时候,都会使用 Billing::class 作为 bind()的第一个参数,比如最常用的 Request ,
    // 此处我们为了直观演示,使用一个不一样的别名。
        }
    }
    
    
    • 3.注册服务提供者
      config/app.phpproviders 数组里面添加 \App\Providers\BillingProvider::class,

    • 4 .以下三种方式都可以取值

    //    $res = app('billing')->test();
    //    $res = app()['billing']->test();
        $res = app()->make('billing')->test();
        dd($res);
    
    • 5.实现Facade
    <?php
    namespace App;
    use Illuminate\Support\Facades\Facade;
    
    class Bill extends Facade {
        protected static function getFacadeAccessor()
        {
            return 'billing'; // TODO: Change the autogenerated stub
        }
    }
    
    • 6.在config/app.phpaliases数组里面添加'Bill' => \App\Bill::class,

    dd(Bill::test())

    Facade 工作原理

    Facade 基类使用了 __callStatic() 魔术方法,直到对象从容器中被解析出来后,才会进行调用。比如以上的例子,

       public static function __callStatic($method, $args)
        {
           // $instance 得到的其实是 BillingProvider中register方法里绑定的 new \App\Billing() 实例
            $instance = static::getFacadeRoot();
    
            if (! $instance) {
                throw new RuntimeException('A facade root has not been set.');
            }
    
            return $instance->$method(...$args);
        }
    
        public static function getFacadeRoot()
        {
            return static::resolveFacadeInstance(static::getFacadeAccessor());
        }
    
    /**
         * Get the registered name of the component.
         *
         * @return string
         *
         * @throws \RuntimeException
         */
        protected static function getFacadeAccessor()
        {
            throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
        }
    注意,因为我们在实例的类中直接重写了方法,所以执行的将会是以下代码
     protected static function getFacadeAccessor()
        {
            return 'billing';
        }
         protected static function resolveFacadeInstance($name)
        {
            if (is_object($name)) {
                return $name;
            }
    
            if (isset(static::$resolvedInstance[$name])) {
                return static::$resolvedInstance[$name];
            }
    
            return static::$resolvedInstance[$name] = static::$app[$name];
        }
     /**
         * Resolve the facade root instance from the container.
         *
         * @param  string|object  $name
         * @return mixed
         */
        protected static function resolveFacadeInstance($name)
        {
            if (is_object($name)) {
                return $name;
            }
    
            if (isset(static::$resolvedInstance[$name])) {
                return static::$resolvedInstance[$name];
            }
    
            return static::$resolvedInstance[$name] = static::$app[$name];
        }
    /**
         * The resolved object instances.
         *
         * @var array
         */
        protected static $resolvedInstance;
    

    • 此处讲解下上面4中app()函数的三种用法,我们来看app()全局函数可能就理解了
    if (! function_exists('app')) {
        /**
         * Get the available container instance.
         *
         * @param  string  $abstract
         * @param  array   $parameters
         * @return mixed|\Illuminate\Foundation\Application
         */
        function app($abstract = null, array $parameters = [])
        {
            if (is_null($abstract)) {
                return Container::getInstance();
            }
    
            return Container::getInstance()->make($abstract, $parameters);
        }
    }
    
     public function make($abstract, array $parameters = [])
        {
            return $this->resolve($abstract, $parameters);
        }
    
      protected function resolve($abstract, $parameters = [])
        {
            $abstract = $this->getAlias($abstract);
    
           ....
    
            return $object;
        }
    
    
    所以app()的第一个参数其实是抽象类
    
    

    还有一种实现实时 Facade 的简单方式,就是直接在将要实现的类的原命名空间前,加上Facades,直接使用手册里的例子吧

    <?php
    
    namespace App;
    
    use Facades\App\Contracts\Publisher;
    use Illuminate\Database\Eloquent\Model;
    
    class Podcast extends Model
    {
        /**
         * 发布 Podcast.
         *
         * @return void
         */
        public function publish()
        {
            $this->update(['publishing' => now()]);
    
            Publisher::publish($this);
        }
    }
    

    推荐laravel空类继承总是继承SPL的原因

    相关文章

      网友评论

        本文标题:laravel服务提供者与门面的使用

        本文链接:https://www.haomeiwen.com/subject/zhgiwftx.html