1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > vendor php 使用php composer时 如何优雅修改vendor中第三方代码

vendor php 使用php composer时 如何优雅修改vendor中第三方代码

时间:2021-11-01 00:13:05

相关推荐

vendor php 使用php composer时  如何优雅修改vendor中第三方代码

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

其实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文件内容:

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"]

}

}

请自行体会

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。