A lightweight PHP library for fast text comparison and difference visualization. Find the quick difference between two text files and render the results in plain text or HTML format.
- Line-by-line comparison - Compares texts line by line with numbered output for easy change tracking
- Immutable result object - Returns a
Diffobject containing original, target, formatted diff, and changed line numbers - Dual output modes - Plain text diff output and styled HTML rendering with color-coded changes
- Strict mode support - Optional strict comparison that preserves different line ending formats
- Whitespace visualization - Pretty rendering shows tabs as arrows and spaces as dots for clarity
- Zero dependencies - Pure PHP implementation requiring only PHP 8.0+
The library consists of two main components with a clean separation of concerns:
┌─────────────────────────────────────────────────────────────┐
│ SimpleDiff │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ compare($left, $right, $strict) │ │
│ │ - Normalizes line endings (non-strict mode) │ │
│ │ - Performs line-by-line comparison │ │
│ │ - Tracks changed line numbers │ │
│ │ - Formats output with line numbers │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ renderDiff($diff) │ │
│ │ - Converts diff to styled HTML │ │
│ │ - Color-codes additions (green) / removals (red) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Diff │
│ Immutable Value Object │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ - original: string (normalized left input) │ │
│ │ - target: string (normalized right input) │ │
│ │ - diff: string (formatted diff output) │ │
│ │ - changedLines: int[] (line numbers that changed) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
The main comparison engine that processes two text inputs and generates a diff result.
Methods:
| Method | Description |
|---|---|
compare(string $left, string $right, bool $strict = false): Diff |
Compares two strings and returns a Diff object |
renderDiff(Diff|string $diff): string |
Renders the diff as styled HTML |
Comparison Process:
- Input normalization (non-strict mode): Converts all line endings (
\r\n,\r) to\nand trims whitespace - Line splitting: Splits both inputs into arrays by newline character
- Line-by-line comparison: Iterates through lines, comparing original vs target
- Output formatting: Prepends each line with status marker (
+,-, or space) and line number - Change tracking: Records line numbers where differences occur
An immutable value object that encapsulates the comparison result.
Properties (via getters):
| Property | Type | Description |
|---|---|---|
original |
string |
The normalized left/original input text |
target |
string |
The normalized right/target input text |
diff |
string |
The formatted diff output with line markers |
changedLines |
int[] |
Array of line numbers (1-indexed) that differ |
String Conversion:
The Diff object implements __toString() which returns the formatted diff string, allowing direct string casting.
It's best to use Composer for installation, and you can also find the package on Packagist and GitHub.
To install, simply use the command:
$ composer require baraja-core/simple-php-diffYou can use the package manually by creating an instance of the internal classes, or register a DIC extension to link the services directly to the Nette Framework.
- PHP 8.0 or higher
use Baraja\DiffGenerator\SimpleDiff;
$left = 'First text';
$right = 'Second text';
$diff = (new SimpleDiff)->compare($left, $right);
// Output the diff as plain text
echo '<code><pre>' . htmlspecialchars((string) $diff) . '</pre></code>';$diff = (new SimpleDiff)->compare($left, $right);
echo 'Changed lines: ' . implode(', ', $diff->getChangedLines());$simpleDiff = new SimpleDiff;
$diff = $simpleDiff->compare($left, $right);
// Returns styled HTML with color-coded changes
echo $simpleDiff->renderDiff($diff);The diff output uses a standardized format:
1| unchanged line
- 2| removed·line·with·visible·spaces
+ 2| added→→→→line·with·visible·tabs
3| another unchanged line
Format explanation:
- Lines starting with
(two spaces) are unchanged - Lines starting with
-indicate content from the original (left) text - Lines starting with
+indicate content from the target (right) text - Line numbers are right-padded and followed by
| - Spaces are rendered as
·(middle dot) - Tabs are rendered as
→→→→(four arrows)
The renderDiff() method generates HTML with inline styles:
<pre class="code">
<div> 1| unchanged line</div>
<div style="background:#e7acac">- 2| removed line</div>
<div style="background:#a2f19c">+ 2| added line</div>
<div> 3| another unchanged line</div>
</pre>Color coding:
- Green background (
#a2f19c): Added lines (prefixed with+) - Red background (
#e7acac): Removed lines (prefixed with-) - No background: Unchanged lines
In non-strict mode (default), the library normalizes line endings before comparison:
- Converts
\r\n(Windows) to\n - Converts
\r(old Mac) to\n - Trims leading and trailing whitespace from both inputs
This mode is ideal for comparing content where line ending differences should be ignored.
// Non-strict comparison (default)
$diff = (new SimpleDiff)->compare($left, $right);
$diff = (new SimpleDiff)->compare($left, $right, false);Strict mode preserves the original line endings and whitespace, useful when you need to detect differences in line termination characters.
// Strict comparison - preserves line endings
$diff = (new SimpleDiff)->compare($left, $right, true);$diff = (new SimpleDiff)->compare($left, $right);
// Get the normalized original text
$original = $diff->getOriginal();
// Get the normalized target text
$target = $diff->getTarget();$diff = (new SimpleDiff)->compare($left, $right);
// Using getter method
$diffString = $diff->getDiff();
// Using string casting (equivalent)
$diffString = (string) $diff;$diff = (new SimpleDiff)->compare($left, $right);
$changedLines = $diff->getChangedLines();
// Example output: [2, 5, 8] - lines 2, 5, and 8 were modified
foreach ($changedLines as $lineNumber) {
echo "Line {$lineNumber} was changed\n";
}
// Check if any changes occurred
if (count($changedLines) === 0) {
echo "No differences found!";
}$originalFile = file_get_contents('/path/to/original.txt');
$modifiedFile = file_get_contents('/path/to/modified.txt');
$simpleDiff = new SimpleDiff;
$diff = $simpleDiff->compare($originalFile, $modifiedFile);
// Check if files are identical
if (empty($diff->getChangedLines())) {
echo "Files are identical.";
} else {
echo "Files differ on lines: " . implode(', ', $diff->getChangedLines());
echo "\n\n";
echo $diff;
}If you need custom styling, you can process the diff string yourself:
$diff = (new SimpleDiff)->compare($left, $right);
$lines = explode("\n", $diff->getDiff());
$html = '<div class="my-diff-container">';
foreach ($lines as $line) {
$firstChar = $line[0] ?? '';
$cssClass = match ($firstChar) {
'+' => 'diff-added',
'-' => 'diff-removed',
default => 'diff-unchanged',
};
$html .= sprintf('<div class="%s">%s</div>', $cssClass, htmlspecialchars($line));
}
$html .= '</div>';
echo $html;function showCommitDiff(string $oldContent, string $newContent): string
{
$simpleDiff = new SimpleDiff;
$diff = $simpleDiff->compare($oldContent, $newContent);
$changedCount = count($diff->getChangedLines());
$output = "<h3>Changes: {$changedCount} line(s) modified</h3>";
$output .= $simpleDiff->renderDiff($diff);
return $output;
}Jan Barášek - https://baraja.cz
baraja-core/simple-php-diff is licensed under the MIT license. See the LICENSE file for more details.

