laravel扩展

刚开始看了laravel "系统架构"这一章后,感觉很难懂,不知道service provider、service container、Facade等等名词讲的是什么鬼。直到自己摸索写出了一个elastic search的服务扩展才恍然大悟。

       其实,laravel service provider、service container、Facade 讲的都是一件事儿:你可以自由扩展laravel框架的服务。 貌似还是有点懵~

       首先你要了解一点:laravel的核心其实是一个IOC容器!laravel框架提供的服务,其实都是后来才注入到容器中的!例如你熟悉的方法“DB::select()”、“Cache::put()”等等中的DB、Cache等服务都是“核心”之外的东西,都是后来才注入到laravel框架中的!如下所有的laraval框架自带的服务,都是注入到laravel核心框架后,才可以使用的!

也就是说:你可以自己定义一个服务,然后放入框架中!

下面以elasticsearch为例,注册一个elasticsearch 服务到laravel框架中。

1、“service provider” 是提供服务的东东,你想提供什么服务,就在这里面定义。

我们先在composer.json中添加elasticsearch 需要的依赖。然后使用:php artisan make:provider ElasticSearchProvider创建一个“ElasticSearchProvider”;在register中添加上你想要实例化的类,即为laravel可提供的服务。推荐使用App的singleton方法,因为很明显“单例”,或者使用其他的例如“bind”等方法,IDE上自行查阅。

 
/**
 * Register the application services.
 *
 * @return void
 */
public function register()
{
    $value = config('database.elasticsearch')['hosts'];
    $this->app->singleton('Elasticsearch\Client',function($value) use ($value){
       return ClientBuilder::create()->setHosts(
           [$value])->build();
    });
}

然后,把所写的这个provider在config目录下的app.php配置文件中的provider 那一栏做一下注册,laravel框架中就有你的服务啦!


2、你想要达到从.env取路径或者配置的效果?就像是laravel框架原生的服务一样?

也很简单,从.env里取东西,只需调用方法"env('key')",例如你在.env文件中定义了如下内容:

#elasticsearch 配置
ElasticSearch_HOST=elasticsearch
ElasticSearch_PORT=9200
你想取出来,就使用:“env("ElasticSearch_HOST")”和“env(ElasticSearch_PORT)”

但是这样会出现一个问题:由于".env"文件通常是不加入版本管理的。

/vendor
/node_modules
/public/storage
Homestead.yaml
Homestead.json
.env
.idea
_ide_helper.php
storage
bootstrap
docker
这样一来,程序就会报错。怎么办呢?细心的你可能会发现laravel自带的DB等服务,都是在config目录下的配置文件中取出.env文件中的内容的:

/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/

'redis' => [

    'cluster' => false,

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

],
我们当然可以效仿,定义一个elasticsearch配置文件。在config目录下或者写在已有的配置文件中(本例子就是),然后在配置文件中写"return 

'hosts' => env('ElasticSearch_HOST',"elasticsearch").":".env("ElasticSearch_PORT","9200")
这里的env方法如果取不到“ElasticSearch_HOST”或者“ElasticSearch_PORT”,就会默认将第二个参数返回即“elasticsearch”和“9200”,这样一来,就解决了.env文件加入版本忽略而下来代码后取不到值得问题。然后想要取配置文件中的内容的时候,使用“config”方法:例如你想取elasticsearch中的"hosts"中的内容 如上图所示。你就可以写:config("elasticsearch.hosts")。本例子是将elasticsearch的配置写在 database.php中的:

 /*
|--------------------------------------------------------------------------
| elasticsearch 相关的配置
|--------------------------------------------------------------------------
|
|
*/
 'elasticsearch' => [
    'hosts' => env('ElasticSearch_HOST',"elasticsearch").":".env("ElasticSearch_PORT","9200")
 ],
所以在取值的时候是这样的:

$value = config('database.elasticsearch')['hosts'];
3、好了,还有最后一步,你发现使用"DB::search()"等方式十分的简便:使用一个“代号”,来代表一个服务,然后直接使用这个服务,十分方便!下面就将ElasticSearch服务用“ES”来代替。

我原以为laraval框架既然支持大家自定义服务,会专门弄一个项目目录来存放Facade,就像controller目录来放置控制器一样,但是很遗憾,没找到!好吧,那只能自定义一个目录来放Facade了,我在App目录下自定义了一个Facade目录,然后写一个了Facade。

class ES extends Facade
{
    protected static function getFacadeAccessor() {
        return 'Elasticsearch\Client';
    }
}
写Facade也类也很简单:首先继承laravel框架的Illumiate\Support\Facades\Facade接口,然后重写"getFacadeAccessor方法,返回你在service provider “register”方法中注册的那个类的名字即可。(就是$this->app->singleton(类的名字,function(){...}),请自行看本文的步骤一 service provider的那张图)

最后,你在config目录下的app.php中的最后一行“aliases”配置项中填上"ES" => 对应的Facade目录下的ES类

    'Route' => Illuminate\Support\Facades\Route::class,
    'Schema' => Illuminate\Support\Facades\Schema::class,
    'Session' => Illuminate\Support\Facades\Session::class,
    'Storage' => Illuminate\Support\Facades\Storage::class,
    'URL' => Illuminate\Support\Facades\URL::class,
    'Validator' => Illuminate\Support\Facades\Validator::class,
    'View' => Illuminate\Support\Facades\View::class,
    'ES' => 刚才自定义的Facade的类的地址
],

好了,大功完成!是不是很简单!laravel的扩展性真心不错!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值