美文网首页
使用php composer时, 如何优雅修改vendor中第三

使用php composer时, 如何优雅修改vendor中第三

作者: PeterQ1998 | 来源:发表于2018-10-30 10:05 被阅读0次

    有些时候在某一个项目中, 使用了一个第三方包, 但是会发现某一些地方不符合项目需求. 或者需要在包代码里注入一段自己的逻辑. 我们可以选择自己维护一个分支, 或者干脆改vendor文件夹, 并它他加入代码管理. 但对于要修改少量代码时, 这样做貌似不太'优雅'

    请先查阅函数spl_autoload_register文档

    其实composer也是利用这个函数来实现自动加载的.

    php代码执行时, 如果遇到代码里依赖了一个类, 而这个类在当前进程中不存在时, php 会按照加载器队列顺序调用通过spl_autoload_register函数注册过的类加载器. 直到某个加载器执行完后, 这个被依赖的类被加载进当前进程空间, 或者所有加载器都执行完这个类仍不存在, 并抛出类不存在的异常.

    所以我们也可以利用spl_autoload_register函数, 注册一个加载器, 并使其在队列里位于composer加载器之前. 当php需要加载我们要改动的第三方代码包里的类时, 我们加载自己改好的php文件, 而不是vendor包里的php文件. 这样就达到了覆盖的目的.

    煮个栗子:
    我写了一个自动抢饿了么最大外卖红包swoole程序. 大概流程就是, 利用hanson/vbot 包监听微信群里发送的红包链接, 并把链接推送到红包队列, 然后有个进程使用小号轮训饿了么接口, 等红包的下一个就是最大时, 用大号去领, 就领到了, 但是有个问题:
    vbot 包有个message handler类, 里面有个listen方法. 这个方法里会调用微信网页版的接口. 当收到微信消息时会调用用户的消息处理器, 并且此方法是while(true)循环.所以一旦执行listen方法, 整个进程是会阻塞在这个方法里的, 就算用swoole的异步定时器也无力回天. 但是我又有个需求, 就是异步发送消息: 当某个红包的最大红包来临时, 可以配置不自动抢, 而是把链接转发到一个'内部群', 由群员抢最大红包. 所以我只好修改一下这个类了, 把while(true)循环改成swoole的定时器

    左边是修改后的
    项目目录结构
    项目目录结构
    注意到, overwrite文件夹, 就是我用来放覆盖第三方代码php文件的目录
    里面的autoload.php文件内容:
    
    <?php
    
    spl_autoload_register(function ($cls) {
        $map = [
            'Hanson\Vbot\Core\MessageHandler' => __DIR__ . '/MessageHandler.php',
            'Hanson\Vbot\Core\Server' => __DIR__  . '/Server.php',
        ];
    
        if (isset($map[$cls])) {
            echo $cls . ' loaded' . PHP_EOL;
            include $map[$cls];
            return true;
        }
    // 注意需要设置prepend参数为true
    }, true, true);
    
    

    项目的composer.json加载了这autoload.php:

    {
      "require": {
        "hanson/vbot": "^2.0",
        "symfony/debug": "^4.1"
      },
      "autoload": {
        "psr-4": {
          "App\\": "src/"
        },
        "files": ["src/overwrite/autoload.php"]
      }
    }
    
    

    请自行体会

    相关文章

      网友评论

          本文标题:使用php composer时, 如何优雅修改vendor中第三

          本文链接:https://www.haomeiwen.com/subject/mpuwtqtx.html