Text Difference

By tye on Dec 31, 2006

Shows differences in two strings of text.

This snippet requires the PEAR Text_Diff package, available from http://pear.php.net/package/Text_Diff.

The class can be use like this:

$diff = new diff($from_text,$to_text);
echo $diff->render();

This will show you the difference in $from_text to $to_text. Text that was added will be shown in green, text that was removed will be shown in red.

A full example of the script is located at http://www.tye.ca/php/diff/

This script will work in PHP4 and PHP5. Lines commented with # are PHP5 equivalents of the lines directly above them (this script was originally written for PHP5).

<?php 

// This line must be used to load the Text/Diff.php PEAR module
// This can be downloaded from http://pear.php.net/package/Text_Diff
require_once("somepath/Text/Diff.php");

// Object created like this:
// $diff = new diff($from_text,$to_text);
// $from_text is the original text
// $to_text is the modified text
class diff extends Text_MappedDiff {

  public function diff($from_text,$to_text) {
  #public function __construct($from_text,$to_text) {

    // Split the text into words
    $from_words = preg_split('/\b/',$from_text);
    $to_words = preg_split('/\b/',$to_text);

    // These alternate split statements will split the text into individual characters
    //$from_words = str_split($from_text,1);
    //$to_words = str_split($to_text,1);

    // These split statements will split the text into lines
    //$from_words = explode("\n",$from_text);
    //$to_words = explode("\n",$to_text);

    // Text_MappedDiff requires copies of these variables
    $mapped_from_words = $from_words;
    $mapped_to_words = $to_words;

    // Call the construct method of the parent class
    parent::Text_MappedDiff($from_words,$to_words,$mapped_from_words,$mapped_to_words);
  }

  // Renders the difference
  public function render() {
    $difference = $this->getDiff(); // Calls the getDiff() method, part of Text_MappedDiff
    $render = ''; // This will be the rendered difference.
    foreach ($difference as $op) {
      // $op is the operation getDiff() has calculated.
      // You can tell which operation (add, delete or change) $op is by checking which class the object is
      if (is_a(&$op,'Text_Diff_Op_copy')) {
      #if ($op instanceof Text_Diff_Op_copy) { // This uses the instanceof operator which is only in PHP5+, in PHP4 you can use is_a()
        // Text was copied (not changed), add it to the rendered difference unmodified
        $render .= implode('',$op->final);
      } elseif (is_a(&$op,'Text_Diff_Op_delete')) {
      #} elseif ($op instanceof Text_Diff_Op_delete) {
        // Text was deleted, add it to the rendered difference in red
        $render .= '<span style="background-color: #FF0000;">' . implode('',$op->orig) . '</span>';
      } elseif (is_a(&$op,'Text_Diff_Op_add')) {
      #} elseif ($op instanceof Text_Diff_Op_add) {
        // Text was added, add it to the rendered difference in green
        $render .= '<span style="background-color: #00FF00;">' . implode('',$op->final) . '</span>';
      } elseif (is_a(&$op,'Text_Diff_Op_change')) {
      #} elseif ($op instanceof Text_Diff_Op_change) {
        // Text was modified, add it to the rendered difference as if the original text was deleted and the new text was added
        $render .= '<span style="background-color: #FF0000;">' . implode('',$op->orig) . '</span>' . 
          '<span style="background-color: #00FF00;">' . implode('',$op->final) . '</span>';
      }
    }

    return $render;
  }

}

?>

Comments

Sign in to comment.
Brandon   -  Jan 15, 2007

This Calls for a MySQL Section.. I made a few MehSelf.

 Respond  
Hawkee   -  Jan 01, 2007

I can see how this would be useful as a mySQL function, but I haven\'t found a use for it yet in PHP code.

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.