• laravel composer 扩展包开发(超详细)


    laravel composer 扩展包开发(超详细)

     版权声明:转载请注明出处:http://blog.csdn.net/m0sh1 http://blog.share345.com/ https://blog.csdn.net/m0sh1/article/details/79257935

    原文章写在自己的博客: 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@email.com"
            }
        ],
        "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 AexPackagetest; 顺便把注册服务等都写完吧,完成代码如下:

     1 <?php
     2 namespace AexPackagetest;
     3 use IlluminateSupportServiceProvider;
     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 }

    自问自答: 

    1.为什么创建的服务要放到src 下? – 你要开发扩展包,放到laravel下面就不算扩展包了,你的包以后要给别人用,别人会统一安装到vendor下的,总不能单独把 service 文件也打包上传吧。 
    同理服务定义了 publish , 配置和视图不同系统需求肯定不一样,为了让人家修改,所以我们提供发布到laravel 原始视图和配置路径的方法,总不能让人家下载了你的到 到 vendor下修改吧。 
    2.那么 composer.json 里的命名空间为什么修改的是laravel 根目录的? – 啪!多嘴!哦,不对,啪啪啪啪!!! 问的好!,这个我们还没讲完嘛,后面会给他提出来的,我们需要先跑通我们的代码,再完善成可发布的 
    接下来注册我们的服务到 config/app.php (你使用别人家的包都需要这步的) 
    添加一行 AexPackagetestPackagetestServiceProvider::class 
    下一步添加配置文件: 
    在 src 目录下添加 config 目录然后添加文件 packagetest.php 内容如下:

    <?php
    return [
        'options' => [] // 只是为了演示
    ];
    
    下一步创建我们的服务真正逻辑实现的代码: 在src目录下创建文件 Packagetest.php 内容如下:
     1 <?php
     2 namespace AexPackagetest;
     3 use IlluminateSessionSessionManager;
     4 use IlluminateConfigRepository;
     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.php

    @extends('layouts.app')
    @section('content')
        <h1>Packagetest Message</h1>
        {{$msg}}
    @endsection

    下一步创建门面(Facades): 在src目录下添加 Facades目录然后添加 Packagetest.php

     1 <?php
     2 namespace AexPackagetestFacades;
     3 use IlluminateSupportFacadesFacade;
     4 class Packagetest extends Facade
     5 {
     6     protected static function getFacadeAccessor()
     7     {
     8         return 'packagetest';
     9     }
    10 }

    然后命令行执行 :
     composer dump-autoload 

    这样就能够使用命名空间 AexPackagetest 了,上面在 config/app.php 下添加的服务那行就真正生效了。(如果不执行 dump-autoload 运行程序会报错,说找不到类) 
    既然我们定义了门面 那么我们就可以为这个服务添加别名了。在 config/app.php 的 aliases 数组添加一行:

     'Packagetest' => AexPackagetestFacadesPackagetest::class 

    现在我们的目录结构类似: 
    这里写图片描述 
    至此代码其实就已经跑通了,但是还没有完全完成。我们先测试下试试,随便找个 controller 当然 route要定义好:例如:TestController.php

     1 <?php
     2 namespace AppHttpControllers;
     3 use IlluminateHttpRequest;
     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="AexPackagetestPackagetestServiceProvider" // --provider 参数指定了要发布的服务 你也可以省略来发布所有 

    发布后你就会在 laravel 本身的 config目录 和 views/vendor/packagetest 下看到你的文件了,也就可以按照需求随意修改了。 
    最后我们说 修改的laravel 的composer.json ,我们要发布我们的包,让所有人都能使用 composer 安装,那么执行如下步骤 
    去掉 添加的 那行 “AexPackagetest”: “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 添加 
    AexPackagetestPackagetestServiceProvider::class 
    和别名的配置: 
    ‘Packagetest’ => AexPackagetestFacadesPackagetest::class 
    执行 composer dump-autoload 
    发布资源文件: php artisan vendor:publish –provider=”AexPackagetestPackagetestServiceProvider” 
    测试通过 大功告成! 
    额外的: 
    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 结合的部分。

  • 相关阅读:
    “混乱有序”一首关于概率论的诗
    关于“混乱有序”理论的讨论 2020-09-20
    关于“混乱有序”理论的讨论 2020-08-30
    【Java】(有步骤!)模逆、模幂、十进制转十六进制、十六进制转十进制、xTime算法、LFSR画状态图、椭圆曲线加法、椭圆曲线乘法、获得椭圆曲线上的点
    算法导论第一课
    经典力学:第一课
    计算机科学及编程导论:第一课
    微积分重点:第十六至十八课
    微积分重点:第十四,十五课
    微积分重点:第十课至十三课
  • 原文地址:https://www.cnblogs.com/guiyishanren/p/10985817.html
Copyright © 2020-2023  润新知