jfcherng/php-diff
PHP library to generate diffs between two strings with multiple renderers: unified/context/text, JSON, and rich HTML (inline, side-by-side, combined). Includes helper CSS (or your own) and customizable differ/renderer options. Requires PHP 8.3+ and ext-iconv.
Installation:
composer require jfcherng/php-diff
Ensure PHP ≥ 8.3.0 and the iconv extension are enabled.
First Use Case:
Compare two strings with the default Unified renderer:
use Jfcherng\Diff\DiffHelper;
$old = "Hello world!";
$new = "Hi there!";
$diff = DiffHelper::calculate($old, $new);
echo $diff;
Key Entry Points:
DiffHelper::calculate() – Quick string comparison.DiffHelper::calculateFiles() – Compare file contents.Differ + RendererFactory – Custom workflows.String Comparison:
$diff = DiffHelper::calculate($oldText, $newText, 'Inline', $differOptions, $rendererOptions);
Unified for CLI tools, Inline/SideBySide for web UIs.File Comparison:
$diff = DiffHelper::calculateFiles('old.txt', 'new.txt', 'Context');
Custom Rendering:
$differ = new Differ(explode("\n", $old), explode("\n", $new), $differOptions);
$renderer = RendererFactory::make('Combined', $rendererOptions);
$htmlDiff = $renderer->render($differ);
Blade Templates:
// In a controller
$diff = DiffHelper::calculate($old, $new, 'SideBySide');
return view('diff.view', ['diff' => $diff]);
// In Blade
<div class="diff-container">
{!! $diff !!}
@include('diff-table.css') <!-- Include CSS -->
</div>
API Responses:
return response()->json([
'diff' => DiffHelper::calculate($old, $new, 'JsonText')
]);
Service Layer:
// app/Services/DiffService.php
class DiffService {
public function generateDiff(string $old, string $new, string $format = 'Unified'): string {
return DiffHelper::calculate($old, $new, $format);
}
}
JSON Storage:
$jsonDiff = DiffHelper::calculate($old, $new, 'Json');
// Store $jsonDiff in DB for later HTML rendering
Dynamic Renderers:
$rendererName = request()->input('renderer', 'Inline');
$diff = DiffHelper::calculate($old, $new, $rendererName);
Line-Level Granularity:
$differOptions = new DifferOptions(context: 5, detailLevel: 'line');
HTML Renderers Require CSS:
diff-table.css or use DiffHelper::getStyleSheet().<style>{!! \Jfcherng\Diff\DiffHelper::getStyleSheet() !!}</style>
Case Sensitivity:
ignoreCase: false treats Hello ≠ hello. Set ignoreCase: true for case-insensitive diffs.Performance with Large Files:
lengthLimit in DifferOptions to avoid memory issues:
$differOptions = new DifferOptions(lengthLimit: 10000);
Line Endings:
ignoreLineEnding: true merges \n/\r\n differences. Disable for strict comparisons.JSON Renderers:
JsonHtml vs. JsonText: Use JsonHtml for inline HTML diffs, JsonText for plain JSON.Validate Inputs:
Check Renderer Names:
Unified, Inline, SideBySide, Combined, Context, Json, JsonHtml.RendererConstant for constants.Debugging Custom Renderers:
\Jfcherng\Diff\Renderer\AbstractRenderer for custom logic:
class CustomRenderer extends AbstractRenderer {
protected function renderLine(...): string { ... }
}
Whitespace Handling:
ignoreWhitespace: true hides space/tab changes. Useful for code diffs but may mask issues.Custom Languages:
language option:
$rendererOptions = new RendererOptions(language: ['added' => '✅ Added']);
Post-Processing:
Json output to highlight changes in a custom UI:
$jsonDiff = json_decode(DiffHelper::calculate($old, $new, 'Json'), true);
// Process $jsonDiff['tag'] (e.g., 'del', 'ins', 'rep')
CLI Colorization:
$rendererOptions = new RendererOptions(cliColorization: RendererConstant::CLI_COLOR_ENABLE);
Tab Handling:
tabSize (negative = preserve tabs):
$rendererOptions = new RendererOptions(tabSize: -1); // Keep tabs as-is
How can I help you explore Laravel packages today?