jfcherng/php-diff
jfcherng/php-diff is a comprehensive PHP library for generating diffs between two strings. It provides text renderers (Context, JSON, Unified) and HTML renderers (Combined, Inline, JSON, Side by Side). Install via Composer; requires PHP 8.3+ and ext-iconv. HTML output needs CSS for proper visualizat...
Unified and Context text renderers are the right primitive for email digests; JSON renderers let you persist a machine-readable change record alongside the notification..env snapshots, feature-flag payloads, translation files, or tenant settings is the same string-diff problem. ignoreWhitespace, ignoreLineEnding, and ignoreCase exist precisely for these noisy inputs.Json renderers let you compute and store a diff once (cheaply, at write time), then re-render it in any format later without recomputation. That is a genuine architectural decision this package enables, not just an implementation detail.Consider adoption when:
detailLevel of none/line/word/char) and configurable noise suppression (case, whitespace, line endings, tab width).renderArray().Differ + RendererFactory are composable, and renderers are pluggable.Look elsewhere when:
lengthLimit (default 2000, primarily for char-level) signals the performance envelope. Mass-diffing thousands of large documents per request is not this tool's job—batch it or reconsider.jsdiff-style) and you don't need persisted, server-authoritative change records.ext-iconv.Adoption caveats to price in: BSD-3-Clause is permissive and commercially safe, but the project is small (≈484 stars, no downstream dependents surfaced in this scan) and bus-factor exposure is real. HTML output requires you to supply CSS (DiffHelper::getStyleSheet() gives a default), and rendered user content must be escaped and sanitized—treat diff output as untrusted HTML in the same way you'd treat any rich-text path.
For executives (one paragraph): We need "show what changed" across content history, approvals, and compliance notifications—capabilities already on the roadmap. The underlying diff algorithm plus four presentation formats is a deceptively expensive thing to build and an ongoing maintenance liability. jfcherng/php-diff is a mature, permissively licensed (BSD-3), actively released PHP library that delivers it as a dependency. Adopting it removes a multi-week build from the roadmap, carries no license cost or commercial restriction, and lets us ship the user-facing features—audit views, review queues, change digests—rather than the plumbing beneath them. The main risk is maintainer concentration, which we mitigate by keeping our usage behind a thin internal adapter so the library is replaceable.
For engineering (the short version): Composer-installable, PSR-12, PHP 8.3+, ext-iconv only. Clean two-layer design: Differ produces the change model, RendererFactory renders it. Three integration paths, in increasing control: DiffHelper::calculate() / calculateFiles() for one-liners; new Differ(...) plus a renderer for custom flows; and Json output persisted to the database with renderArray() at display time—so you compute once at write and re-render in HTML, unified, or context later without recomputing. Options cover context lines, case/whitespace/line-ending insensitivity, granularity (none/line/word/char), line numbers, block separators, tab width, and a lengthLimit guard for pathological inputs. Renderers are pluggable if we ever need something bespoke. Our integration work is a service class, a Blade partial, the stylesheet, and output escaping—not an algorithm.
For design and content stakeholders: The renderers are the four layouts you'd expect—side-by-side, inline, combined (no line numbers, suited to prose and articles), and unified/context for text contexts like email. Granularity is a per-surface choice: line-level for code and config, word- or character-level for prose where a single changed sentence should highlight only the changed words.
How can I help you explore Laravel packages today?