zoukankan      html  css  js  c++  java
  • Laravel 服务容器、服务提供器、契约实例讲解

     
     

    前言

    刚开始看laravel服务容器、契约、服务提供器的确生涩难懂,不单单是概念繁多,而且实际的demo很难找(找是找到了,但难用啊),最后就隔一段时间看一遍,大概个十来遍,还真给看出个门道,废话少说上代码。

     

    准备阶段

    首先声明一下我的测试环境
    php 7.2.4
    laravel 5.6

     

    1.创建新项目(composer)

    在你的项目目录命令行运行:

    composer create-project laravel/laravel laravelapp --prefer-dist
     

    2.创建服务提供器

    生成文件位于:项目/app/Providers/TestServiceProvider

    php artisan make:provider TestServiceProvider

    同时修改配置文件config/app.php,在providers数组中追加该服务提供器

    'providers' => [
         AppProvidersTestServiceProvider::class,
    ],
     

    3.创建自己的工作目录(xiaocai)

    我的工作目录在:项目/app/Xiaocai目录下
    项目
       |---app
           |---Xiaocai
             |---DemoInterface.php
             |---DemoProvider.php
             |---DemoProvider2.php
    写到这里你可能问我的工作目录下三个文件干什么用呢?不要着急,接下来我们逐个创建文件并进行讲解。
    1:DemoInterface.php【接口文件】这个就是laravel中提到的Contracts(契约),使用接口(契约)的原因官方也给了说明:低耦合和简单性,文件内容如下:

    <?php 
    namespace AppXiaocaiTest;
    interface DemoInterface
    { 
        function demo1();
        function demo2(); 
    } 

    接口中只简单定义两个测试方法,记住带上命名空间AppXiaocaiTest,这个很重要;
    2:DemoProvider.php【接口实现类】,这个官方并没有特别说明,当然,有了接口当然会有对应的实现类去实现接口中的方法
    文件内容如下:

    <?php 
    namespace AppXiaocaiTest;
    class DemoProvider implements DemoInterface
    {
        public function demo1()
        {
            return 'demo1';
        }
        public function demo2()
        {
            return 'demo2';
        }
    }

    对于这个实现类,我是这样理解的,laravel中的契约(接口)通过规定好方法名称,这样,第三方扩展包在想要实现这些契约方法的时候,必然要受到契约提供的方法的约束,防止滥用,使用户在使用laravel基础上的扩展包的时候,不必要再去了解底层代码逻辑,方法都是定义好的,尽管不同的包处理的逻辑不同,但是对于用户来说,都是调用的同一个方法,对于如何选择到底使用哪个实现类,我们也准备好了DemoProvider2.php类,他是DemoInterface.php的第二种实现方法。
    3:DemoProvider2.php【接口实现类2】内容如下

    <?php 
    namespace AppXiaocaiTest;
    class DemoProvider2 implements DemoInterface
    {
        public function demo1()
        {
            return 'demo1的第二种实现';
        }
        public function demo2()
        {
            return 'demo2的第二种实现';
        }
    }
     

    4.创建测试控制器

    命令行运行:

    php artisan make:controller TestController
     

    5.添加路由

    未测试控制器添加一个测试路由,修改项目/routes/web.php文件,追加代码如下:

    Route::get('/test', 'TestController@index');
     

    6.修改服务提供器文件(TestServiceProvider)

    这里是重点!这里是重点!这里是重点!重要的事情我只说三遍

    <?php
    
    namespace AppProviders;
    
    use IlluminateSupportServiceProvider;
    use AppXiaocaiTestDemoInterface;
    use AppXiaocaiTestDemoProvider;
    use AppXiaocaiTestDemoProvider2;
    
    class TestServiceProvider extends ServiceProvider
    {
        public function boot()
        {
        }
        public function register()
        {
            $this->app->bind(DemoInterface::class, DemoProvider2::class);
        }
    }

    在这里就可以对想要使用的实现接口(契约)类进行选择,$this->app->bind(arg1, arg2);参数1代表接口类,参数2代表要使用的接口实现类,你可以在这里进行切换选择实现类,切换之后如何验证呢?

     

    验证

    修改TestController文件

    <?php
    namespace AppHttpControllers;
    
    use IlluminateHttpRequest;
    use AppXiaocaiTestDemoInterface;//注意引用的是接口文件,并非实现类
    
    class TestController extends Controller
    {
        public function index(DemoInterface $demo)
        {
            dd($demo->demo1());
        }
    }

    此时浏览器输出接口不出意外的话应该是这样的:

    file
     

    我们不妨修改一下实现类,在TestServiceProvider文件中修改如下:
    $this->app->bind(DemoInterface::class, DemoProvider::class);
    //$this->app->bind(DemoInterface::class, DemoProvider2::class);

    此时再运行,如下:

    file
     
     

    总结

    如此一来,切换实现的方法是不是很简单,只需要在服务提供器中修改即可,果真是低耦合。如果文章中出现什么纰漏欢迎指出,防止祸害他人,如果觉得对您有帮助的话,点个赞支持一下吧。

     

    结语

    另外Xiaocai工作目录是测试用的,当然如果做项目的话,你也可以把你的代码上传到composer,这样通过composer直接引入到vendor目录下,通过composer的自动加载机制,这样是不是更能提高你的效率呢。

  • 相关阅读:
    vite的使用
    webpack--Plugin
    webpack--loader
    uniapp 或小程序,通过蓝牙连接设备, 给设备配网
    每一项与之前一项相加
    vue使用vue-fullpage
    React基礎
    无间隙循环轮播效果
    Wow.js动画效果
    正则表达式
  • 原文地址:https://www.cnblogs.com/brady-wang/p/10678237.html
Copyright © 2011-2022 走看看