擴充包開發
擴充包開發
- 簡介
- #語言包
- 視圖
- 命令
」擴充功能是在Laravel 中新增功能的主要方式。擴充包可以包含許多有用的功能,例如時間處理擴充包
Carbon
Behat
。當然,擴充包有很多種類型。有些擴充包是獨立運行的,這意味著他們可以在任意的 PHP 框架中使用。 Carbon 和 Behat 就是這樣的獨立擴充包。要在 Laravel 中使用這種擴充包只需要在 composer.json
檔案中引入他們即可。 另一方面,有些擴充包只能在 Laravel 中使用。這些擴充包可能包含專門用來增強 Laravel 應用的路由、控制器、視圖和配置的檔案。這份指南主要介紹 Laravel 擴充包的開發。 當開發Laravel 應用時,通常使用契約(contracts)或facades 沒有區別,因為他們都提供基本相同的可測試能力。然而,在進行擴充包開發的時候,擴充包並不能存取 Laravel 提供的所有測試輔助函數。如果你想像在 Laravel 應用程式中一樣編寫擴充包的測試案例,你可以使用擴充包發現擴充包
在Laravel 應用的config/app.php
設定檔中,providers
選項定義了能夠被Laravel 載入的服務提供者列表。當有人安裝你的擴充包時,你需要將你的服務提供者包含到這個清單中。你可以將服務提供者定義到擴充包的 composer.json
檔案中的 extra
部分,而不是讓使用者手動將你的服務提供者新增到清單中。除了服務提供者,還可以列出所有你想註冊的facades:
"extra": { "laravel": { "providers": [ "Barryvdh\Debugbar\ServiceProvider" ], "aliases": { "Debugbar": "Barryvdh\Debugbar\Facade" } } },
一旦你的擴充包配置為可發現,Laravel 就會在安裝時自動註冊擴充包的服務提供者和facades,為擴充包的使用者提供一個友善的安裝體驗。
選擇性的發現擴充包
如果你是擴充包的用戶,想要禁止一個擴充包被發現,你可以在應用的composer .json
檔案中的extra
部分列出這個擴充包:
"extra": { "laravel": { "dont-discover": [ "barryvdh/laravel-debugbar" ] } },
你也可以透過在套用的dont-discover
指令中使用*
字符,停用擴充功能發現功能:
"extra": { "laravel": { "dont-discover": [ "*" ] } },
#服務提供者
服務提供者讓你的擴充包與Laravel 連結在一起。服務提供者負責將一些東西綁定到 Laravel 的 服務容器 中,並告訴 Laravel 從哪裡加載擴充包的資源文件,例如視圖、設定檔、語言包等。
服務提供者繼承了 Illuminate\Support\ServiceProvider
類,並包含了兩個方法:register
和 boot
。基底類別 ServiceProvider
位於名為 illuminate/support
的 Composer 擴充包中,你必須將它加入到你的擴充包依賴。想要了解更多關於服務提供者的結構和用途,請查閱它的文件.
資源文件
設定
有時,你需要將擴充包設定檔發佈到應用程式本身的config
目錄中。這樣使用擴充包的使用者就可以輕鬆的重寫預設配置項目。想要發布擴充包設定文件,只需要在服務提供者的boot
方法中呼叫publishes
方法即可:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->publishes([ __DIR__.'/path/to/config/courier.php' => config_path('courier.php'), ]); }
現在,當擴充包的用戶執行Laravel 的vendor:publish
指令,擴充包檔案就會被複製到指定的目錄中。當然,一旦你的設定檔被發布,就可以像其他設定一樣被存取:
$value = config('courier.option');
#{note} 你不應該在設定檔中定義閉包函數。因為當使用者執行
config:cache
Artisan 指令時,設定檔將無法被正確的序列化。
擴充包預設配置
你也可以將擴充包預設配置與套用的副本配置合併在一起。這樣擴充包使用者就可以在副本設定檔中定義他們想要覆寫的設定選項。想要合併配置,只需要在服務提供者的register
方法中呼叫mergeConfigFrom
方法:
/** * 在容器中注册绑定。 * * @return void */ public function register(){ $this->mergeConfigFrom( __DIR__.'/path/to/config/courier.php', 'courier' ); }
{note} 此方法只合併配置數組的第一維。如果擴充包使用者定義了多維配置數組,缺少的選項將不會被合併。
路由
#如果你的擴充包包含路由文件,你需要使用 loadRoutesFrom
方法載入他們。此方法將自動判斷應用程式的路由是否已被緩存,如果路由已緩存,將不會載入你的路由檔案:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->loadRoutesFrom(__DIR__.'/routes.php'); }
資料庫遷移
如果你的擴充包包含資料庫遷移,你需要使用loadMigrationsFrom
方法告知Laravel 如何載入他們。 loadMigrationsFrom
方法只需要擴充包遷移檔案路徑作為唯一參數:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->loadMigrationsFrom(__DIR__.'/path/to/migrations'); }
一旦你的擴充包遷移檔案被註冊,當執行php artisan migrate
指令時他們就會被自動執行。你不需要將他們匯入到應用的 database/migrations
目錄中。
語言包
#如果你的擴充包中包含語言包文件,你需要使用loadTranslationsFrom
方法告知Laravel 如何載入他們。例如,如果你的擴充包名為courier
,你需要將下面的內容加入到服務提供者的boot
方法:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier'); }
擴充包翻譯約定使用package::file.line
語法進行參考。因此,你可以按照下面的方式來載入courier
擴充包中的messages
檔案的welcome
行:
echo trans('courier::messages.welcome');
#發佈語言包
如果你想要將擴充包中的語言包發佈到應用程式的resources/lang/vendor
目錄,可以使用服務提供者的publishes
方法。 publishes
方法接收一個包含語言包路徑和對應發佈位置的陣列。例如,發布courier
擴充包的語言包文件,操作如下:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier'); $this->publishes([ __DIR__.'/path/to/translations' => resource_path('lang/vendor/courier'), ]); }
現在,當擴充包的使用者執行Laravel 的vendor:publish
Artisan 指令,語言包將會發佈到指定的目錄中。
視圖
想要在 Laravel 中註冊你的擴充包的 視圖, 需要告知 Laravel 視圖檔案的位置。你可以使用服務提供者的 loadViewsFrom
方法來實作。 loadViewsFrom
方法允許接收兩個參數:視圖範本路徑和擴充包名。例如,如果你的擴充包名為courier
,你需要將下面的內容加入到服務提供者的boot
方法:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); }
擴充功能檢視約定使用package::view
語法進行引用。因此,一旦視圖路徑在服務提供者中註冊成功,你可以使用下面的方式來載入courier
擴充包中的admin
視圖:
Route::get('admin', function () { return view('courier::admin'); });
#重寫擴充包視圖
當你使用loadViewsFrom
方法時,Laravel 實際上會在兩個位置註冊視圖:應用程式的resources/views/vendor
目錄和你的自訂目錄。所以,也以 courier
擴充包為例,Laravel 首先會檢查開發人員是否在 resources/views/vendor/courier
中提供了一個自訂版本的視圖。然後,如果視圖尚未被定義,Laravel 將會搜尋在 loadViewsFrom
中定義的視圖目錄。這種方法可以讓使用者很簡單的自訂或重寫擴充包的視圖。
發佈視圖
如果你希望將你的視圖發佈到應用程式的resources/views/vendor
目錄中,可以使用服務提供者的publishes
方法。 publishes
方法接收一個包含視圖路徑和對應發佈位置的陣列:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier'); $this->publishes([ __DIR__.'/path/to/views' => resource_path('views/vendor/courier'), ]); }
現在,當擴充包的使用者執行Laravel 的vendor:publish
Artisan 指令,視圖將會被發佈到自訂的目錄中。
命令
#想要在Laravel 中註冊擴充包的Artisan 指令,需要使用commands
方法。此方法接收一個命令類別的陣列。一旦這些命令註冊成功,可以使用Artisan 命令列執行他們:
/** * 引导应用服务。 * * @return void */ public function boot(){ if ($this->app->runningInConsole()) { $this->commands([ FooCommand::class, BarCommand::class, ]); } }
#公共資源檔案
##你的擴充包中可能存在JavaScript、CSS 和圖片之類的資源檔案。想要發佈這些資源檔案到應用程式的public 目錄,可以使用服務提供者的
publishes 方法。在下面的範例中,我們也可以新增一個
public 資源分類標籤,可用於相關發布資源的分類:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->publishes([ __DIR__.'/path/to/assets' => public_path('vendor/courier'), ], 'public'); }現在,當擴充包的使用者執行
vendor: publish 指令,你的資源檔案將會被複製到指定的目錄中。由於每次更新擴充包時通常都需要覆寫資源文件,因此需要使用
--force 標籤:
php artisan vendor:publish --tag=public --force
發布群組檔案
你可能想要分別打包發布擴充包資源檔案或資源。舉個例子,你想讓使用者單獨發布擴充包中的設定文件,而不是被強制發布擴充包中的所有資源檔案。你可以透過呼叫擴充包服務提供者中的 publishes
方法來為不同檔案打上「標籤」。例如,讓我們使用擴充服務提供者中的boot
方法來定義兩個發布群組:
/** * 在注册后启动服务。 * * @return void */ public function boot(){ $this->publishes([ __DIR__.'/../config/package.php' => config_path('package.php') ], 'config'); $this->publishes([ __DIR__.'/../database/migrations/' => database_path('migrations') ], 'migrations'); }
現在你的使用者就可以透過執行vendor:publish
指令,根據定義的標籤來發布不同的群組檔案:
php artisan vendor:publish --tag=config