PHPackages                             caxy/php-htmldiff - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. caxy/php-htmldiff

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

caxy/php-htmldiff
=================

A library for comparing two HTML files/snippets and highlighting the differences using simple HTML.

v0.1.17(1y ago)21320.9M—6.1%54[27 issues](https://github.com/caxy/php-htmldiff/issues)[5 PRs](https://github.com/caxy/php-htmldiff/pulls)11GPL-2.0PHPPHP &gt;=7.3

Since Jul 31Pushed 4mo ago42 watchersCompare

[ Source](https://github.com/caxy/php-htmldiff)[ Packagist](https://packagist.org/packages/caxy/php-htmldiff)[ Docs](https://github.com/caxy/php-htmldiff)[ RSS](/packages/caxy-php-htmldiff/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (42)Used By (11)

php-htmldiff
============

[](#php-htmldiff)

[![Scrutinizer Code Quality](https://camo.githubusercontent.com/78b27fa9015b8db67e0657b89d4bfd07afca35a49324b17c13b8c78926f9d612/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f636178792f7068702d68746d6c646966662f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/caxy/php-htmldiff/?branch=master)[![Build Status](https://camo.githubusercontent.com/c9c48d9b19cf75fae25ef5ffd7d7b8bd0ed3930608fa79b7160ea48397aa38a7/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f636178792f7068702d68746d6c646966662f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/caxy/php-htmldiff/build-status/master)[![Code Coverage](https://camo.githubusercontent.com/9beb6becc5ea59ad070797e6b368984d15d3892ffa362a05018e7bf1de30edad/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f636178792f7068702d68746d6c646966662f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/caxy/php-htmldiff/?branch=master)[![Packagist](https://camo.githubusercontent.com/97ed3a0897d8aedeb0dc74af6b48d0871613f7727b490998134bb7cbda2e869f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636178792f7068702d68746d6c646966662e737667)](https://packagist.org/packages/caxy/php-htmldiff)[![Average time to resolve an issue](https://camo.githubusercontent.com/c09c256defd86a12520ff6f43c79b7b26c6e24a439f5f605ae08b0193d49a3ba/687474703a2f2f697369746d61696e7461696e65642e636f6d2f62616467652f7265736f6c7574696f6e2f636178792f7068702d68746d6c646966662e737667)](http://isitmaintained.com/project/caxy/php-htmldiff "Average time to resolve an issue")[![Percentage of issues still open](https://camo.githubusercontent.com/35921dcba6b995f638488e658aa3b3271e4aa1241dad59f01e1863259e72583c/687474703a2f2f697369746d61696e7461696e65642e636f6d2f62616467652f6f70656e2f636178792f7068702d68746d6c646966662e737667)](http://isitmaintained.com/project/caxy/php-htmldiff "Percentage of issues still open")

php-htmldiff is a library for comparing two HTML files/snippets and highlighting the differences using simple HTML.

This HTML Diff implementation was forked from [rashid2538/php-htmldiff](https://github.com/rashid2538/php-htmldiff) and has been modified with new features, bug fixes, and enhancements to the original code.

For more information on these modifications, read the [differences from rashid2538/php-htmldiff](https://github.com/caxy/php-htmldiff/blob/master/doc/differences.rst) or view the [CHANGELOG](https://github.com/caxy/php-htmldiff/blob/master/CHANGELOG.md).

Demo
----

[](#demo)

Installation
------------

[](#installation)

The recommended way to install php-htmldiff is through [Composer](http://getcomposer.org/). Require the [caxy/php-htmldiff](https://packagist.org/packages/caxy/php-htmldiff) package by running following command:

```
composer require caxy/php-htmldiff
```

This will resolve the latest stable version.

Otherwise, install the library and setup the autoloader yourself.

### Working with Symfony

[](#working-with-symfony)

If you are using Symfony, you can use the [caxy/HtmlDiffBundle](https://github.com/caxy/HtmlDiffBundle) to make life easy!

Usage
-----

[](#usage)

```
use Caxy\HtmlDiff\HtmlDiff;

$htmlDiff = new HtmlDiff($oldHtml, $newHtml);
$content = $htmlDiff->build();
```

CSS Example
-----------

[](#css-example)

See  for starter CSS you can use for displaying the HTML diff output.

Configuration
-------------

[](#configuration)

The configuration for HtmlDiff is contained in the `Caxy\HtmlDiff\HtmlDiffConfig` class.

There are two ways to set the configuration:

1. [Configure an Existing HtmlDiff Object](#configure-an-existing-htmldiff-object)
2. [Create and Use a HtmlDiffConfig Object](#create-and-use-a-htmldiffconfig-object)

#### Configure an Existing HtmlDiff Object

[](#configure-an-existing-htmldiff-object)

When a new `HtmlDiff` object is created, it creates a `HtmlDiffConfig` object with the default configuration. You can change the configuration using setters on the object:

```
use Caxy\HtmlDiff\HtmlDiff;

// ...

$htmlDiff = new HtmlDiff($oldHtml, $newHtml);

// Set some of the configuration options.
$htmlDiff->getConfig()
    ->setMatchThreshold(80)
    ->setInsertSpaceInReplace(true)
;

// Calculate the differences using the configuration and get the html diff.
$content = $htmlDiff->build();

// ...
```

#### Create and Use a HtmlDiffConfig Object

[](#create-and-use-a-htmldiffconfig-object)

You can also set the configuration by creating an instance of `Caxy\HtmlDiff\HtmlDiffConfig` and using it when creating a new `HtmlDiff`object using `HtmlDiff::create`.

This is useful when creating more than one instance of `HtmlDiff`:

```
use Caxy\HtmlDiff\HtmlDiff;
use Caxy\HtmlDiff\HtmlDiffConfig;

// ...

$config = new HtmlDiffConfig();
$config
    ->setMatchThreshold(95)
    ->setInsertSpaceInReplace(true)
;

// Create an HtmlDiff object with the custom configuration.
$firstHtmlDiff = HtmlDiff::create($oldHtml, $newHtml, $config);
$firstContent = $firstHtmlDiff->build();

$secondHtmlDiff = HtmlDiff::create($oldHtml2, $newHtml2, $config);
$secondHtmlDiff->getConfig()->setMatchThreshold(50);

$secondContent = $secondHtmlDiff->build();

// ...
```

#### Full Configuration with Defaults:

[](#full-configuration-with-defaults)

```
$config = new HtmlDiffConfig();
$config
    // Percentage required for list items to be considered a match.
    ->setMatchThreshold(80)

    // Set the encoding of the text to be diffed.
    ->setEncoding('UTF-8')

    // If true, a space will be added between the  and  tags of text that was replaced.
    ->setInsertSpaceInReplace(false)

    // Option to disable the new Table Diffing feature and treat tables as regular text.
    ->setUseTableDiffing(true)

    // Pass an instance of \Doctrine\Common\Cache\Cache to cache the calculated diffs.
    ->setCacheProvider(null)

    // Disable the HTML purifier (only do this if you known what you're doing)
    // This bundle heavily relies on the purified input from ezyang/htmlpurifier
    ->setPurifierEnabled(true)

    // Set the cache directory that HTMLPurifier should use.
    ->setPurifierCacheLocation(null)

    // Group consecutive deletions and insertions instead of showing a deletion and insertion for each word individually.
    ->setGroupDiffs(true)

    // List of characters to consider part of a single word when in the middle of text.
    ->setSpecialCaseChars(array('.', ',', '(', ')', '\''))

    // List of tags (and their replacement strings) to be diffed in isolation.
    ->setIsolatedDiffTags(array(
        'ol'     => '[[REPLACE_ORDERED_LIST]]',
        'ul'     => '[[REPLACE_UNORDERED_LIST]]',
        'sub'    => '[[REPLACE_SUB_SCRIPT]]',
        'sup'    => '[[REPLACE_SUPER_SCRIPT]]',
        'dl'     => '[[REPLACE_DEFINITION_LIST]]',
        'table'  => '[[REPLACE_TABLE]]',
        'strong' => '[[REPLACE_STRONG]]',
        'b'      => '[[REPLACE_B]]',
        'em'     => '[[REPLACE_EM]]',
        'i'      => '[[REPLACE_I]]',
        'a'      => '[[REPLACE_A]]',
    ))

    // Sets whether newline characters are kept or removed when `$htmlDiff->build()` is called.
    // For example, if your content includes  tags, you might want to set this to true.
    ->setKeepNewLines(false)
;
```

Contributing
------------

[](#contributing)

See [CONTRIBUTING](https://github.com/caxy/php-htmldiff/blob/master/CONTRIBUTING.md) file.

Contributor Code of Conduct
---------------------------

[](#contributor-code-of-conduct)

Please note that this project is released with a [Contributor Code of Conduct](http://contributor-covenant.org/). By participating in this project you agree to abide by its terms. See [CODE\_OF\_CONDUCT](https://github.com/caxy/php-htmldiff/blob/master/CODE_OF_CONDUCT.md) file.

Credits
-------

[](#credits)

- [SavageTiger](https://github.com/SavageTiger) for contributing many improvements and fixes to caxy/php-htmldiff!
- [rashid2538](https://github.com/rashid2538) for the port to PHP and the base for our project: [rashid2538/php-htmldiff](https://github.com/rashid2538/php-htmldiff)
- [willdurand](https://github.com/willdurand) for an excellent post on [open sourcing libraries](http://williamdurand.fr/2013/07/04/on-open-sourcing-libraries/). Much of this documentation is based off of the examples in the post.

Did we miss anyone? If we did, let us know or put in a pull request!

License
-------

[](#license)

php-htmldiff is available under [GNU General Public License, version 2](http://www.gnu.org/licenses/gpl-2.0.html). See the [LICENSE](https://github.com/caxy/php-htmldiff/blob/master/LICENSE) file for details.

TODO
----

[](#todo)

- Tests, tests, and more tests! (mostly unit tests) - need more tests before we can major refactoring / cleanup for a v1 release
- Add documentation for setting up a cache provider (doctrine cache)
    - Maybe add abstraction layer for cache + adapter for doctrine cache
- Make HTML Purifier an optional dependency - possibly use abstraction layer for purifiers so alternatives could be used (or none at all for performance)
- Expose configuration for HTML Purifier (used in table diffing) - currently only cache dir is configurable through HtmlDiffConfig object
- Performance improvements (we have 1 benchmark test, we should probably get more)
    - Algorithm improvements - trimming alike text at start and ends, store nested diff results in memory to re-use (like we do w/ caching)
    - Benchmark using DOMDocument vs. alternatives vs. string parsing
    - Consider not using string parsing for HtmlDiff in order to avoid having to create many DOMDocument instances in ListDiff and TableDiff
- Benchmarking
- Refactoring (but... tests first)
    - Overall design/architecture improvements
    - API improvements so a new HtmlDiff isn't required for each new diff (especially so that configuration can be re-used)
- Split demo application to separate repository
- Add documentation on alternative htmldiff engines and perhaps some comparisons

###  Health Score

60

—

FairBetter than 99% of packages

Maintenance61

Regular maintenance activity

Popularity67

Solid adoption and visibility

Community42

Growing community involvement

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 59.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~123 days

Recently: every ~331 days

Total

33

Last Release

367d ago

PHP version history (2 changes)0.0.1PHP &gt;=5.3.3

v0.1.10PHP &gt;=7.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/43f12aab6bb0aa8924dee13a363a3d0808627782d14b2214e0059892a1b4f655?d=identicon)[jschroed91](/maintainers/jschroed91)

![](https://www.gravatar.com/avatar/e978fd38c8591f9960d5b2fb5361e6a9a15d316e02301583662fcd0451245326?d=identicon)[caxy](/maintainers/caxy)

---

Top Contributors

[![jschroed91](https://avatars.githubusercontent.com/u/2540804?v=4)](https://github.com/jschroed91 "jschroed91 (137 commits)")[![adamCaxy](https://avatars.githubusercontent.com/u/8698709?v=4)](https://github.com/adamCaxy "adamCaxy (25 commits)")[![rashid2538](https://avatars.githubusercontent.com/u/207907?v=4)](https://github.com/rashid2538 "rashid2538 (20 commits)")[![SavageTiger](https://avatars.githubusercontent.com/u/1238070?v=4)](https://github.com/SavageTiger "SavageTiger (15 commits)")[![mgersten-caxy](https://avatars.githubusercontent.com/u/4094087?v=4)](https://github.com/mgersten-caxy "mgersten-caxy (7 commits)")[![dbergunder](https://avatars.githubusercontent.com/u/2178929?v=4)](https://github.com/dbergunder "dbergunder (4 commits)")[![richardbrinkman](https://avatars.githubusercontent.com/u/3140575?v=4)](https://github.com/richardbrinkman "richardbrinkman (3 commits)")[![bobvandevijver](https://avatars.githubusercontent.com/u/1835343?v=4)](https://github.com/bobvandevijver "bobvandevijver (2 commits)")[![iluuu1994](https://avatars.githubusercontent.com/u/1752683?v=4)](https://github.com/iluuu1994 "iluuu1994 (1 commits)")[![irkallacz](https://avatars.githubusercontent.com/u/5904678?v=4)](https://github.com/irkallacz "irkallacz (1 commits)")[![jerray](https://avatars.githubusercontent.com/u/591094?v=4)](https://github.com/jerray "jerray (1 commits)")[![jprado](https://avatars.githubusercontent.com/u/931139?v=4)](https://github.com/jprado "jprado (1 commits)")[![jurgenhaas](https://avatars.githubusercontent.com/u/1475675?v=4)](https://github.com/jurgenhaas "jurgenhaas (1 commits)")[![LukeLeber](https://avatars.githubusercontent.com/u/3664814?v=4)](https://github.com/LukeLeber "LukeLeber (1 commits)")[![millnut](https://avatars.githubusercontent.com/u/8024370?v=4)](https://github.com/millnut "millnut (1 commits)")[![pharixces](https://avatars.githubusercontent.com/u/6975878?v=4)](https://github.com/pharixces "pharixces (1 commits)")[![s-ayers](https://avatars.githubusercontent.com/u/3673802?v=4)](https://github.com/s-ayers "s-ayers (1 commits)")[![snebes](https://avatars.githubusercontent.com/u/666333?v=4)](https://github.com/snebes "snebes (1 commits)")[![adamgoose](https://avatars.githubusercontent.com/u/611068?v=4)](https://github.com/adamgoose "adamgoose (1 commits)")[![berarma](https://avatars.githubusercontent.com/u/162766?v=4)](https://github.com/berarma "berarma (1 commits)")

---

Tags

diffdiff-htmldiffhtmlhtml-diffhtmldiffphpphp-htmldiffvisual-diffdiffhtml

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/caxy-php-htmldiff/health.svg)

```
[![Health](https://phpackages.com/badges/caxy-php-htmldiff/health.svg)](https://phpackages.com/packages/caxy-php-htmldiff)
```

###  Alternatives

[spatie/laravel-html

A fluent html builder

8376.4M72](/packages/spatie-laravel-html)[mkalkbrenner/php-htmldiff-advanced

An add-on for the php-htmldiff library for comparing two HTML files/snippets and highlighting the differences using simple HTML.

3517.8M1](/packages/mkalkbrenner-php-htmldiff-advanced)[jfcherng/php-diff

A comprehensive library for generating differences between two strings in multiple formats (unified, side by side HTML etc).

4705.1M51](/packages/jfcherng-php-diff)[yajra/laravel-datatables-html

Laravel DataTables HTML builder plugin

2899.6M48](/packages/yajra-laravel-datatables-html)[tinymce/tinymce

Web based JavaScript HTML WYSIWYG editor control.

1697.5M106](/packages/tinymce-tinymce)[voku/html-min

HTML Compressor and Minifier

1804.7M39](/packages/voku-html-min)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
