基于 Laravel Route 的 ThinkSNS+ Component

在前面,我介绍了拓展类型,分别有 plus-compnentplus-plugin 两个,这里重点讲以下如何实现 plus-component 的。

plus-component 是什么

就如同名字一样,plus 代表的是 ThinlSNS+ 程序,用 - 分割 后面的 component 就是「包」或者我们理解成应用。在这里的「应用」指的是通过实现 API 或者 web 的功能。所以产生了这个类型。

但是 plus-component 不只是应用,也可以是简单的功能拓展,例如 medz/plus-storage-quniu 就是拓展的七牛云储存。

composer 插件的建立

既然涉及到路由,最开始的想法,其实是 /routes 目录下生成文件,包的路由文件复制到这里来。后来,发现了问题不足。
最后想到,plus-component 的实现,不一定是基于路由的应用,也有可能是简单的拓展。我们看下中间插件的接口类:

<?php

namespace Zhiyi\Component\Installer\PlusInstallPlugin;

use Closure;
use Illuminate\Console\Command;
use Illuminate\Console\OutputStyle;

interface InstallerInterface
{
    public function setCommand(Command $command, OutputStyle $output);

    /**
     * Get the component info.
     *
     * @return void|\Zhiyi\Component\Installer\PlusInstallPlugin\ComponentInfoInterface
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function getComponentInfo();

    /**
     * 应用安装.
     *
     * @param Closure $next
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function install(Closure $next);

    /**
     * 应用升级.
     *
     * @param Closure $next
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function update(Closure $next);

    /**
     * 应用卸载.
     *
     * @param Closure $next
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function uninstall(Closure $next);

    /**
     * 静态资源.
     *
     * @return string 静态资源目录
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function resource();

    /**
     * 路由配置.
     *
     * @return string 路由配置文件列表
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function router();
}

其中 router 成了非必需项。
转而,拥有了三个 hook 方法 installupdateuninstall 方法,这三个分别对应的是安装,升级,卸载。
而设计中,plus-component 中间插件会在 Laravel 的 /config/component.php 中增加如下配置:

'medz/plus-component-example' => 
  array (
    'installed' => false,
    'installer' => 'Medz\\Component\\ZhiyiPlus\\PlusComponentExample\\Installer\\Installer',
  ),

中间插件的 composer.json 配置

其实很简单,看到上面添加到 /config/component.php 的代码了, installer 项哪里来的呢?看下 包的配置:

{
    "name": "medz/plus-component-example",
    "type": "plus-component",
    "require": {
        "zhiyicx/plus-install-plugin": "^1.1"
    },
    "autoload": {
        "psr-4": {
                    "Medz\\Component\\ZhiyiPlus\\PlusComponentExample\\": "src/"
                }
    },
    "extra": {
        "installer-class": "Medz\\Component\\ZhiyiPlus\\PlusComponentExample\\Installer\\Installer"
    }
}

就是最后的 extra.installer-class 配置的,这里是完整的 class name,这样,在 composer 插件执行的时候读取这个额外的配置,并写入到 Laravel 的配置文件中。

install/update/uninstall

在 ThinkSNS+ 中有 php artisan component [install|update|unstall] vendor/name 这样一个命令,主要是用作 包的安装,升级,卸载。
实际运行如下:

php artisan component install medz/plus-component-example

通过这样的方式安装包,而这个命令会读取 /config/component.php 的配置,从而得到 installer ,这样,在运行不同的参数的时候后,调用 install,uodate,uninstall 等 需求 hook 达到目的。

router

在最上面的接口类中你也看到了,有一个 router 方法,这个方法返回类型有两个 void|string,所以, void 代表没有路由,string 就表示包路由文件的绝对地址。

php artisan component 命令执行的时候,对应的添加 /config/component_routes.php 里面的配置。
/app/Providers/RouteServiceProvider.php 中如下:

protected function mapVendorRoutes()
    {
        $files = config('component_routes', []);
        foreach ($files as $file) {
            include_once $file;
        }
    }

可能你会误会,为什么只是 include 进来呢?是的,这里的代码其实是参照 Route::group 来的,而在包里面的文件,可以正常的使用 Route::* 进行路由配置。

resource

既然可以基于路由,那就必然会存在静态资源的问题,在接口类中也有这样的规定:

 /**
     * 静态资源.
     *
     * @return string 静态资源目录
     *
     * @author Seven Du <shiweidu@outlook.com>
     * @homepage http://medz.cn
     */
    public function resource();

这里返回在包中静态资源存储的目录,执行安装或者升级命令的时候复制到 /public/vendor/name 目录下来达到静态资源发布的功能。

更高级的封装

这里其实是只模式封装,在 ThinkSNS+ 的 php artisan component 其实还有一个 --link 参数,做什么用的?其实不难理解,就是吧静态资源由原来的复制变成创建软链。这在开发过程中很有用。


GitHub: https://github.com/zhiyicx/thinksns-plus 欢迎点一个 Star ?。

下一篇文章,我会简单的讲以下 ThinkSNS+ 自封装的命令实现。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Seven 的代码太渣,欢迎关注我的新拓展包 medz/cors 解决 PHP 项目程序设置跨域需求。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 13

又出好东西了 哇塞

6年前 评论

上文说的 路由 和资源文件这些 composer 包中都可以独立配置啊,

所以还是想咨询一下, 你们自己实现的这一套 component 和 plugin, 跟正常情况下开发一个laravel composer package 相比, 有哪些优点? 或者说 composer 包有哪些地方满足不了你们的需求?

6年前 评论
medz

@Hexor ?废弃了~因为我们打算直接兼容 Laravel 拓展包 和 Laravel 5.5 所以基于 laravel 服务提供者重新设计了拓展。开发拓展包现在和开发 laravel 拓展一样了,目前已经做了「包自动发现」兼容方案,注入服务提供者按照 Laravel 5.5 提供的方式进行在 composer.json 中配置。其他注入点全部重写了服务类在服务提供者里面注册事件。

6年前 评论

还有一个问题是我这边碰到的, 看看你们内部有没有碰到. 因为我看你说的, 也是有多个开发者在使用这个系统的.

比如说我是一个你们这套系统的使用者, 需要你们的一个资讯模块, 所以我就单独安装了这个资讯模块. 但是对于这个资讯模块, 有些地方满足不了我的需求, 所以我就更改这个资讯模块中的某些设置, 使其更加满足我的需求.

在未来的某一天, 你们的资讯模块版本更新了, 其中一些函数的功能或者表现不一样了. 那么这个时候, 你们作为这套系统的维护者, 是以什么样的态度来面对我这个系统的使用者的? 或者说你们会建议我做些什么来应对这个模块的更新?

6年前 评论

还有啊 如果你们打算把原来的 component 和 plugin 废弃了, 那以后打算用什么方式来安装这些插件包?

是跟跟普通的composer 包一样 , composer require 直接安装嘛? 安装之后会不会有一些脚本什么的来对安装好的包进行再次处理?

6年前 评论
medz

@Hexor 其实一点,例如你需要咨询模块自己在定义一些东西~我们对用户的建议是fork我们的仓库,模块更新都会使用git管理的,你只需要合并过去即可,对于废弃的东西,都会在版本发布里面列出来的~

6年前 评论
medz

@Hexor 有一部分包是直接 require 即可,功能型的,例如咨询,音乐等,在 Laravel 的服务提供者支持注册 command 的基础上我还设计了一个更简单的 handler,handler就是一个方法,会注入一个 command 进来,你可以用也可以不用(注入进来方便调用其他 command),然后在handler里面写一些过程代码~例如包安装后的初始化执行的代码等。

6年前 评论

@medz 这部分的代码打算什么时候更新到 github 上呢

6年前 评论
medz

@Hexor 已经更新上去了~ 一直都在 github 上的,

6年前 评论
medz

@Hexor https://github.com/zhiyicx/thinksns-plus 你看看下,master 是作为开发分支的。

6年前 评论

@medz 噢 文档是不是还没更新? 我没找如何使用拓展包的相关文档

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
创始人 @ Odore Inc.
文章
33
粉丝
202
喜欢
532
收藏
198
排名:23
访问:24.7 万
私信
所有博文
社区赞助商