# php-diff
[![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/jfcherng/php-diff/php.yml?branch=v6-php71&style=flat-square)](https://github.com/jfcherng/php-diff/actions)
[![Codacy grade](https://img.shields.io/codacy/grade/5b7ab5ed613d48b99f12cd334f6489ff/v6?style=flat-square)](https://app.codacy.com/project/jfcherng/php-diff/dashboard)
[![Packagist](https://img.shields.io/packagist/dt/jfcherng/php-diff?style=flat-square)](https://packagist.org/packages/jfcherng/php-diff)
[![Packagist Version](https://img.shields.io/packagist/v/jfcherng/php-diff?style=flat-square)](https://packagist.org/packages/jfcherng/php-diff)
[![Project license](https://img.shields.io/github/license/jfcherng/php-diff?style=flat-square)](https://github.com/jfcherng/php-diff/blob/v6/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/jfcherng/php-diff?style=flat-square&logo=github)](https://github.com/jfcherng/php-diff/stargazers)
[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-blue.svg?style=flat-square&logo=paypal)](https://www.paypal.me/jfcherng/5usd)
A comprehensive library for generating diff between two strings.
## Introduction
Generated diff can be rendered in all of the standard formats including:
**Text** renderers:
- Context
- Json (plain text)
- Unified
**HTML** renderers:
- Combined
- Inline
- Json (HTML)
- Side by Side
Note that for HTML rendered results, you have to add CSS for a better visualization.
You may modify one from `example/diff-table.css` or write your own from zero.
If you are okay with the default CSS, there is `\Jfcherng\Diff\DiffHelper::getStyleSheet()`
which can be used to get the content of the `example/diff-table.css`.
## Requirements
![php](https://img.shields.io/badge/php-%E2%89%A57.1.3-blue?style=flat-square)
![ext-iconv](https://img.shields.io/badge/ext-iconv-brightgreen?style=flat-square)
## Installation
This package is available on `Packagist` by the name of [jfcherng/php-diff](https://packagist.org/packages/jfcherng/php-diff).
```bash
composer require jfcherng/php-diff
```
## Example
See files and readme in the [example/](https://github.com/jfcherng/php-diff/blob/v6/example) directory.
```php
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,
];
// 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://www.php.net/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 "good-looking" into "good-looking"
// 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));
```
## Rendered Results
### HTML Diff In-line Detailed Rendering
None-level | Line-level (Default) |
---|---|
![]() |
![]() |
Word-level | Char-level |
![]() |
![]() |
Hello World!
+Hello World!
~~~~~~~~~~~~~~~~~~~ X --- 1,4 ---- !Hello World! Good-looking.
"] }, "new": { "offset": 0, "lines": ["