原文章寫在本身的博客: 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 內容以下:php
{ "name": "aex/packagetest-for-laravel", "authors": [ { "name": "aex", "email": "email@email.com" } ], "require": {} }
你也能夠根據 composer.json 的規則添加相應的其它配置
目前目錄結構是這樣的:
雖然你知道代碼都在 src目錄下,可是 laravel 不知道,因此你要告訴他,即配置 laravel 根目錄的 composer.json
修改 autoload 改成相似以下:html
"autoload": { "classmap": [ "database" ], "psr-4": { "App\\": "app/", "Aex\\Packagetest\\": "packages/aex/packagetest/src/" } },
而後建立服務:使用 artisan 命令java
php artisan make:provider PackagetestServiceProvider
執行完成,laravel 在 app/Providers下會生成 PackagetestServiceProvider.php 而後你把他剪切到 你的 src目錄:packages/aex/packagetest/src
同時修改代碼的命名空間爲你剛剛定義的:namespace Aex\Packagetest; 順便把註冊服務等都寫完吧,完成代碼以下:laravel
1 <?php 2 namespace Aex\Packagetest; 3 use Illuminate\Support\ServiceProvider; 4 class PackagetestServiceProvider extends ServiceProvider 5 { 6 /** 7 * 服務提供者加是否延遲加載. 8 * 9 * @var bool 10 */ 11 protected $defer = true; // 延遲加載服務 12 /** 13 * Bootstrap the application services. 14 * 15 * @return void 16 */ 17 public function boot() 18 { 19 $this->loadViewsFrom(__DIR__ . '/views', 'Packagetest'); // 視圖目錄指定 20 $this->publishes([ 21 __DIR__.'/views' => base_path('resources/views/vendor/packagetest'), // 發佈視圖目錄到resources 下 22 __DIR__.'/config/packagetest.php' => config_path('packagetest.php'), // 發佈配置文件到 laravel 的config 下 23 ]); 24 } 25 /** 26 * Register the application services. 27 * 28 * @return void 29 */ 30 public function register() 31 { 32 // 單例綁定服務 33 $this->app->singleton('packagetest', function ($app) { 34 return new Packagetest($app['session'], $app['config']); 35 }); 36 } 37 /** 38 * Get the services provided by the provider. 39 * 40 * @return array 41 */ 42 public function provides() 43 { 44 // 由於延遲加載 因此要定義 provides 函數 具體參考laravel 文檔 45 return ['packagetest']; 46 } 47 }
自問自答: git
1.爲何建立的服務要放到src 下? – 你要開發擴展包,放到laravel下面就不算擴展包了,你的包之後要給別人用,別人會統一安裝到vendor下的,總不能單獨把 service 文件也打包上傳吧。
同理服務定義了 publish , 配置和視圖不一樣系統需求確定不同,爲了讓人家修改,因此咱們提供發佈到laravel 原始視圖和配置路徑的方法,總不能讓人家下載了你的到 到 vendor下修改吧。
2.那麼 composer.json 裏的命名空間爲何修改的是laravel 根目錄的? – 啪!多嘴!哦,不對,啪啪啪啪!!! 問的好!,這個咱們還沒講完嘛,後面會給他提出來的,咱們須要先跑通咱們的代碼,再完善成可發佈的
接下來註冊咱們的服務到 config/app.php (你使用別人家的包都須要這步的)
添加一行 Aex\Packagetest\PackagetestServiceProvider::class
下一步添加配置文件:
在 src 目錄下添加 config 目錄而後添加文件 packagetest.php 內容以下:github
<?php return [ 'options' => [] // 只是爲了演示 ];
下一步建立咱們的服務真正邏輯實現的代碼: 在src目錄下建立文件 Packagetest.php 內容以下:
1 <?php 2 namespace Aex\Packagetest; 3 use Illuminate\Session\SessionManager; 4 use Illuminate\Config\Repository; 5 class Packagetest 6 { 7 /** 8 * @var SessionManager 9 */ 10 protected $session; 11 /** 12 * @var Repository 13 */ 14 protected $config; 15 /** 16 * Packagetest constructor. 17 * @param SessionManager $session 18 * @param Repository $config 19 */ 20 public function __construct(SessionManager $session, Repository $config) 21 { 22 $this->session = $session; 23 $this->config = $config; 24 } 25 /** 26 * @param string $msg 27 * @return string 28 */ 29 public function test_rtn($msg = ''){ 30 $config_arr = $this->config->get('packagetest.options'); 31 return $msg.' <strong>from your custom develop package!</strong>>'; 32 } 33 }
下一步建立視圖文件:在src目錄下添加views目錄而後添加 packagetest.blade.phpjson
@extends('layouts.app') @section('content') <h1>Packagetest Message</h1> {{$msg}} @endsection
下一步建立門面(Facades): 在src目錄下添加 Facades目錄而後添加 Packagetest.php數組
1 <?php 2 namespace Aex\Packagetest\Facades; 3 use Illuminate\Support\Facades\Facade; 4 class Packagetest extends Facade 5 { 6 protected static function getFacadeAccessor() 7 { 8 return 'packagetest'; 9 } 10 }
而後命令行執行 :
composer dump-autoload
這樣就可以使用命名空間 Aex\Packagetest 了,上面在 config/app.php 下添加的服務那行就真正生效了。(若是不執行 dump-autoload 運行程序會報錯,說找不到類)
既然咱們定義了門面 那麼咱們就能夠爲這個服務添加別名了。在 config/app.php 的 aliases 數組添加一行:markdown
'Packagetest' => Aex\Packagetest\Facades\Packagetest::class
如今咱們的目錄結構相似:
至此代碼其實就已經跑通了,可是尚未徹底完成。咱們先測試下試試,隨便找個 controller 固然 route要定義好:例如:TestController.phpsession
1 <?php 2 namespace App\Http\Controllers; 3 use Illuminate\Http\Request; 4 use Packagetest; 5 class TestController extends Controller 6 { 7 public function test(Request $request){ 8 $a = Packagetest::test_rtn('Aex'); 9 return view('Packagetest::packagetest',['msg'=>$a]); 10 } 11 }
而後根據路由訪問就能夠看到效果啦。爲何說沒有徹底完成呢?由於 視圖文件和 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 結合的部分。