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 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.

September 17th, 2014

It was some time ago when I wrote the original share button for Identi.ca, back then Identi.ca enjoyed quite a lot of traffic and user activity, but more than that it was also developed heavily and was praised by many, including myself, for being technologically impressive whilst allowing easy online conversations and communication.

August 25th, 2014

This may sound like analyzing yesterday's news, but I think it's important, and more than that I need to put this here as a resource to point certain people to.

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!