原文章写在本身的博客: 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 结合的部分。