插件开发 - 实战篇

比如我们采集回来的内容是这样的:

  1. 这是内容段落一。
  2. <a href="/xxx/a">这是链接1</a>
  3. <img src="/image/1.jpg" />
  4. 这是内容段落二。
  5. <a href="/xxx/b">这是链接2</a>
  6. <img src="/image/2.jpg" />

采集到的内容中的链接和图片地址都是不全的,所以必须要补全才可以,也就是下面效果:

  1. 这是内容段落一。
  2. <a href="http://a.com/xxx/a">这是链接1</a>
  3. <img src="http://a.com/image/1.jpg" />
  4. 这是内容段落二。
  5. <a href="http://a.com/xxx/b">这是链接2</a>
  6. <img src="http://a.com/image/2.jpg" />

这是一个非常常见的需求,接下来我们开发一款插件来自动实现链接地址的补全。

最终插件目录结构如下:

  1. QueryList-AbsoluteUrl
  2. ├── AbsoluteUrl.php
  3. ├── README.md
  4. └── composer.json

最终效果参考:https://github.com/jae-jae/QueryList-AbsoluteUrl


第一步:创建Composer包,安装依赖

命令行:

  1. # 创建一个空文件夹
  2. $ mkdir QueryList-AbsoluteUrl
  3. # 进入文件夹
  4. $ cd QueryList-AbsoluteUrl
  5. # 安装QueryList作为开发依赖
  6. $ composer require jaeger/querylist --dev


相对链接转绝对链接这个功能没必要我们手动实现,有现成的轮子可以直接用,直接引用别人写好的包即可,在Github上找到了一个满足要求的项目:https://github.com/monkeysuffrage/phpuri

  1. # 安装第三方相对链接转绝对链接的包
  2. $ composer require pguardiario/phpuri


第二步:创建插件,代码逻辑开发

安装好依赖之后,就可以创建插件的主文件了,由于这个插件比较简单,所以就一个PHP文件:

  1. $ touch AbsoluteUrl.php

插件主文件的初始内容如下:

  1. <?php
  2. use QL\Contracts\PluginContract;
  3. use QL\QueryList;
  4. class AbsoluteUrl implements PluginContract
  5. {
  6. public static function install(QueryList $queryList, ...$opt)
  7. {
  8. }
  9. }

我们需要为插件创建一个命名空间并让Composer自动加载这个文件,接下来修改composer.json文件,加入autoload选项,这个文件是使用composer安装依赖包时自动生成的:

  1. {
  2. "require": {
  3. "pguardiario/phpuri": "^1.0"
  4. },
  5. "require-dev": {
  6. "jaeger/querylist": "^4.0"
  7. },
  8. "autoload": {
  9. "psr-4": {
  10. "QL\\Ext\\": ""
  11. }
  12. }
  13. }

我将命名空间QL\Ext映射到了当前插件项目根目录,接下来修改插件主文件AbsoluteUrl.php,加入命名空间名,并加入一个convertAll()的链接转换函数:

  1. <?php
  2. namespace QL\Ext;
  3. use QL\Contracts\PluginContract;
  4. use QL\QueryList;
  5. use phpUri;
  6. class AbsoluteUrl implements PluginContract
  7. {
  8. public static function install(QueryList $queryList, ...$opt)
  9. {
  10. }
  11. public static function convertAll($ql,$url)
  12. {
  13. $parser = phpUri::parse($url);
  14. $ql->find('a')->map(function($item) use ($parser,$ql){
  15. $relativeUrl = $item->attr('href');
  16. $absoluteUrl = $parser->join($relativeUrl);
  17. $item->attr('href',$absoluteUrl);
  18. });
  19. $ql->find('img')->map(function($item) use ($parser,$ql){
  20. $relativeUrl = $item->attr('src');
  21. $absoluteUrl = $parser->join($relativeUrl);
  22. $item->attr('src',$absoluteUrl);
  23. });
  24. $ql->setHtml($ql->find('')->html());
  25. return $ql;
  26. }
  27. }

phpUri是我们之前引入的链接转换的包,我们在convertAll()中遍历了QueryList采集到的内容中的所有<a>标签和<img>标签,并使用phpUri依次转换了相对链接为绝对链接。

最后只需要在install()方法中用bind()方法把convertAll()方法绑定到QueryList对象即可:

  1. public static function install(QueryList $queryList, ...$opt)
  2. {
  3. $queryList->bind('absoluteUrl',function ($url){
  4. return AbsoluteUrl::convertAll($this,$url);
  5. });
  6. }

一个QueryList插件就这样大功告成了。

{warning} 修改composer.json文件后,要执行一下composer update命令来更新一下自动加载文件,否则修改不会生效。



第三步:测试插件

可以直接在插件项目目录新建一个test.php文件来测试一下插件:

  1. <?php
  2. require 'vendor/autoload.php';
  3. use QL\QueryList;
  4. use QL\Ext\AbsoluteUrl;
  5. $ql = QueryList::getInstance();
  6. $ql->use(AbsoluteUrl::class);
  7. $data = $ql->get('https://toutiao.io/')
  8. ->absoluteUrl('https://toutiao.io/')
  9. ->find('a')->attrs('href');
  10. print_r($data);

在命令行下运行php test.php看输出结果是否符合预期,如果发现问题,可以继续修改插件,然后继续测试,直到完全正常工作为止。


第四步:发布插件到Packagist

发布插件到Packagist的目的是为了方便其它人可以方便的通过Composer安装并使用你的插件,你需要做以下3步:

  1. 1. 完善composer.json文件信息,加入包名和你的个人信息
  2. 2. 将代码推送到Github仓库
  3. 3. 提交Github仓库到Packagist

相关教程网上很多,这里就不再赘述了。