服務(wù) ―― 包開(kāi)發(fā)

2018-02-24 15:38 更新

服務(wù) —— 包開(kāi)發(fā)

1、簡(jiǎn)介

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

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

另一方面,其它包只能特定和Laravel一起使用,這些包可能有路由用于加強(qiáng)Laravel應(yīng)用的功能,本章主要討論只能在Laravel中使用的包。

2、服務(wù)提供者

服務(wù)提供者是包和Laravel之間的連接點(diǎn)。服務(wù)提供者負(fù)責(zé)綁定對(duì)象到Laravel的服務(wù)容器并告知Laravel從哪里加載包資源如視圖、配置和本地化文件。

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

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

3、路由

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

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

4、資源

4.1 視圖

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

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

包視圖通過(guò)使用類似的package::view語(yǔ)法來(lái)引用。所以,你可以通過(guò)如下方式加載courier包上的admin視圖:

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

4.1.1 覆蓋包視圖

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

4.1.2?發(fā)布視圖

如果你想要視圖能夠發(fā)布到應(yīng)用的resources/views/vendor目錄,可以使用服務(wù)提供者的publishes方法。該方法接收包視圖路徑及其相應(yīng)的發(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)在,當(dāng)包用戶執(zhí)行Laravel的Artisan命令vendor:publish時(shí),你的視圖包將會(huì)被拷貝到指定路徑。

4.2?翻譯

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

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

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

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

4.3 配置

通常,你想要發(fā)布包配置文件到應(yīng)用根目錄下的config目錄,這將允許包用戶輕松覆蓋默認(rèn)配置選項(xiàng),要發(fā)布一個(gè)配置文件,只需在服務(wù)提供者的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)在,當(dāng)包用戶執(zhí)行Laravel的Artisan命令vendor:publish時(shí),你的文件將會(huì)被拷貝到指定位置,當(dāng)然,配置被發(fā)布后,可以通過(guò)和其它配置選項(xiàng)一樣的方式進(jìn)行訪問(wèn):

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

4.3.1 默認(rèn)包配置

你還可以選擇將自己的包配置文件合并到應(yīng)用的拷貝版本,這允許用戶只引入他們?cè)趹?yīng)用配置文件中實(shí)際想要覆蓋的配置選項(xiàng)。要合并兩個(gè)配置,在服務(wù)提供者的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ā)布這些前端資源到應(yīng)用根目錄下的public目錄,使用服務(wù)提供者的publishes方法。在本例中,我們添加一個(gè)前端資源組標(biāo)簽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)在,當(dāng)包用戶執(zhí)行vendor:publish命令時(shí),前端資源將會(huì)被拷貝到指定位置,由于你需要在每次包更新時(shí)重寫(xiě)前端資源,可以使用--force標(biāo)識(shí):

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

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

6、發(fā)布文件組

你可能想要分開(kāi)發(fā)布包前端資源組和資源,例如,你可能想要用戶發(fā)布包配置的同時(shí)不發(fā)布包前端資源,可以通過(guò)在調(diào)用時(shí)給它們打上“標(biāo)簽”來(lái)實(shí)現(xiàn)分離。下面我們?cè)诎?wù)提供者的boot方法中定義兩個(gè)公共組:

/**
 * 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時(shí)通過(guò)引用標(biāo)簽名來(lái)分開(kāi)發(fā)布這兩個(gè)組:

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

擴(kuò)展閱讀:實(shí)例教程 —— 如何在Laravel 5.1中進(jìn)行自定義包開(kāi)發(fā)

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)