Composer Package 套件開發第三篇
先前已經紀錄過兩篇關於模組開發的文章,如果你還沒看過這兩篇請先閱讀
本篇會從頭再帶一次整個開發流程,以及更多的使用方式,包含publish migration以及view的用法
1.建立開發測試用的專案
這個專案目的在於透過laravel本身直接執行package程式碼,確認package本身沒有問題
1 |
composer create-project laravel/laravel packageDev --prefer-dist |
建立一個名為packageDev的Laravel專案來使用
接著建立”packages”資料夾,作為開發套件的根目錄
2.建立套件資料夾
接著將套件使用的資料夾建立起來後,資料夾結構會長這個樣子
1 |
packageDev/packages/vendor_name/package_name/src |
接著建立起src/Facades資料夾以及package_name.php 檔案,讓套件method可以使用static的方式來呼叫使用
用一個範例來看,packages資料夾底下結構會是這個樣子
假設在sitemap套件底下,你會一個Sitemap.php作為主要邏輯檔案,一個SitemapServiceProvider.php註冊為service provider使用
以及Facades資料夾底下的SItemap.php
3.建立套件的composer.json檔
以上方範例來說
切換到packageDev/packages/virtualorz/sitemap資料夾後透過以下指令建立composer.json
1 |
composer init |
這個指令會帶你幾個步驟將資料填寫完畢即可,最主要依定要填入name, author
接著請編輯這個composer.json檔案,加入autoload的psr-4描述,讓這個package可以被載入
以上方的範例來說,編輯完過後的composer.json會長這個樣子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "name": "virtualorz/sitemap", "authors": [ { "name": "virtualorz", } ], "require": {}, "autoload": { "psr-4": { "Virtualorz\\Sitemap\\": "src/" } } } |
接著,如果你有其他必須要依賴使用的套件請編輯”require”區域,舉例像是底下的範例就需要依賴使用 actionLogin 0.0.8版本以上以及sitemap0.0.3版本以上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "name": "virtualorz/permission", "authors": [ { "name": "virtualorz", } ], "require": { "virtualorz/actionLog": "^0.0.8", "virtualorz/sitemap": "^0.0.3" }, "autoload": { "psr-4": { "Virtualorz\\Permission\\": "src/" } } } |
接著,必須要回到packageDev根目錄中更新autoload
1 |
composer dump-autoload |
4.建立以及編輯套件的serviceProvider檔
1 |
php artisan make:provider SitemapServiceProvider |
建立好serviceProvider需要將檔案從packageDerv/app/providers底下移動到packageDev/packages/virtualorz/src 底下
然後編輯一下namespace,以及register的部分,大概會像這個樣子
其中,register的部分註冊讓package method可以透過facades資料夾中定義好的方式靜態呼叫
1 2 3 |
$this->app->singleton('sitemap',function(){ return new Sitemap(); }); |
5.編輯Facades/package_name.php
以上面的範例來看,Facades/Sitemap.php會長這個樣子
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php namespace Virtualorz\Sitemap\Facades; use Illuminate\Support\Facades\Facade; class Sitemap extends Facade { protected static function getFacadeAccessor() { return 'sitemap'; } } |
6.註冊serviceProvider以及aliases
以上面的範例,需要在packageDev/config/app.php 中註冊以下資料
1 2 3 4 5 6 7 8 9 10 11 |
'providers' => [ ..... Virtualorz\Sitemap\SitemapServiceProvider::class, ..... ], 'aliases' => [ ..... 'Sitemap' => Virtualorz\Sitemap\Facades\Sitemap::class, ..... ] |
將套件sitemp帶入到packageDev專案中使用
現在,你就可以跟在github上面看到的套件一樣在controller中呼叫你的package method了
像是這個Stitemap套件,就可以在packageDev專案中這樣子使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Sitemap; class TestController extends Controller { public function index(Request $request){ Sitemap::getMenu(); } } |
7.如果需要將套件中設定檔或者其他JS檔複製到專案資料夾中使用,可以這樣做
舉例來說,permission套件中需要將src/asset以及src/config打下的檔案複製到pacakageDev底下使用
資料夾結構會是這樣子
可以在permissionServiceProder.php中的boot() 寫入以下資訊,就可以將asset中所有檔案複製到packageDev中的config資料夾
以及將config資料夾中的檔案複製到packageDev中的public/vender/treeView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php namespace Virtualorz\Permission; use Illuminate\Support\ServiceProvider; class PermissionServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // $this->app->singleton('permission',function(){ return new Permission(); }); } /** * Bootstrap services. * * @return void */ public function boot() { // $this->publishes([ __DIR__.'/config' => base_path('config'), __DIR__.'/asset/treeView' => public_path('vendor/treeView'), ]); } } |
8.如果需要用到vview以及route,也可以這麼做
舉例來說fileupload套件中會有自己定義好的route讓專案執行某個路徑就可以處理檔案上傳的資料
以及在fileupload套件中也會有個method透過view將html產生回傳給controller
因此我們可以這樣定義資料結構
src/routes.php是定義上傳檔案所需要用到的url,會長這個樣子
1 2 3 4 5 6 |
Route::post('/virtualorz/upload', [ 'as' => 'virtualorz.upload' , 'uses' => 'Virtualorz\Fileupload\Fileupload@index', 'permission' => false ]); |
而view/uploadArea.blade.php,就是預先定義好拿來產生html的blade file
接著需要在FileuploadServiceProvider.php中定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php namespace Virtualorz\Fileupload; use Illuminate\Support\ServiceProvider; class FileuploadServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // $this->app->singleton('fileupload',function(){ return new Fileupload(); }); } /** * Bootstrap services. * * @return void */ public function boot() { // $this->loadViewsFrom(__DIR__.'/view', 'fileupload'); $this->loadRoutesFrom(__DIR__.'/routes.php'); $this->publishes([ __DIR__.'/asset/fileupload' => public_path('vendor/fileupload') ]); } } |
其中loadViewsFrom 是讓系統知道可以從那邊存取view blade
loadRoutesFrom是讓系統知道可以從哪邊存取route檔案
所以這時候在如果存取 http://package_url//virtualorz/upload 就可以使用package中定義好的 ‘Virtualorz\Fileupload\Fileupload@index’
9.如果你需要定義資料表來存取資料,你可以這麼做
舉例來說,aactionLog套件需要建立一張’system_log’資料表來儲存記錄訊息
所以我們先建立system_log migration
1 |
php artisan make:migrate create_system_log |
接著把檔案從 packageDev/database/migrations/ 搬移到 packageDev/packages/virtualorz/actionLog/migrations中
接著編輯好migrate檔案後,在ActionLogServiceProvider中註冊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php namespace Virtualorz\ActionLog; use Illuminate\Support\ServiceProvider; class ActionLogServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // $this->app->singleton('actionLog',function(){ return new ActionLog(); }); } /** * Bootstrap services. * * @return void */ public function boot() { // $this->loadMigrationsFrom(__DIR__.'/migrations'); $this->loadViewsFrom(__DIR__.'/view', 'actionLog'); $this->publishes([ __DIR__.'/config' => base_path('config'), ]); } } |
其中,loadMigrationsFrom讓系統知道可以從哪邊讀取migrate檔案,這麼一來執行
php artisan migration時就會將這個指定的路徑納入
10.最後,請記得編輯readme.md
readme.md是整個套件使用的入門,readme.md檔是markdown語法構成的,不熟悉markdown可以參考
回到套件根目錄後透過touch readme.md 可以建立空的檔案,然後直接使用編輯器編寫即可
接下來的步驟就是將git push到github上,以及設定好tag version,然後submit到packagist上就可以透過composer找到你的套件了
步驟不多,也就不再詳述可以直接參考 模組化 套件 開發自己的Package
以上範例皆存在gihub上,可以自由參考