Laravel Manager驱动管理

没头脑

作者 没头脑

创建时间 2021-06-23

更新时间 2021-06-23

阅读 170

评论 0

Laravel最大的特性之一就是能够创建一个易于扩展、高度自定义的服务。你可以实例化多个遵循某个接口的类,并通过一个管理类来处理它们。例如,你可以在程序中任意调用session守卫、api守卫或是jwt守卫去检索、存储用户的信息。

Manager Class

Illuminate\Support\Manager 是驱动管理的基础。通过继承这个抽象类,我们可以轻松扩展自定义服务,并能够实例化多种不同的驱动。接下来,我们通过第三方登陆的场景来介绍Laravel的类。
假设我们的平台允许多个第三方账号登陆,例如:QQ登陆、微信登陆、Gitee登陆、Google登陆等。每个平台对外开放了不同的接口,不同的方式去获取该平台的用户信息,返回的数据也各不相同。但是,我们的目标只有一个,获取用户第三方的唯一标识、用户昵称和头像等基础信息,然后将其保存,关联到我们自己平台下的唯一账号。
小伙伴们不妨先思考一下,一般我们会怎样实现这一功能...

创建一个LoginManager

如上图所示,LoginManager继承自Manager类,LoginManager依赖于WeChatProvider和GithubProvider。WeChatProvider和GitHubProvider有一个共同的抽象标准ProviderAbstract,用于从第三方平台获取用户的信息。 LoginManager代码如下

<?php
namespace App\Http\Controllers\Auth;

use Illuminate\Support\Manager;
use App\Contract\Login\Factory;

class LoginManager extends Manager implements Factory
{
    /**
     * 创建github登陆的驱动.
     *
     * @return App\Http\Controllers\Auth\Provider\ProviderAbstract
     */
    protected function createGithubDriver()
    {
        return new GitHubProvider()
    }
    
    /**
     * 创建微信登陆的驱动.
     *
     * @return App\Http\Controllers\Auth\Provider\ProviderAbstract
     */
    protected function createWeChatDriver()
    {
        return new WeChatProvider()
    }

    /**
     * 设置默认的驱动.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return 'github';
    }
}

在服务容器中绑定Factory

然后,我们在 App\Providers\AppserviceProvider.php中添加如下代码

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Factory::class, function ($app) {
            return new LoginManager($app);
        });
    }
}

上述代码中的singleton方法表示Factory在服务容器中只会被实例化一次,之后获取的都是第一次实例化的对象。
之后,我们可以在 App\Providers\AppserviceProvider.php任意扩展LoginManager,当然,也可以在LoginManager中定义其他的驱动。

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app->make(Factory::class)->extend('google', function ($app) {
            return new GoogleProvider($app)
        })
        $this->app->make(Factory::class)->extend('gitee', function ($app) {
            return new GiteeProvider($app)
        })
        ...
    }
}

方法的调用

<?php
    // 在这里简单举例,建议为LoginManaager写一个Contract或是Facades。使用更简洁的调用方法
    $manager = app()->make(Factory::class);
    $manager->driver()->login();         // 默认是github
    $manager->driver('wechat')->login();
    $manager->driver('google')->login();
    $manager->driver('gitee')->login();

总结

在这只是简单介绍一下Laravel的Manager设计模式,如果你需要实现某个问题不同的解决方案,这会是一个不错的起点。

提 交
暂无评论