鍍金池/ 教程/ PHP/ 包開發(fā)
門面
Laravel Homestead
安裝及配置
測試
HTTP 中間件
加密
升級指南
幫助函數(shù)
應用目錄結(jié)構(gòu)
集合
新手入門指南-簡單任務管理系統(tǒng)
任務調(diào)度
查詢構(gòu)建器
視圖
驗證
Laravel Cashier(訂購&支付&發(fā)票)
本地化
隊列
調(diào)整器
分頁
文件系統(tǒng)/云存儲
貢獻代碼
哈希
HTTP 控制器
緩存
遷移
HTTP 請求
Laravel Elixir
發(fā)行版本說明
Envoy 任務運行器(SSH任務)
序列化
Session
起步
帶用戶功能的任務管理系統(tǒng)
起步
用戶授權(quán)
郵件
事件
填充數(shù)據(jù)
HTTP 路由
服務提供者
Blade 模板引擎
包開發(fā)
用戶認證
Artisan 控制臺
HTTP 響應
集合
服務容器
關(guān)聯(lián)關(guān)系
一次請求的生命周期
契約
Redis
錯誤&日志

包開發(fā)

1、簡介

包是添加功能到 Laravel 的主要方式。包可以提供任何功能,小到處理日期如 Carbon,大到整個 BDD 測試框架如 Behat。

當然,有很多不同類型的包。有些包是獨立的,意味著可以在任何框架中使用,而不僅是 Laravel。比如 Carbon 和 Behat 都是獨立的包。所有這些包都可以通過在 composer.json 文件中請求以便被 Laravel 使用。

另一方面,其它包只能特定和 Laravel 一起使用,這些包可能有路由,控制器、視圖和配置用于加強 Laravel 應用的功能,本章主要討論只能在 Laravel 中使用的包。

2、服務提供者

服務提供者是包和 Laravel 之間的連接點。服務提供者負責綁定對象到 Laravel 的服務容器并告知 Laravel 從哪里加載包資源如視圖、配置和本地化文件。

服務提供者繼承自 Illuminate\Support\ServiceProvider 類并包含兩個方法:registerbootServiceProvider 基類位于 Composer 包 illuminate/support。

要了解更多關(guān)于服務提供者的內(nèi)容,查看其文檔。

3、路由

要定義包的路由,只需要在包服務提供者中的 boot 方法中引入路由文件。在路由文件中,可以使用 Route 門面注冊路由,和 Laravel 應用中注冊路由一樣:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot(){
    if (! $this->app->routesAreCached()) {
        require __DIR__.'/../../routes.php';
    }
}

4、資源

4.1 視圖

要在 Laravel 中注冊包視圖,需要告訴 Laravel 視圖在哪,可以使用服務提供者的 loadViewsFrom 方法來實現(xiàn)。loadViewsFrom 方法接收兩個參數(shù):視圖模板的路徑和包名稱。例如,如果你的包名稱是“courier”,添加如下代碼到服務提供者的 boot 方法:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot(){
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}

包視圖通過使用類似的 package::view 語法來引用。所以,你可以通過如下方式加載courier包上的 admin 視圖:

Route::get('admin', function () {
    return view('courier::admin');
});

4.1.1 覆蓋包視圖

當你使用 loadViewsFrom 方法的時候,Laravel 實際上為視圖注冊了兩個存放位置:一個是 resources/views/vendor 目錄,另一個是你指定的目錄。所以,以 courier 為例:當請求一個包視圖時,Laravel 首先檢查開發(fā)者是否在 resources/views/vendor/courier 提供了自定義版本的視圖,如果該視圖不存在,Laravel 才會搜索你調(diào)用 loadViewsFrom方法時指定的目錄。這種機制使得終端用戶可以輕松地自定義/覆蓋包視圖。

4.1.2 發(fā)布視圖

如果你想要視圖能夠發(fā)布到應用的 resources/views/vendor 目錄,可以使用服務提供者的publishes方法。該方法接收包視圖路徑及其相應的發(fā)布路徑數(shù)組作為參數(shù):

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot(){
    $this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');

    $this->publishes([
        __DIR__.'/path/to/views' => base_path('resources/views/vendor/courier'),
    ]);
}

現(xiàn)在,當包用戶執(zhí)行 Laravel 的 Artisan 命令 vendor:publish時,你的視圖包將會被拷貝到指定路徑。

4.2 翻譯

如果你的包包含翻譯文件,你可以使用 loadTranslationsFrom 方法告訴 Laravel 如何加載它們,例如,如果你的包命名為“courier”,你應該添加如下代碼到服務提供者的 boot 方法:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot(){
    $this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}

包翻譯使用形如 package::file.line 的語法進行引用。所以,你可以使用如下方式從messages 文件中加載 courier 包的 welcome 行:

echo trans('courier::messages.welcome');

4.3 配置

通常,你想要發(fā)布包配置文件到應用根目錄下的 config 目錄,這將允許包用戶輕松覆蓋默認配置選項,要發(fā)布一個配置文件,只需在服務提供者的 boot 方法中使用 publishes方法即可:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot(){
    $this->publishes([
        __DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
    ])
}

現(xiàn)在,當包用戶執(zhí)行 Laravel 的 Artisan 命令 vendor:publish 時,你的文件將會被拷貝到指定位置,當然,配置被發(fā)布后,可以通過和其它配置選項一樣的方式進行訪問:

$value = config('courier.option');

4.3.1 默認包配置

你還可以選擇將自己的包配置文件合并到應用的拷貝版本,這允許用戶只引入他們在應用配置文件中實際想要覆蓋的配置選項。要合并兩個配置,在服務提供者的 register 方法中使用 mergeConfigFrom 方法即可:

/**
 * Register bindings in the container.
 *
 * @return void
 */
public function register(){
    $this->mergeConfigFrom(
        __DIR__.'/path/to/config/courier.php', 'courier'
    );
}

5、公共前端資源

你的包可能包含 JavaScript、CSS 和圖片,要發(fā)布這些前端資源到應用根目錄下的 public 目錄,使用服務提供者的 publishes 方法。在本例中,我們添加一個前端資源組標簽 public,用于發(fā)布相關(guān)的前端資源組:

/**
 * Perform post-registration booting of services.
 *
 * @return void
 */
public function boot(){
    $this->publishes([
        __DIR__.'/path/to/assets' => public_path('vendor/courier'),
    ], 'public');
}

現(xiàn)在,當包用戶執(zhí)行 vendor:publish 命令時,前端資源將會被拷貝到指定位置,由于你需要在每次包更新時重寫前端資源,可以使用--force 標識:

php artisan vendor:publish --tag=public --force

如果你想要確保前端資源已經(jīng)更新到最新版本,可添加該命令到composer.json文件的post-update-cmd列表。

6、發(fā)布文件組

你可能想要發(fā)分開布包前端資源組和資源,例如,你可能想要用戶發(fā)布包配置的同時不發(fā)布包前端資源,可以通過在調(diào)用時給它們打上“標簽”來實現(xiàn)分離。下面我們在包服務提供者的 boot方法中定義兩個公共組:

/**
 * Perform post-registration booting of services.
 *
 * @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');
}

現(xiàn)在用戶可以在使用 Artisan 命令 vendor:publish時通過引用標簽名來分開發(fā)布這兩個組:

php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider" --tag="config"