在 LightDB 开发过程中,如何把已修改的文章更新到原有文章上,是个很重要的功能。
Steem 对于大篇幅的文章修改,使用的是 patch 的方式,把增量信息存入到区块链上,这样可以很大程度上减少空间开销,但是原始数据对人类不友好。因此在最终给人阅读前,需要由程序把所有变动的 patch 都依次打上才行。
经过调研,发现 Steem 使用的是 Google 的 DiffMatchPatch 这个库,但是遗憾的是,没有针对 PHP 的封装。不过最终我也还是找到一个 PHP 的库,https://github.com/yetanotherape/diff-match-patch 。
这个库的使用非常的简单,直接上示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?php require __DIR__ . '/vendor/autoload.php'; use DiffMatchPatch\DiffMatchPatch; $dmp = new DiffMatchPatch();
$old = "[SteemLightDB](https://github.com/ety001/steem-lightdb) (以下简称 LightDB ) 是一个基于 Steem 链的 MySQL 数据服务。
在有 SBDS 的情况下,为啥还要在弄一个 SteemLightDB 呢?
由于之前搭建过 SBDS 服务,发现里面有很多的问题,其中稳定性、数据原始性、数据容量这三个问题比较突出。
* SBDS 的稳定性直接依赖于其取数据的节点的稳定性; * SBDS 的数据太原始,加工度不够,如果应用开发者需要一些数据之间的关系,需要开发者获取后自己加工,增加了开发者的开发工作量和难度; * SBDS 占用空间太大,对于穷人来说,服务器费用开销太大。";
$patches = "@@ -32,11 +32,8 @@ om/e -ty0 01/s @@ -90,17 +90,16 @@ %E6%95%B0%E6%8D%AE%E6%9C%8D%E5%8A%A1%E3%80%82%0A%0A -%E5%9C%A8 %E6%9C%89 SBDS %E7%9A%84 ";
$new_content = "[SteemLightDB](https://github.com/e01/steem-lightdb) (以下简称 LightDB ) 是一个基于 Steem 链的 MySQL 数据服务。
有 SBDS 的情况下,为啥还要在弄一个 SteemLightDB 呢?
由于之前搭建过 SBDS 服务,发现里面有很多的问题,其中稳定性、数据原始性、数据容量这三个问题比较突出。
* SBDS 的稳定性直接依赖于其取数据的节点的稳定性; * SBDS 的数据太原始,加工度不够,如果应用开发者需要一些数据之间的关系,需要开发者获取后自己加工,增加了开发者的开发工作量和难度; * SBDS 占用空间太大,对于穷人来说,服务器费用开销太大。";
$patches = $dmp->patch_fromText($patches); $res = $dmp->patch_apply($patches, $old); var_dump($res); var_dump($new_content);
|
这里需要注意一点,就是 patch 中数据的格式。之前一直卡在这里调不出来的原因就是 steemd.com 中提供的 patch 数据格式有问题。就像我上面给出的示例代码中的 patch ,其中有些行前面是有空格的,而在 steemd.com 提供数据中,这些空格是消失了的。。。
除此之外,还有一个坑,就是 Steem 会针对文章长短来采取是否使用 patch。。。也就是说如果你的文章就一句话,如果你编辑修好提交了,那么就不会用 patch,而是直接把你新修改的内容直接提交保存。。。具体多长我也不清楚,我没有看源码,但是有一点可以肯定就是这个操作让人很蛋疼。目前我的解决方案是使用 try catch 来区分是否使用了 patch。
1 2 3 4 5 6
| try { $patches = $dmp->patch_fromText($patches); $res = $dmp->patch_apply($patches, $old); } catch(\Exception $e) { $res = $patches; }
|
虽然目前看貌似没有什么问题,但是感觉实现的很不优雅。
OVER!