jfcherng/php-diff
Generate diffs between two strings in PHP with multiple renderers: unified/context text, JSON, and rich HTML (inline, side-by-side, combined). Includes configurable differ/renderer options and helper CSS for easy HTML diff styling.
Strengths:
lengthLimit mitigates risks of resource exhaustion for large inputs (e.g., diffing entire files).Gaps:
Differ/RendererFactory to Laravel’s container).DiffHelper::getStyleSheet()) may need bundling (e.g., Laravel Mix/Vite) for frontend integration.Core Laravel Integration:
Differ and RendererFactory in AppServiceProvider for dependency injection:
$this->app->bind(Differ::class, function () {
return new Differ([], [], new DifferOptions());
});
Diff facade for concise syntax (e.g., Diff::calculate($old, $new, 'Unified')).@diff directives for inline HTML diffs in views.API/CLI Use Cases:
JsonText/JsonHtml renderers for structured diff outputs (e.g., GitHub-style PR reviews).artisan diff commands for local file comparisons (e.g., php artisan diff:compare old.txt new.txt).Database/Storage:
JsonText output) in databases for audit trails or versioning systems.High:
RendererInterface).@stack/@push for CSS/JS.mb_convert_encoding).Medium:
lengthLimit and opcache.Low:
Use Case Prioritization:
Inline vs. JsonHtml).Performance Trade-offs:
lengthLimit and consider chunking for large files.Extensibility Needs:
Operational Impact:
Testing Strategy:
Differ/Renderer classes to test integration points (e.g., Blade directives, API responses).Laravel Core:
Differ/RendererFactory instances.@diff directives or custom Blade components for HTML diffs.diff:compare).Frontend:
diff-table.css via Laravel Mix/Vite or inline critical styles.JsonHtml) and hydrate with JS (e.g., React/Vue components).API:
JsonText/JsonHtml for structured diff responses (e.g., /api/diff endpoint).Database:
text or jsonb columns for versioning/auditing.file_id, timestamp) for querying.Pilot Phase:
Unified, Inline, JsonText) to identify the best fit.Core Integration:
AppServiceProvider:
$this->app->bind(Differ::class, fn() => new Differ([], [], new DifferOptions()));
$this->app->bind(RendererFactory::class, fn() => new RendererFactory());
Diff facade for concise usage:
// app/Facades/Diff.php
public static function calculate(string $old, string $new, string $renderer = 'Unified'): string {
return DiffHelper::calculate($old, $new, $renderer);
}
@diff component:
// resources/views/components/diff.blade.php
<div class="diff-wrapper">
{!! $diff !!}
</div>
API/CLI Integration:
Route::post('/api/diff', function (Request $request) {
$diff = Diff::calculate($request->old, $request->new, 'JsonText');
return response()->json($diff);
});
diff:compare command:
// app/Console/Commands/DiffCompare.php
public function handle() {
$old = file_get_contents($this->argument('old'));
$new = file_get_contents($this->argument('new'));
echo Diff::calculate($old, $new, 'SideBySide');
}
Frontend Integration:
resources/css/app.css:
@import 'vendor/jfcherng/php-diff/example/diff-table.css';
// Example: Fetch JSON diff and render with JS
fetch('/api/diff', { method: 'POST', body: JSON.stringify({ old, new }) })
.then(response => response.json())
.then(diff => {
const htmlRenderer = new Jfcherng\Diff\Renderer\Inline(new RendererOptions());
document.getElementById('diff-container').innerHTML = htmlRenderer.renderArray(diff);
});
How can I help you explore Laravel packages today?