包開發(fā)
包是在 laravel 中添加功能的主要方式撵溃。包可以是任何形式息罗,比如處理日期的 Carbon 或者是整個 BDD 測試框架 Behat掂咒。
當(dāng)然,包是有不同類型的迈喉。有些包是獨立的包绍刮。意味著它可以在任何框架中使用,而不僅僅是在 laravel 中挨摸。Carbon 和 Behat 就是獨立的包孩革。這些包你可以簡單的通過在 composer.json
文件中進行引入安裝使用。
而在另一方面得运,有些包是專門用于 laravel 使用的膝蜈。這些包可能擁有路由,控制器熔掺,視圖和配置文件饱搏,他們配合起來旨在提高 laravel 的功能。這篇指南就是來告訴你如何開發(fā)增強 laravel 功能的包置逻。
服務(wù)提供者
服務(wù)提供者是 laravel 和包的連接點推沸。服務(wù)提供者主要負(fù)責(zé)包內(nèi)容在服務(wù)容器中的綁定以及應(yīng)用應(yīng)該如何加載資源文件如視圖,配置文件和語言文件券坞。
一個服務(wù)提供者應(yīng)該繼承 Illuminate\Support\ServiceProvider
類并且包含兩個方法: register
和 boot
鬓催。基類 ServiceProvider
類位于 Composer 包的 illuminate/support
中报慕。你應(yīng)該在你的包中添加這個依賴深浮。
路由
你可以在你的服務(wù)提供者的 boot
方法中簡單的 require
路由文件來定義包的路由。在你的路由文件中眠冈,你可以使用 Route
假面來注冊路由飞苇,其方式就如普通的 laravel 應(yīng)用一樣:
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
if (! $this->app->routesAreCached(){
requir __DIR__.'/../../routes.php';
})
}
資源
視圖
你需要告訴 laravel 視圖的位置才能使 laravel 加載包中的視圖。你可以通過服務(wù)提供者的 loadViewsFrom
方法蜗顽。loadViewsFrom
方法接受兩個參數(shù):視圖的路徑和包的名稱布卡。比如,如果你的包名稱是“courier”雇盖,你應(yīng)該像下面一樣在 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');
});
覆蓋包視圖
當(dāng)你使用 loadViewsFrom
方法來加載視圖時崔挖,laravel 實際上是注冊了兩個視圖位置:一個是應(yīng)用的 resources/views/vendor
目錄贸街,另一個是你指定的目錄庵寞。所以,我們還使用上面的例子:當(dāng)請求引入包視圖時薛匪,laravel 會首先檢查 resources/views/vendor/courier
目錄中是否有相應(yīng)的視圖捐川,然后,如果沒有才會通過 loadViewFrom
方法來加載指定的目錄下的視圖逸尖。這就引入了一種自定義包視圖的簡便方式古沥。
發(fā)布視圖
如果你希望有一種簡單的方式將包的視圖發(fā)布到 resources/views/vendor
目錄。你可以在服務(wù)提供者中使用 publishes
方法娇跟。publishes
方法接收一個包視圖路徑和其發(fā)布地址路徑所組成的數(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' => resource_path('views/vendor/courier'),
]);
}
現(xiàn)在岩齿,當(dāng)你通過命令行工具使用 vendor:publish
Artisan 命令時,你的包視圖會被復(fù)制到其所指定的位置苞俘。
譯文
如果你的包中包含了翻譯文件盹沈。你可以使用 loadTranslationsFrom
方法來指導(dǎo) 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::filer.line
類似的語法。所以基协,你可以像這樣來加載 courier
包中的 messages
文件的 welcome
鍵:
echo trans('courier::messages.welcome');
發(fā)布譯文
如果你希望發(fā)布包的譯文到應(yīng)用的 resources/lang/vendor
目錄歌亲,你可以使用服務(wù)提供者的 publishes
方法。publishes
方法接收一個包含包路徑和其相應(yīng)的發(fā)布路徑所組成的數(shù)組澜驮。比如陷揪,發(fā)布 courier
包中的譯文:
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
$this->publishes([
__DIR__.'/path/to/translations' => resource_path('lang/vendor/courier')
]);
}
現(xiàn)在,當(dāng)你通過命令行工具使用 vendor:publish
Artisan 命令時杂穷,包中的譯文會自動的發(fā)布到指定的位置悍缠。
配置文件
通常,你希望發(fā)布你的包配置文件到應(yīng)用的 config
目錄耐量。這樣就允許用戶通過簡單的配置來覆蓋默認(rèn)的配置選項飞蚓。你可以使用 publishes
方法來發(fā)布配置文件:
/**
* 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)使用你包的用戶使用 laravel 的 vendor:push
命令時,你的配置文件將會復(fù)制到指定的位置廊蜒。當(dāng)然趴拧,一旦你的配置文件被發(fā)布到 config
目錄,它就可以像訪問其他配置文件一樣被訪問:
$value = config('courier.option');
默認(rèn)的包配置
你也可以選擇合并包的默認(rèn)配置和應(yīng)用復(fù)制的配置山叮。這樣就允許用戶只引入其真實需要變更的配置選項著榴。你可以使用 mergeConfigFrom
方法來在你的服務(wù)提供者的 register
方法中進行合并:
/**
* Register bindingsin the container.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(
__DIR__.'/path/to/config/courier.php', 'courier'
);
}
公共資源文件
你的包文件中可能含有一些資源文件比如 JavaScript,CSS屁倔,圖片脑又。你同樣可以在你的服務(wù)提供者中使用 publishes
方法來發(fā)布這些資源到應(yīng)用的 public
目錄。我們同樣可以添加一個 public
組標(biāo)簽,這樣可以選擇在發(fā)布時只發(fā)布 public
標(biāo)簽組的文件:
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
$this->published([
__DIR__.'/path/to/assets' => public_path('vendor/courier'),
], 'public');
}
現(xiàn)在问麸,使用你的包的用戶在執(zhí)行 vendor:publish
命令時往衷,你的資源文件會被發(fā)布到指定的位置。如果你需要每次發(fā)布資源時覆蓋之前發(fā)布的內(nèi)容口叙,你可以使用 --force
標(biāo)識:
php artisan vendor:publish --tag=public --force
如果你希望你的公共資源總是在發(fā)布時是最新的版本炼绘,你應(yīng)該在你的 composer.json
文件中的 post-update-cmd
列中添加上述命令。
發(fā)布組文件
你可能希望將前端資源和后端資源進行分組分開發(fā)布妄田。比如,你可能希望用戶在發(fā)布配置文件的同時并不重新發(fā)布更新公共資源文件驮捍。你可以通過在使用 publishes
方法時對發(fā)布項打標(biāo)簽的方式來對發(fā)布進行分組:
/**
* 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)在疟呐,你的包用戶可以在發(fā)布文件時通過組標(biāo)簽來分開發(fā)布了:
php artisan vendor:publish --provider="Vendor\Providers\PackageServiceProvider"