laravel composer 擴充套件包開發(超詳細)
原文章寫在自己的部落格: http://blog.share345.com/2018/02/05/laravel-package-development.html
文章適用於laravel 包開發,當然如果你理解著完成一遍,就可以發現他也適用於 composer 擴充套件包開發,不是必須在laravel 下。
首先在 laravel 根目錄建立資料夾 packages 這裡放置我們準備建立的擴充套件包,這個目錄只是暫時存放我們的擴充套件包程式碼,等我們開發完成配置好了,就不需要他了。
當然如果你不需要釋出你的包,以後也可以就使用這個目錄。packages 目錄和 laravel 的 app 目錄同級
然後進入packages 建立目錄 aex 當然這個名字可以隨意起(最好是作者的名之類的),
接著進入 aex 目錄建立目錄 packagetest 這個目錄的名稱最好是你的擴充套件包名稱,有點意義。 我就是為了測試,所以就叫做 packagetest 好了
然後建立目錄 src 這裡就是我們放置程式碼的地方啦。
接著命令列下進入 packages/aex/packagetest 執行 composer init 他會一步步詢問你要填寫的資訊:
執行完成你會在 packagetest 目錄下看到 composer.json 內容和上圖一致。 當然其實你也可以直接複製一個 composer.json 不需要 composer init
我的 composer.json 內容如下:
{
"name": "aex/packagetest-for-laravel",
"authors": [
{
"name": "aex",
"email": "[email protected]"
}
],
"require": {}
}
你也可以根據 composer.json 的規則新增相應的其它配置
目前目錄結構是這樣的:
雖然你知道程式碼都在 src目錄下,但是 laravel 不知道,所以你要告訴他,即配置 laravel 根目錄的 composer.json
修改 autoload 改為類似如下:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Aex\\Packagetest\\": "packages/aex/packagetest/src/"
}
},
然後建立服務:使用 artisan 命令
php artisan make:provider PackagetestServiceProvider
執行完成,laravel 在 app/Providers下會生成 PackagetestServiceProvider.php 然後你把他剪下到 你的 src目錄:packages/aex/packagetest/src
同時修改程式碼的名稱空間為你剛剛定義的:namespace Aex\Packagetest; 順便把註冊服務等都寫完吧,完成程式碼如下:
<?php
namespace Aex\Packagetest;
use Illuminate\Support\ServiceProvider;
class PackagetestServiceProvider extends ServiceProvider
{
/**
* 服務提供者加是否延遲載入.
*
* @var bool
*/
protected $defer = true; // 延遲載入服務
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__ . '/views', 'Packagetest'); // 檢視目錄指定
$this->publishes([
__DIR__.'/views' => base_path('resources/views/vendor/packagetest'), // 釋出檢視目錄到resources 下
__DIR__.'/config/packagetest.php' => config_path('packagetest.php'), // 釋出配置檔案到 laravel 的config 下
]);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
// 單例繫結服務
$this->app->singleton('packagetest', function ($app) {
return new Packagetest($app['session'], $app['config']);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
// 因為延遲載入 所以要定義 provides 函式 具體參考laravel 文件
return ['packagetest'];
}
}
自問自答:
1.為什麼建立的服務要放到src 下? – 你要開發擴充套件包,放到laravel下面就不算擴充套件包了,你的包以後要給別人用,別人會統一安裝到vendor下的,總不能單獨把 service 檔案也打包上傳吧。
同理服務定義了 publish , 配置和檢視不同系統需求肯定不一樣,為了讓人家修改,所以我們提供釋出到laravel 原始檢視和配置路徑的方法,總不能讓人家下載了你的到 到 vendor下修改吧。
2.那麼 composer.json 裡的名稱空間為什麼修改的是laravel 根目錄的? – 啪!多嘴!哦,不對,啪啪啪啪!!! 問的好!,這個我們還沒講完嘛,後面會給他提出來的,我們需要先跑通我們的程式碼,再完善成可釋出的
接下來註冊我們的服務到 config/app.php (你使用別人家的包都需要這步的)
新增一行 Aex\Packagetest\PackagetestServiceProvider::class
下一步新增配置檔案:
在 src 目錄下新增 config 目錄然後新增檔案 packagetest.php 內容如下:
<?php
return [
'options' => [] // 只是為了演示
];
下一步建立我們的服務真正邏輯實現的程式碼: 在src目錄下建立檔案 Packagetest.php 內容如下:
<?php
namespace Aex\Packagetest;
use Illuminate\Session\SessionManager;
use Illuminate\Config\Repository;
class Packagetest
{
/**
* @var SessionManager
*/
protected $session;
/**
* @var Repository
*/
protected $config;
/**
* Packagetest constructor.
* @param SessionManager $session
* @param Repository $config
*/
public function __construct(SessionManager $session, Repository $config)
{
$this->session = $session;
$this->config = $config;
}
/**
* @param string $msg
* @return string
*/
public function test_rtn($msg = ''){
$config_arr = $this->config->get('packagetest.options');
return $msg.' <strong>from your custom develop package!</strong>>';
}
}
下一步建立檢視檔案:在src目錄下新增views目錄然後新增 packagetest.blade.php
@extends('layouts.app')
@section('content')
<h1>Packagetest Message</h1>
{{$msg}}
@endsection
下一步建立門面(Facades): 在src目錄下新增 Facades目錄然後新增 Packagetest.php
<?php
namespace Aex\Packagetest\Facades;
use Illuminate\Support\Facades\Facade;
class Packagetest extends Facade
{
protected static function getFacadeAccessor()
{
return 'packagetest';
}
}
然後命令列執行 :
composer dump-autoload
這樣就能夠使用名稱空間 Aex\Packagetest 了,上面在 config/app.php 下新增的服務那行就真正生效了。(如果不執行 dump-autoload 執行程式會報錯,說找不到類)
既然我們定義了門面 那麼我們就可以為這個服務新增別名了。在 config/app.php 的 aliases 陣列新增一行:
'Packagetest' => Aex\Packagetest\Facades\Packagetest::class
現在我們的目錄結構類似:
至此程式碼其實就已經跑通了,但是還沒有完全完成。我們先測試下試試,隨便找個 controller 當然 route要定義好:例如:TestController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Packagetest;
class TestController extends Controller
{
public function test(Request $request){
$a = Packagetest::test_rtn('Aex');
return view('Packagetest::packagetest',['msg'=>$a]);
}
}
然後根據路由訪問就可以看到效果啦。為什麼說沒有完全完成呢?因為 檢視檔案和 config 配置檔案還在我們的包裡定義,以後釋出出去,包會在 vendor目錄下,這些檔案不應該在vendor下修改
所以命令列執行:
php artisan vendor:publish --provider="Aex\Packagetest\PackagetestServiceProvider"
// --provider 引數指定了要釋出的服務 你也可以省略來發布所有的
釋出後你就會在 laravel 本身的 config目錄 和 views/vendor/packagetest 下看到你的檔案了,也就可以按照需求隨意修改了。
最後我們說 修改的laravel 的composer.json ,我們要釋出我們的包,讓所有人都能使用 composer 安裝,那麼執行如下步驟
去掉 新增的 那行 “Aex\Packagetest\”: “packages/aex/packagetest/src/” 然後 修改 packages/aex/packagetest/composer.json
新增 autoload:
"autoload": {
"psr-4": {
"Aex\\Packagetest\\": "src/"
}
}
這樣包就是一個完整獨立的包了,然後把他提交到你的 GitHub 上。
提交到 github 上的我的目錄結構是:
我的地址是:https://github.com/ALawating-Rex/packagetest-for-laravel 有需要參考的可以參考下。
接著就是把包提交到 packagelist了, 網址: https://packagist.org/ 如果沒有賬戶則註冊一個
然後點選 submit ,填寫專案URL,點選check
成功後點擊 submit 就完成了。 至此你的包就可以像其它人的一樣通過 composer require 安裝了
如上圖,兩個箭頭分別代表了包名稱 和 版本
所以安裝這個包的時候你的 composer.json 在require可以加這樣一行:
"aex/packagetest-for-laravel": "dev-master"
安裝之前我們先把我們之前開發的這個包都刪除吧,就假設是一個別人的 laravel 框架要用我們的包: 刪除 packages 資料夾
刪除 config/packagetest.php
刪除 resources/views/vendor/packagetest
conifg/app.php 裡面刪除新增的服務和別名
controller 裡的改動就保留吧,因為安裝完還是要這麼寫一遍 最後執行 composer dump-autoload
下面安裝這個自定義包吧: composer update aex/packagetest-for-laravel
然後新增服務: 修改 config/app.php 新增
Aex\Packagetest\PackagetestServiceProvider::class
和別名的配置:
‘Packagetest’ => Aex\Packagetest\Facades\Packagetest::class
執行 composer dump-autoload
釋出資原始檔: php artisan vendor:publish –provider=”Aex\Packagetest\PackagetestServiceProvider”
測試通過 大功告成!
額外的:
1.在 packagelist 你的這個包頁面可以看到提示了 Set Up GitHub Service Hook 你可以按照提示辦法安裝,安裝完成後,一旦你的專案有push,這裡就會跟著更新。
2.還是 packagelist 頁面,可以看到目前你只有 dev-master 版本,假設你需要其它的版本 你可以去你的 github 專案新增 tag
git tag 1.0.0 && git push –tags
這樣composer require 就可以指定別的版本了。
3.為了別人能夠更加清晰的使用你的包,完善你的 Readme 吧
4.不是必須laravel 框架,單純的 composer 擴充套件包開發也是按照這個步驟來,只不過需要你摘出 laravel 結合的部分。