jfcherng / php-diff
一个综合库,用于生成多种格式(统一、并排HTML等)的两个字符串之间的差异。
7.0.0-alpha.2
2023-03-11 07:17 UTC
Requires
- php: >=8.1
- jfcherng/php-color-output: ^3
- jfcherng/php-mb-string: ^2
- jfcherng/php-sequence-matcher: ^4.0.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3
- phan/phan: ^5
- phpunit/phpunit: ^10
- squizlabs/php_codesniffer: ^3.7
- 7.0.0-alpha.2
- 7.0.0-alpha.1
- v6.x-dev
- 6.16.2
- 6.16.1
- 6.16.0
- 6.15.3
- 6.15.2
- 6.15.1
- 6.15.0
- 6.14.2
- 6.14.1
- 6.14.0
- 6.13.1
- 6.13.0
- 6.12.1
- 6.12.0
- 6.11.6
- 6.11.5
- 6.11.4
- 6.11.3
- 6.11.2
- 6.11.1
- 6.11.0
- 6.10.17
- 6.10.16
- 6.10.15
- 6.10.14
- 6.10.13
- 6.10.12
- 6.10.11
- 6.10.10
- 6.10.9
- 6.10.8
- 6.10.7
- 6.10.6
- 6.10.5
- 6.10.4
- 6.10.3
- 6.10.2
- 6.10.1
- 6.10.0
- 6.9.0
- 6.8.0
- 6.7.7
- 6.7.6
- 6.7.5
- 6.7.4
- 6.7.3
- 6.7.2
- 6.7.1
- 6.7.0
- 6.6.4
- 6.6.3
- 6.6.2
- 6.6.1
- 6.6.0
- 6.5.7
- 6.5.6
- 6.5.5
- 6.5.4
- 6.5.3
- 6.5.2
- 6.5.1
- 6.5.0
- 6.4.7
- 6.4.6
- 6.4.5
- 6.4.4
- 6.4.3
- 6.4.2
- 6.4.1
- 6.4.0
- 6.3.2
- 6.3.1
- 6.3.0
- 6.2.1
- 6.2.0
- 6.1.2
- 6.1.1
- 6.1.0
- 6.0.1
- 6.0.0
- v5.x-dev
- 5.2.2
- 5.2.1
- 5.2.0
- 5.1.1
- 5.1.0
- 5.0.2
- 5.0.1
- 5.0.0
- v4.x-dev
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.9
- 4.1.8
- 4.1.7
- 4.1.5
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.1
- 4.0.0
- 3.3.0
- 3.2.6
- 3.2.5
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.0
- 2.2.0
- 2.1.23
- 2.1.22
- 2.1.21
- 2.1.20
- 2.1.19
- 2.1.18
- 2.1.17
- 2.1.16
- 2.1.15
- 2.1.14
- 2.1.13
- 2.1.12
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- dev-v6-php71
- dev-exp-php81
This package is auto-updated.
Last update: 2024-09-18 02:39:46 UTC
README
一个综合库,用于生成两个字符串之间的diff。
介绍
生成的diff可以在所有标准格式中渲染,包括
文本渲染器
- 上下文
- Json(纯文本)
- 统一
HTML渲染器
- 组合
- 内联
- Json(HTML)
- 并排
注意:对于HTML渲染结果,您需要添加CSS以获得更好的可视化效果。您可以从example/diff-table.css
中修改一个,或者从头开始编写。
如果您对默认CSS满意,则可以使用\Jfcherng\Diff\DiffHelper::getStyleSheet()
获取example/diff-table.css
的内容。
要求
安装
该包可在Packagist
上通过jfcherng/php-diff名称获取。
composer require jfcherng/php-diff
示例
请参阅example/目录中的文件和readme。
<?php include __DIR__ . '/vendor/autoload.php'; use Jfcherng\Diff\Differ; use Jfcherng\Diff\DiffHelper; use Jfcherng\Diff\Factory\RendererFactory; use Jfcherng\Diff\Renderer\RendererConstant; $oldFile = __DIR__ . '/example/old_file.txt'; $newFile = __DIR__ . '/example/new_file.txt'; $old = 'This is the old string.'; $new = 'And this is the new one.'; // renderer class name: // Text renderers: Context, JsonText, Unified // HTML renderers: Combined, Inline, JsonHtml, SideBySide $rendererName = 'Unified'; // the Diff class options $differOptions = [ // show how many neighbor lines // Differ::CONTEXT_ALL can be used to show the whole file 'context' => 3, // ignore case difference 'ignoreCase' => false, // ignore line ending difference 'ignoreLineEnding' => false, // ignore whitespace difference 'ignoreWhitespace' => false, // if the input sequence is too long, it will just gives up (especially for char-level diff) 'lengthLimit' => 2000, // if truthy, when inputs are identical, the whole inputs will be rendered in the output 'fullContextIfIdentical' => false, ]; // the renderer class options $rendererOptions = [ // how detailed the rendered HTML in-line diff is? (none, line, word, char) 'detailLevel' => 'line', // renderer language: eng, cht, chs, jpn, ... // or an array which has the same keys with a language file // check the "Custom Language" section in the readme for more advanced usage 'language' => 'eng', // show line numbers in HTML renderers 'lineNumbers' => true, // show a separator between different diff hunks in HTML renderers 'separateBlock' => true, // show the (table) header 'showHeader' => true, // the frontend HTML could use CSS "white-space: pre;" to visualize consecutive whitespaces // but if you want to visualize them in the backend with " ", you can set this to true 'spacesToNbsp' => false, // HTML renderer tab width (negative = do not convert into spaces) 'tabSize' => 4, // this option is currently only for the Combined renderer. // it determines whether a replace-type block should be merged or not // depending on the content changed ratio, which values between 0 and 1. 'mergeThreshold' => 0.8, // this option is currently only for the Unified and the Context renderers. // RendererConstant::CLI_COLOR_AUTO = colorize the output if possible (default) // RendererConstant::CLI_COLOR_ENABLE = force to colorize the output // RendererConstant::CLI_COLOR_DISABLE = force not to colorize the output 'cliColorization' => RendererConstant::CLI_COLOR_AUTO, // this option is currently only for the Json renderer. // internally, ops (tags) are all int type but this is not good for human reading. // set this to "true" to convert them into string form before outputting. 'outputTagAsString' => false, // this option is currently only for the Json renderer. // it controls how the output JSON is formatted. // see available options on https://php.ac.cn/manual/en/function.json-encode.php 'jsonEncodeFlags' => \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE, // this option is currently effective when the "detailLevel" is "word" // characters listed in this array can be used to make diff segments into a whole // for example, making "<del>good</del>-<del>looking</del>" into "<del>good-looking</del>" // this should bring better readability but set this to empty array if you do not want it 'wordGlues' => [' ', '-'], // change this value to a string as the returned diff if the two input strings are identical 'resultForIdenticals' => null, // extra HTML classes added to the DOM of the diff container 'wrapperClasses' => ['diff-wrapper'], ]; // one-line simply compare two files $result = DiffHelper::calculateFiles($oldFile, $newFile, $rendererName, $differOptions, $rendererOptions); // one-line simply compare two strings $result = DiffHelper::calculate($old, $new, $rendererName, $differOptions, $rendererOptions); // or even shorter if you are happy with default options $result = DiffHelper::calculate($old, $new, $rendererName); // custom usage $differ = new Differ(explode("\n", $old), explode("\n", $new), $differOptions); $renderer = RendererFactory::make($rendererName, $rendererOptions); // or your own renderer object $result = $renderer->render($differ); // use the JSON result to render in HTML $jsonResult = DiffHelper::calculate($old, $new, 'Json'); // may store the JSON result in your database $htmlRenderer = RendererFactory::make('Inline', $rendererOptions); $result = $htmlRenderer->renderArray(json_decode($jsonResult, true));
渲染结果
HTML Diff内联详细渲染
渲染器:内联
<?php $rendererOptions = ['detailLevel' => 'line'];
渲染器:并排
<?php $rendererOptions = ['detailLevel' => 'line'];
渲染器:组合
<?php $rendererOptions = ['detailLevel' => 'word'];
此渲染器适用于文章,始终没有行号信息。
渲染器:统一
关于统一
diff格式:https://en.wikipedia.org/wiki/Diff#Unified_format
@@ -1,3 +1,4 @@ -<p>Hello World!</p> +<div>Hello World!</div> ~~~~~~~~~~~~~~~~~~~ +Let's add a new line here. X @@ -7,6 +8,5 @@ N -Do you know in Chinese, "金槍魚罐頭" means tuna can. +Do you know in Japanese, "魚の缶詰" means fish can. This is just a useless line. G -// remember to delete this line Say hello to my neighbors.
渲染器:上下文
关于上下文
diff格式:https://en.wikipedia.org/wiki/Diff#Context_format
点击展开
*************** *** 1,3 **** ! <p>Hello World!</p> ~~~~~~~~~~~~~~~~~~~ X --- 1,4 ---- ! <div>Hello World!</div> ~~~~~~~~~~~~~~~~~~~ + Let's add a new line here. X *************** *** 7,12 **** N ! Do you know in Chinese, "金槍魚罐頭" means tuna can. This is just a useless line. G - // remember to delete this line Say hello to my neighbors. --- 8,12 ---- N ! Do you know in Japanese, "魚の缶詰" means fish can. This is just a useless line. G Say hello to my neighbors.
渲染器:文本JSON
此渲染器没有详细diff。
点击展开
[ [ { "tag": "rep", "old": { "offset": 0, "lines": ["<p>Hello World! Good-looking.</p>"] }, "new": { "offset": 0, "lines": ["<div>Hello World! Bad-tempered.</div>"] } }, { "tag": "eq", "old": { "offset": 1, "lines": ["~~~~~~~~~~~~~~~~~~~"] }, "new": { "offset": 1, "lines": ["~~~~~~~~~~~~~~~~~~~"] } }, { "tag": "ins", "old": { "offset": 2, "lines": [] }, "new": { "offset": 2, "lines": ["Let's add a new line here."] } }, { "tag": "eq", "old": { "offset": 2, "lines": ["X"] }, "new": { "offset": 3, "lines": ["X"] } } ], [ { "tag": "eq", "old": { "offset": 6, "lines": ["N"] }, "new": { "offset": 7, "lines": ["N"] } }, { "tag": "rep", "old": { "offset": 7, "lines": ["Do you know in Chinese, \"金槍魚罐頭\" means tuna can."] }, "new": { "offset": 8, "lines": ["Do you know in Japanese, \"魚の缶詰\" means fish can."] } }, { "tag": "eq", "old": { "offset": 8, "lines": ["\t \tTab visualization test.", "G"] }, "new": { "offset": 9, "lines": ["\t \tTab visualization test.", "G"] } }, { "tag": "del", "old": { "offset": 10, "lines": ["// remember to delete this line"] }, "new": { "offset": 11, "lines": [] } }, { "tag": "eq", "old": { "offset": 11, "lines": ["Say hello to my neighbors."] }, "new": { "offset": 11, "lines": ["Say hello to my neighbors."] } } ], [ { "tag": "eq", "old": { "offset": 14, "lines": ["B"] }, "new": { "offset": 14, "lines": ["B"] } }, { "tag": "rep", "old": { "offset": 15, "lines": ["Donec rutrum."] }, "new": { "offset": 15, "lines": ["Donec rutrum test.", "There is a new inserted line."] } }, { "tag": "eq", "old": { "offset": 16, "lines": ["C"] }, "new": { "offset": 17, "lines": ["C"] } }, { "tag": "rep", "old": { "offset": 17, "lines": ["Sed dictum lorem ipsum."] }, "new": { "offset": 18, "lines": ["Sed dolor lorem ipsum hendrerit."] } }, { "tag": "eq", "old": { "offset": 18, "lines": [""] }, "new": { "offset": 19, "lines": [""] } } ] ]
渲染器:HTML JSON
对于"tag": "rep" (8)
块,此渲染器具有HTML样式的详细diff。如果您不需要这些详细diff,请考虑使用JsonText
渲染器。
点击展开
[ [ { "tag": "rep", "old": { "offset": 0, "lines": ["<<del>p>Hello World! Good-looking.</p</del>>"] }, "new": { "offset": 0, "lines": ["<<ins>div>Hello World! Bad-tempered.</div</ins>>"] } }, { "tag": "eq", "old": { "offset": 1, "lines": ["~~~~~~~~~~~~~~~~~~~"] }, "new": { "offset": 1, "lines": ["~~~~~~~~~~~~~~~~~~~"] } }, { "tag": "ins", "old": { "offset": 2, "lines": [""] }, "new": { "offset": 2, "lines": ["Let's add a new line here."] } }, { "tag": "eq", "old": { "offset": 2, "lines": ["X"] }, "new": { "offset": 3, "lines": ["X"] } } ], [ { "tag": "eq", "old": { "offset": 6, "lines": ["N"] }, "new": { "offset": 7, "lines": ["N"] } }, { "tag": "rep", "old": { "offset": 7, "lines": ["Do you know in <del>Chinese, \"金槍魚罐頭\" means tuna</del> can."] }, "new": { "offset": 8, "lines": ["Do you know in <ins>Japanese, \"魚の缶詰\" means fish</ins> can."] } }, { "tag": "eq", "old": { "offset": 8, "lines": ["\t \tTab visualization test.", "G"] }, "new": { "offset": 9, "lines": ["\t \tTab visualization test.", "G"] } }, { "tag": "del", "old": { "offset": 10, "lines": ["// remember to delete this line"] }, "new": { "offset": 11, "lines": [""] } }, { "tag": "eq", "old": { "offset": 11, "lines": ["Say hello to my neighbors."] }, "new": { "offset": 11, "lines": ["Say hello to my neighbors."] } } ], [ { "tag": "eq", "old": { "offset": 14, "lines": ["B"] }, "new": { "offset": 14, "lines": ["B"] } }, { "tag": "rep", "old": { "offset": 15, "lines": ["Donec rutrum."] }, "new": { "offset": 15, "lines": ["Donec rutrum test.", "There is a new inserted line."] } }, { "tag": "eq", "old": { "offset": 16, "lines": ["C"] }, "new": { "offset": 17, "lines": ["C"] } }, { "tag": "rep", "old": { "offset": 17, "lines": ["Sed d<del>ictum lorem ipsum</del>."] }, "new": { "offset": 18, "lines": ["Sed d<ins>olor lorem ipsum hendrerit</ins>."] } }, { "tag": "eq", "old": { "offset": 18, "lines": [""] }, "new": { "offset": 19, "lines": [""] } } ] ]
自定义语言
覆盖现有语言
如果您只想覆盖现有语言的一些翻译...
$rendererOptions = [ 'language' => [ // use English as the base language 'eng', // your custom overrides [ // use "Diff" as the new value of the "differences" key 'differences' => 'Diff', ], // maybe more overrides if you somehow need them... ], ]
致谢
该包最初是基于chrisboulton/php-diff构建的。但原始存储库似乎不再维护。从那时起,已经进行了大量重写和新增功能,因此我将其作为一个新包重新启动,以提高可见性。