基礎插件生成及發佈流程

原理

1、以跨域插件為例,插件分為三部分,一個是跨域中間件程式檔案,一個是中間件設定檔 middleware.php,還有一個是透過指令自動生成的 Install.php。
2、我們使用指令將三個檔案打包並發佈到 composer。
3、當使用者使用 composer 安裝跨域插件時,插件中的 Install.php 會將跨域中間件程式檔案以及設定檔拷貝到 {主專案}/config/plugin 下,讓 webman 載入。實現了跨域中間件檔案自動配置生效。
4、當使用者使用 composer 刪除該插件時,Install.php 會刪除相應的跨域中間件程式檔案和設定檔,實現插件自動卸載。

規範

1、插件名由兩部分組成,廠商插件名,例如 webman/push,這個與 composer 包名對應。
2、插件設定檔統一放在 config/plugin/廠商/插件名/ 下 (console 命令會自動創建設定目錄)。如果插件不需要設定,則需要刪除自動創建的設定目錄。
3、插件設定目錄僅支援 app.php 插件主設定,bootstrap.php 程式啟動設定,route.php 路由設定,middleware.php 中間件設定,process.php 自訂進程設定,database.php 數據庫設定,redis.php redis 設定,thinkorm.php thinkorm 設定。這些設定會自動被 webman 辨識。
4、插件使用以下方法獲取設定 config('plugin.廠商.插件名.設定檔.具體設定項');,例如 config('plugin.webman.push.app.app_key')
5、插件如果有自己的數據庫設定,則透過以下方式訪問。illuminate/databaseDb::connection('plugin.廠商.插件名.具體的連接')thinkromDb::connct('plugin.廠商.插件名.具體的連接')
6、如果插件需要在 app/ 目錄下放置業務檔案,需要確保不與使用者專案以及其它插件衝突。
7、插件應該儘量避免向主專案拷貝檔案或目錄,例如跨域插件除了設定檔需要拷貝到主專案,中間件檔案應該放在 vendor/webman/cros/src 下,不必拷貝到主專案。
8、插件命名空間建議使用大寫,例如 Webman/Console。

示例

安裝 webman/console 命令行

composer require webman/console

創建插件

假設創建的插件名字叫 foo/admin (名稱也就是後面 composer 要發佈的專案名,名稱需要小寫)
運行命令
php webman plugin:create --name=foo/admin

創建插件後會生成目錄 vendor/foo/admin 用於存放插件相關檔案 和 config/plugin/foo/admin 用於存放插件相關設定。

注意
config/plugin/foo/admin 支援以下設定,app.php 插件主設定,bootstrap.php 程式啟動設定,route.php 路由設定,middleware.php 中間件設定,process.php 自訂進程設定,database.php 數據庫設定,redis.php redis 設定,thinkorm.php thinkorm 設定。設定格式與 webman 相同,這些設定會自動被 webman 辨識合併到設定當中。
使用時以 plugin 為前綴訪問,例如 config('plugin.foo.admin.app');

導出插件

當我們開發完插件後,執行以下命令導出插件
php webman plugin:export --name=foo/admin
導出

说明
導出後會將 config/plugin/foo/admin 目錄拷貝到 vendor/foo/admin/src 下,同時自動生成一個 Install.php,Install.php 用於自動安裝和自動卸載時執行一些操作。
安裝預設操作是將 vendor/foo/admin/src 下的設定拷貝到當前專案 config/plugin 下
移除時預設操作是將當前專案 config/plugin 下的設定檔刪除
你可以修改 Install.php 以便在安裝和卸載插件時做一些自訂操作。

提交插件

  • 假設你已經有 githubpackagist 帳號
  • github 上創建一個 admin 專案並將程式碼上傳,專案地址假設是 https://github.com/你的使用者名稱/admin
  • 進入地址 https://github.com/你的使用者名稱/admin/releases/new 發佈一個 release 如 v1.0.0
  • 進入 packagist 點擊導航裡 Submit,將你的 github 專案地址 https://github.com/你的使用者名稱/admin 提交上去這樣就完成了一個插件的發佈

提示
如果在 packagist 裡提交插件顯示字衝突,可以重新取一個廠商的名字,比如 foo/admin 改成 myfoo/admin

後續當你的插件專案程式碼有更新時,需要將程式碼同步到 github,並再次進入地址 https://github.com/你的使用者名稱/admin/releases/new 重新發佈一個 release,然後到 https://packagist.org/packages/foo/admin 頁面點擊 Update 按鈕更新版本

給插件添加命令

有時候我們的插件需要一些自訂命令來提供一些輔助功能,例如安裝 webman/redis-queue 插件後,專案將會自動增加一個 redis-queue:consumer 命令,用戶只要運行 php webman redis-queue:consumer send-mail 就會在專案裡生成一個 SendMail.php 的消費者類,這樣有助於快速開發。

假設 foo/admin 插件需要添加 foo-admin:add 命令,參考如下步驟。

新建命令

新建命令檔案 vendor/foo/admin/src/FooAdminAddCommand.php

<?php

namespace Foo\Admin;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

class FooAdminAddCommand extends Command
{
    protected static $defaultName = 'foo-admin:add';
    protected static $defaultDescription = '這裡是命令行描述';

    /**
     * @return void
     */
    protected function configure()
    {
        $this->addArgument('name', InputArgument::REQUIRED, 'Add name');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $name = $input->getArgument('name');
        $output->writeln("Admin add $name");
        return self::SUCCESS;
    }

}

注意
為了避免插件間命令衝突,命令行格式建議為 廠商-插件名:具體命令,例如 foo/admin 插件的所有命令都應該以 foo-admin: 為前綴,例如 foo-admin:add

增加配置

新建設定 config/plugin/foo/admin/command.php

<?php

use Foo\Admin\FooAdminAddCommand;

return [
    FooAdminAddCommand::class,
    // ....可以添加多個設定...
];

提示
command.php 用於給插件配置自訂命令,數組中每個元素對應一個命令行類檔案,每個類檔案對應一個命令。當使用者運行命令行時 webman/console 會自動加載每個插件 command.php 裡設定的自訂命令。想了解更多命令行相關請參考 命令行

執行導出

執行命令 php webman plugin:export --name=foo/admin 導出插件,並提交到 packagist。這樣使用者安裝 foo/admin 插件後,就會增加一個 foo-admin:add 命令。執行 php webman foo-admin:add jerry 將打印 Admin add jerry