Simple PHP Diff Script - Shows Line Changes in Bold Text

May 27th, 2012 by Jacob Barkdull

Here's a simple PHP diff script I wrote for no particular reason. Its output is similar to how Wikipedia does it, though admittedly, a lot simpler and inferior. It works really well for predictable comparisons, like two files that are mostly the same or a directory listing where some files have been renamed, added or removed. However, I have no use for it, I was simply trying for proof of concept. Even if I have no use for it, somebody might, right?

Anyway, here's how it works.

  1. It loads two files (any file and its older version.)
  2. It slits (or "explodes") each line into an array and counts the number of lines.
  3. It then compares each line of the current file to its older version.
  4. If two lines match, the current file's line is displayed normally.
    • If two lines don't match it does the same process again, this time slitting each word into an array and comparing them to the words in the old file's line.
      • When two words don't match, the words from the current file's line are wrapped in HTML bold tags ("<b></b>") with a little style for color, and printed (or "echoed") on page.
  5. It then reads and displays the old version of the file.

PHP Source Code:

<?php

// Copyright (C) 2012 Jacob Barkdull
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU Affero General Public License as
//    published by the Free Software Foundation, either version 3 of the
//    License, or (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU Affero General Public License for more details.
//
//    You should have received a copy of the GNU Affero General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//--------------------
//
// Script Description:
//
//    A simple PHP diff script I wrote for no particular reason. Its 
//    output is similar to how Wikipedia does it, though admittedly, a 
//    lot simpler and inferior. It works really well for predictable 
//    comparisons, like two files that are mostly the same or a directory 
//    listing where some files have been renamed, added or removed.


// Display source code
if (basename ($_SERVER['PHP_SELF']) === basename (__FILE__)) {
    if (isset (
$_GET['source'])) {
        
header ('Content-type: text/plain; charset=UTF-8');
        exit (
file_get_contents (basename (__FILE__)));
    }
}

// Replace '<' and '>' Characters
function replace ($input)
{
    return 
str_replace (array ('<''>'), array ('&lt;''&gt;'), $input);
}

// Read files
$cf replace (file_get_contents ('testdoc.txt')); // Current Version
$of replace (file_get_contents ('testdoc_old.txt')); // Old Version

// Line Arrays
$cv explode ("\n"$cf);
$ov explode ("\n"$of);

// Count Lines - Set to Longer Version
$lc = (count ($cv) > count ($ov)) ? count ($cv) : count ($ov);

// Fix Mismatched Line Counts
for ($flc count ($ov); $flc $lc$flc++) {
    
$ov[$flc] = '';
}

// Begin HTML Table
echo '<table width="100%">'"\n<tbody>\n<tr>\n";

// Begin diff column
echo '<td valign="top">'"\nCurrent Version:<hr>\n<pre>\n";

for (
$l 0$l $lc$l++) {
    
// Word Arrays
    
$cw explode (' '$cv[$l]); // Current Version
    
$ow explode (' '$ov[$l]); // Old Version

    // Count Words - Set to Longer Version
    
$wc = (count ($cw) > count ($ow)) ? count ($cw) : count ($ow);

    
// Fix Mismatched Word Counts
    
for ($fwc count ($ow); $fwc $wc$fwc++) {
        
$ow[$fwc] = '';
    }

    
// If each line is identical, just echo the normal line. If not,
    // check if each word is identical. If not, wrap colored "<b>"
    // tags around the mismatched words.
    
if ($cv[$l] !== $ov[$l]) {
        for (
$w 0$w $wc$w++) {
            if (
$cw[$w] === $ow[$w]) {
                echo 
$cw[$w];
                echo (
$w !== ($wc 1)) ? ' ' "\n";
            } else {
                echo 
'<b style="color: #00BB00;">'$cw[$w];
                echo (
$w !== ($wc 1)) ? '</b> ' "</b>\n";
            }
        }
    } else {
        echo 
$cv[$l], "\n";
    }
}

// End diff column
echo "</pre>\n</td>\n<td>&nbsp;</td>\n";

// Begin old version column
echo '<td valign="top">'"\nOld Version:<hr>\n<pre>\n";
echo 
$of"\n";

// End old version column
echo "</pre>\n</td>\n";

// End HTML table
echo "</tr>\n</tbody>\n</table>";

Output:

Current Version:
This is the new file,
Here's an unchanged line,
This is totally awesome!
And here's whole new line!
  Old Version:
This is the old file,
Here's an unchanged line,
This is completely aweful!

If you think you could use this script for something, here is the source code: diff-script.php. If you make any changes, feel free to send them my way, someday I may need a script like this, so if you improve it that might mean a lot someday. Check out my other bits of code: here.

Let me know what you think in the comments. And enjoy!

Loading...

On the Blog RSS

May 9th, 2021

GNOME 40 is finally out and I'm happy to say a small contribution of mine made it into the release. My contribution adds a new feature to GNOME System Monitor version 40. Few articles about GNOME 40 mention it, but some power users might find my contribution useful.

November 15th, 2019
If you leave this option checked when you export your image, any pixels you erased will be saved in the exported image. They will not be truly erased, just made fully transparent. In other words, the data that describes the color of each pixel will be preserved, they will just be made invisible. This option has privacy implications. With it enabled, what you erase from an image may still be present in transparent pixels.
May 2nd, 2015

Over the past few days I've been in talks with a nice fellow named Kamil Jablonski, a concept artist, graphic designer, and web developer who recently contributed a Polish locale for HashOver. He shared with me a logo design for HashOver, that after some back and forth became, in my opinion, a very cool design.

Subscribe to Newsletter

Want to get the latest news and updates about my software, blog posts and behind the scenes information? Than subscribe to my newsletter to stay up-to-date!