如何优雅修改composer第三方类库
目录
有些时候在某一个项目中, 使用了一个第三方包, 但是会发现某一些地方不符合项目需求. 或者需要在包代码里注入一段自己的逻辑. 我们可以选择自己维护一个分支, 或者干脆改vendor文件夹, 并它他加入代码管理. 但对于要修改少量代码时, 这样做貌似不太’优雅’
spl_autoload_register
请先查阅函数spl_autoload_register文档
composer autoload自动加载器原理
其实composer也是利用这个函数来实现自动加载的.
php代码执行时, 如果遇到代码里依赖了一个类, 而这个类在当前进程中不存在时, php 会按照加载器队列顺序调用通过spl_autoload_register函数注册过的类加载器. 直到某个加载器执行完后, 这个被依赖的类被加载进当前进程空间, 或者所有加载器都执行完这个类仍不存在, 并抛出类不存在的异常.
覆盖composer第三方类库
所以我们也可以利用spl_autoload_register函数, 注册一个加载器, 并使其在队列里位于composer加载器之前. 当php需要加载我们要改动的第三方代码包里的类时, 我们加载自己改好的php文件, 而不是vendor包里的php文件. 这样就达到了覆盖的目的.
范例
项目中使用到html-to-markdown类库:
composer require league/html-to-markdown
但由于其中的图片image的转换处理,其中//协议及懒加载的图片,不能被正确转换,但官方类库又没有更新,我们又急着使用,稍微看了html-to-markdown的源码,我们清楚原理后,需要完善image的转换处理,我们先看下html-to-markdown类库的结构:
查看文件树结构:
tree ./src /f /a
vendor\league\html-to-markdown\src
| Configuration.php
| ConfigurationAwareInterface.php
| Element.php
| ElementInterface.php
| Environment.php
| HtmlConverter.php
| HtmlConverterInterface.php
|
\---Converter
BlockquoteConverter.php
CodeConverter.php
CommentConverter.php
ConverterInterface.php
DefaultConverter.php
DivConverter.php
EmphasisConverter.php
HardBreakConverter.php
HeaderConverter.php
HorizontalRuleConverter.php
ImageConverter.php
LinkConverter.php
ListBlockConverter.php
ListItemConverter.php
ParagraphConverter.php
PreformattedConverter.php
TextConverter.php
从上面代码文件结构,我们知道只需要重写ImageConvert.php类文件即可,在extend扩展目录准备html-to-markdown-overwrite:
extend\html-to-markdown-overwrite
autoload.php
ImageConverter.php
注意到里面的autoload.php文件内容:
<?php
/**
* 重写html-to-markdown类文件
* 在composer.json中配置自定义files,并重新生成:composer dump-autoload
"autoload": {
"psr-4": {
"app\\": "application"
},
"files":["extend/html-to-markdown-overwrite/autoload.php"]
},
*/
spl_autoload_register(function ($class) {
$map = [
'League\HTMLToMarkdown\Converter\ImageConverter' => __DIR__ . '/ImageConverter.php',
];
if (isset($map[$class])) {
// debug_log($class . ' loaded' . PHP_EOL);
include $map[$class];
return true;
}
// 注意需要设置prepend参数为true
}, true, true);
项目composer.php加载该自定义autoload.php 加载器:
"autoload": {
"psr-4": {
"app\\": "application"
},
"files":["extend/html-to-markdown-overwrite/autoload.php"]
},
修改了composer.php的autoload的配置后,我们需要重新生成整个项目最终autoload.php,在项目路径执行命令:
composer dump-autoload
而我们覆盖的ImageConverter.php 从原类库复制而来,做逻辑上的微调整。
@tsingchan 2019