在前面,我介紹了擴充型別,分別有 plus-compnent
和 plus-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 方法 install
、update
和 uninstall
方法,這三個分別對應的是安裝,升級,解除安裝。
而設計中,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 協議》,轉載必須註明作者和本文連結