继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

如何在 Laravel 5.1 中创建服务 Service Provider

拉丁的传说
关注TA
已关注
手记 578
粉丝 126
获赞 789

这是一份面向初学者的 Laravel 5.1 中构建 Service Provider 的教程。

我在自己过去的博客中提到了我喜欢 Laravel 5.1 的架构,尤其是它引入了Service Provider,从而使你模块化的构建应用成为了可能。应用的配置常常可能成为棘手的任务,完全取决于你正在使用的框架,但幸运的是,我们正在使用的 Laravel 让这件事变得相当简单。

所以让我们开始创建一个用于演示的路由(route)。到 app/Http/routes.php中添加下面这条路由:

Route::resource('demo', 'DemoController');

通过使用 Route::resource,我们就获得了预定义好的 index,show,create,edit,update,store 和 destroy 路由。

为了实现良好的对称性,现在我们可以使用 artisan 命令行工具来为我们创建对应的控制器(controller)。键入如下指令:

php artisan make:controller DemoController

让我们打开创建好的文件,将 index 方法修改为如下内容:

public function index(){    return view('demo.index');
}

现在让我们继续在 app/Resources/views 目录下创建一个名为 Demo 的文件夹,并在文件夹中创建一个名为 index.blade.php 的视图(view)文件,内容如下:

@extends('layouts.master')

@section('content')
<h1>Demo Page</h1>
@endsection

这个例子中我们正在调用一个我已经在 layouts 文件夹中创建了的 master 页面master.blade.php。如果你的 master 用了另一个名字,那么这里你得替换掉。如果你没有 master 页面,那么就删掉第一行 extends 的全部内容,包括 @sectioin 申明。

假设你已经配置好了你的开发环境并解析了你的域名,那么当你访问路由yourapplication.com/demo,你应该可以看到内容 Demo Page 了。

好的,那么现在就让我们来创建一个Service Provider。这个Service Provider不会做太多特别有用的事情。它只是用来向你展示如何搭建它。

让我们在 app 目录下创建一个 Helpers 文件夹。然后在 Helpers 文件夹里,创建一个 Contracts 文件夹。在 Contracts 文件夹里,创建文件RocketShipContract.php 并写入下面的内容:

<?phpnamespace App\Helpers\Contracts;Interface RocketShipContract{    public function blastOff();

}

正如你所知,接口(interface)是一种用来强化架构的契约(contract)。为了定义类的接口,它必须包含名为 blastOff 的公共函数(public function)。

所以为什么要费力地创建一个契约呢?其实,Laravel 有一个神奇的功能是你可以类型提示契约,Service Provider会返回一个受它约束的具体类的实例。这实现了无与伦比的灵活性和松耦合的结构,因为你的工作将可以轻松地通过一行代码来完成。我们即将看到这是如何工作的。

首先,让我们创建一个具体类。在 app/Helpers 文件夹中,创建RocketShip.php,代码如下:

<?phpnamespace app\Helpers;use App\Helpers\Contracts\RocketShipContract;class RocketShip implements RocketShipContract{    public function blastOff()
    {        return 'Houston, we have ignition';

    }

}

你可以看到我们的具体类没有做很多事,但我们则对如何配合在一起更感兴趣。你可以自己决定你想给你的应用提供什么服务。

好的,现在我们要来创建一个符合契约和具体类的Service Provider了。在命令行中键入下面的指令:

php artisan make:provider RocketShipServiceProvider

回车确认,它就会为你创建好一个类。

新文件位于 app/Providers。前往这个文件,修改为如下内容:

<?phpnamespace App\Providers;use Illuminate\Support\ServiceProvider;use App\Helpers\RocketLauncher;class RocketShipServiceProvider extends ServiceProvider{    protected $defer = true;    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {        //
    }    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {        $this->app->bind('App\Helpers\Contracts\RocketShipContract', function(){            return new RocketShip();

        });
    }    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {        return ['App\Helpers\Contracts\RocketShipContract'];
    }

}

让我们看一下这一段:

<?phpnamespace App\Providers;use Illuminate\Support\ServiceProvider;use App\Helpers\RocketShip;class RocketShipServiceProvider extends ServiceProvider{

简单粗暴。我们有了命名空间,use 申明和 class 申明。当你创建Service Provider时,你要导入(import)具体类,像这里我在 use 申明中导入了 RocketShip。

接下来是:

protected $defer = true;

属性 $defer 设置为 true 代表这个类只有在必要的时候才会被加载,这样应用可以更高效地运行。

接下来我们有一个 boot 函数,这只是个空的存根,我们不会对它做任何配置。

然后,我们有 register 方法:

/**
 * Register the application services.
 *
 * @return void
 */public function register(){    $this->app->bind('App\Helpers\Contracts\RocketShipContract', function(){        return new RocketShip();

    });
}

你可以看到我们正在使用绑定方法来将契约和具体类绑定到一起。这是就是Service Provider定义具体类方法的地方。所以你可以很便捷地调整你想要绑定的类。之后我们会看到这如何起效。

最后,我们有 provides 方法:

/**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {        return ['App\Helpers\Contracts\RocketShipContract'];
    }

}

如果你把属性 $defer 设为 true 的话你就会需要这个方法了。

不管怎么说,这是一个相当简单的类,只是涵盖了部分的精华。

好,接下来我们需要告诉我们的应用来找到这个类,我们通过把它添加到config/app.php 中的 providers 数组来实现。

/*
         * Application Service Providers...
         */

        App\Providers\AppServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        App\Providers\RocketShipServiceProvider::class,

这里包含了一些其它的Provider作为参考,你可以看到我们的Provider在最后一行。保存完你就可以离开这里继续后面的了。

我们来修改一下 DemoController 的 index 方法:

public function index(RocketShipContract $rocketship){
        $boom = $rocketship->blastOff();        return view('demo.index', compact('boom'));
}

所以在这里,我们键入 RocketShipContract 并传递给实例变量 $rocketship。Laravel 通过Service Provider获知你其实想要的是 RocketShip 类,因为你在服务提供者里把它和契约绑定了。是不是很酷?

然后我们简单地调用 blastoff 方法并把它赋值给一个要传递向视图的变量。让我们来修改一下视图:

@extends('layouts.master')

@section('content')

    {{ $boom }}

@endsection

你可以看到我正在使用 blade 打印变量。所以浏览器中应该可以看到:

Houston, we have ignition.

所以现在为了更简单的描述能实现什么,我们可以在 Helpers 文件夹中创建第二个具体类。我们把它命名为 RocketLauncher.php,内容如下:

<?phpnamespace app\Helpers;use App\Helpers\Contracts\RocketShipContract;class RocketLauncher implements RocketShipContract{    public function blastOff()
    {        return 'Houston, we have launched!';

    }

}

你可以发现这个我们的 RocketShip 类很像,只是 blastoff 方法略有不同。所以我们在Service Provider的 register 方法中修改其中一行代码来实现它:

public function register()
    {        $this->app->bind('App\Helpers\Contracts\RocketShipContract', function(){            return new RocketLauncher();

        });
    }

还包括 use 申明:

use App\Helpers\RocketLauncher;

根据上面的简单变动,我们现在有了基于契约约束的不同的实现,所以浏览器里的结果也会产生相应变化。

尽管我们为了这个教程只是做了一个超级无聊的例子,你还是可以通过它看到这个架构的好处。通过编写一个契约而不是一个具体类,我们给自己提供了一种更灵活和简单的而方法来管理代码。

这里有一些“陷阱”你需要注意。你没法直接重命名一个Service Provider,而是需要删除它并通过 artisan 新建一个,因为创建时其它地方也会有一些不被注意的改动。这很可能与自动加载(autoload)有关。如果你发生了这类问题,你可以尝试在命令行运行 composer dump-autoload。如果仍不起作用,那就还是删除文件并重新创建吧。

另一件事是务必在最后一步才把Service Provider添加到 config/app.php。如果里面配置了一个并不存在的类估计 artisan 会崩溃。

Laravel 框架拥有完善的文档,你可以在这里阅读更多关于 Laravel Service Provider 的内容。

我希望你能享受这个教程并觉得它有价值。点击页面来阅读全部的教程。如果可以,请评论、分享和点赞,谢谢!

我没有捐款按钮,但如果你愿意支持我的工作或学习更多 Laravel 的知识,你可以通过购买我的书来实现,《Laraboot: laravel 5* For Beginners》,非常感谢。

译文链接:http://www.codeceo.com/article/laravel-service-provider.html
英文原文:How to Create a Service Provider in Laravel 5.1
翻译作者:码农网 – 任琦磊
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP