Diff: Know exactly what changed
array_diff() misses nested changes and shifts every index after an insertion. Diff compares two PHP values and tells you what was added, removed, modified or moved, at the exact path, with records matched by ID and secrets redacted. For text, it gives you GitHub-style line diffs with hunks, word highlighting, patches that git apply accepts, and HTML.
Everything you need to see what changed
One call for the default, immutable options when you need rules.
Changes at Exact Paths
Every change has a type and a path such as user.email, with its old and new values, and wasModified() or hasChanged() answer questions directly.
Records Matched by ID
identify('users', 'id') compares lists of records by key, and detectMoves() reports the ones that changed order.
Redaction Built In
redact('user.password') still detects the change but stores [REDACTED], even inside parent and removed values.
Strict and Predictable
1, '1' and 1.0 differ, a missing key is not null, map key order is ignored, and dates compare by instant.
GitHub-Style Text Diffs
Line diffs with hunks, word or character highlighting, and unified patches that git apply and patch accept.
HTML Ready
toHtml() returns an escaped table, styled by the optional resources/diff.css in light and dark mode.
A quick look
Give it the old value and the new value, and it tells you what changed.
1use Pharaonic\Diff\Diff; 2 3// Compare two values 4$before = ['name' => 'Ali', 'age' => 30, 'phone' => '0100']; 6 7$result = Diff::between($before, $after); 8 9$result->wasModified('age'); // true10$result->wasAdded('email'); // true11$result->wasRemoved('phone'); // true12$result->hasChanged('name'); // false13 14// Compare two texts15echo Diff::text("apple\nbanana\ncherry\n", "apple\nblueberry\ncherry\n")->toUnified();16// --- before17// +++ after18// @@ -1,3 +1,3 @@19// apple20// -banana21// +blueberry22// cherryDiff Questions
Quick answers about installing and using Diff.
What is Diff?
Semantic diffs of PHP arrays and objects, with paths, identity-aware lists, moves and redaction, plus GitHub-style text diffs with hunks, unified patches and HTML. It's a free, open-source PHP package by Pharaonic.
How do I install Diff?
Run composer require pharaonic/php-diff in your project's root directory.
What does Diff require?
The latest release requires PHP 8.2+.
How is it different from array_diff()?
array_diff() compares only the top level, loosely, and by value. Diff walks nested arrays and objects, compares strictly, aligns lists so one insertion does not shift every later item, matches records by ID, and tells you the exact path, type and old and new value of each change.
Can I keep passwords and tokens out of the result?
Yes. DiffOptions::create()->redact('user.password') still detects that the value changed, but the result stores [REDACTED] instead of it, including inside the values of its parent and of added or removed containers.
Can I apply the text diff as a patch?
Yes. toUnified() writes a standard unified diff that git apply and patch accept, including the "No newline at end of file" marker.
Does it work with Laravel?
Yes, it is plain PHP with no dependencies, so you can use it anywhere. Convert models with toArray() first, or register a normalizer for them.
Is Diff free to use?
Yes. Diff is open source under the MIT license, so you can use it in personal and commercial projects.
Where can I find the Diff documentation?
Read the Diff documentation for setup, configuration, and usage examples.
How do I report a bug or contribute to Diff?
Open an issue or a pull request on GitHub, or ask in the Pharaonic Discord.
Ready to dig in?
Read the full documentation for comparison rules, reading results, paths and wildcards, ignoring, selecting and redacting values, list strategies, identity and moves, objects, text diffs, unified and HTML output, limits, and exceptions.