Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 PEAR – Einführung
2 Authentication
3 Caching
4 Date and Time
5 File Formats
6 HTTP
7 Internationalization
8 Mail
9 Networking
10 PHP
11 Text
12 Web Services
13 Benchmarking
14 Configuration
15 Database
16 File System
17 HTML
18 Images
19 Logging
20 Math
21 Numbers
22 Tools and Utilities
23 XML
24 Selbst Pakete erstellen
25 PECL
Index
Ihre Meinung?

Spacer
 <<   zurück
PHP PEAR von Carsten Möhrke
Anwendung und Entwicklung – Erweiterungen für PHP schreiben
Buch: PHP PEAR

PHP PEAR
798 S., 39,90 Euro
Rheinwerk Computing
ISBN 3-89842-580-0
gp 11 Text
  gp 11.1 Text_Password
  gp 11.2 Text_CAPTCHA
  gp 11.3 Text_Wiki
  gp 11.4 Text_Highlighter
  gp 11.5 Text_Diff


Rheinwerk Computing

11.5 Text_Diff  toptop


Besprochene Version: 0.0.4 Lizenz: LGPL
Klassendatei(en): Text/Diff.php; Text/Diff3.php; Text/Diff/Renderer.php; Text/Diff/ Renderer/inline.php; Text/Diff/Renderer/unified.php

Text_Diff ist ein Paket, mit dem Sie die Funktionalität des diff-Befehls implementieren können. Dieser ist unter vielen Unix-Derivaten vorhanden und bietet die spannende Möglichkeit, zwei bzw. als diff3 drei Textdateien zeilenweise miteinander zu vergleichen. Das ist immer dann besonders praktisch, wenn Sie in einem langen Quelltext nur eine »Kleinigkeit« geändert haben, danach nichts mehr funktioniert und Sie die Stellen nicht mehr finden, an denen Sie etwas geändert haben. Das setzt natürlich voraus, dass Sie vorher eine Sicherheitskopie erstellt haben.

Da das Paket ursprünglich für die Nutzung in Wikis und für den Vergleich von Wiki-Dateien gedacht war, kennt es zwei Ausgabe-Modi. Zum einen können die ermittelten Daten gleich in Wiki-Syntax ausgegeben werden, um eine entsprechende Integration möglichst einfach zu gestalten. Die zweite Variante ist die Ausgabe als einfacher Text mit HTML-Tags.

Für die folgenden Beispiele habe die beiden Dateien aus Tabelle 11.4 genutzt.


Tabelle 11.4 Beispieltexte für Text_Diff
Zeile eins.text zwei.txt
1 2 3 4 5 6 Homer Bart Lisa Ned Tod Marge Homer Bard Lisa Ned Tod Grampa

Um die Unterschiede zwischen den beiden Texten zu ermitteln, müssen diese erst als Array, z. B. mit file(), eingelesen werden. Diese beiden Arrays werden dann an den Konstruktor Text_Diff() übergeben. Dabei wird sofort ausgewertet, ob Unterschiede zwischen den beiden Datensätzen ermittelt werden können.

Ist das der Fall, können die Daten mithilfe des inline- oder des unified-Renderers ausgegeben werden. Der inline-Renderer, den ich nachfolgend nutzen werde, liefert die Daten in HTML-Syntax zurück. Die unified-Variante generiert dementsprechend den Wiki-Code.

// Einbinden der benoetigten Dateien 
require_once ('Text/Diff.php'); 
 
// Quelldateien einlesen 
$zeilen1 = file('eins.txt'); 
$zeilen2 = file('zwei.txt'); 
 
// Objekt instanziieren 
$diff = new Text_Diff($zeilen1, $zeilen2); 
 
// Konnten Unterschiede gefunden werden? 
if (false===$diff->isEmpty()) 
{ 
   // Renderer-Objekt ableiten und Daten ausgeben 
   require_once 'Text/Diff/Renderer.php'; 
   require_once 'Text/Diff/Renderer/inline.php'; 
   $renderer = new Text_Diff_Renderer_inline(); 
   $res= $renderer->render($diff); 
   echo nl2br($res); 
} 
else 
{ 
   echo 'Es wurden keine Unterschiede festgestellt'; 
}

Listing 11.8 Ermitteln von Unterschieden in Texten mit Text_Diff

Nachdem die Daten in Listing 11.8 an den Konstruktor übergeben worden sind, ermittelt dieser sofort, ob es Unterschiede in den Datensätzen gibt. Ob welche gefunden wurden, wird hier mit der Methode isEmpty() geprüft. Liefert diese ein logisches Falsch zurück, wurden Unterschiede gefunden, die dann ausgegeben werden. In dem true-Teil der if-Abfrage werden zunächst die Dateien eingebunden, die zur Ausgabe der Daten benötigt werden. Möchten Sie auf den unified-Renderer zurückgreifen, müsste an dieser Stelle 'Text/Diff/Renderer/unified.php' eingebunden werden. Des Weiteren müsste ein Text_Diff_Renderer_unified-Objekt an Stelle eines Text_Diff_Renderer_inline-Objekts abgeleitet werden.

Das Text_Diff-Objekt wird an die Methode render() des Renderer-Objekts übergeben, die die Daten auswertet und aufbereitet. Da die Zeilenumbrüche aus der ursprünglichen Datei übernommen werden, greife ich auf nl2br() zurück, um die Daten für die Bildschirmausgabe aufzubereiten, die Sie in Abbildung 11.5 sehen können.

Abbildung 11.5 Die Unterschiede in den beiden Dateien

In der linken Spalte finden Sie alle Zeilen aus der Datei eins.txt. Zeilen, die sich von denen in der Datei zwei.txt unterscheiden, sind links jeweils durchgestrichen, und rechts daneben ist die Zeile aus zwei.txt zu finden. Das eigentliche Unterscheidungsmerkmal, wohin eine Zeile gehört, ist aber nicht die Position, sondern die Formatierung (unter- oder durchgestrichen), was sich besonders dann bemerkbar macht, wenn in der zweiten Datei eine zusätzliche Zeile vorhanden ist.

Sollten sich in einer Zeile nur einzelne Buchstaben geändert haben, erkennt der Renderer das und markiert nur die geänderten Zeichen.

Sollte Ihnen diese Auswertung nicht zusagen, können Sie die Daten auch selbst für die Ausgabe aufbereiten. Die Methode getDiff(), die zum Text_Diff-Objekt gehört, liefert Ihnen alles, was Sie brauchen.

Sie gibt ein Array aus Objekten zurück. Hierbei kann es sich um Objekte der folgenden Klassen handeln:

  • Text_Diff_Op_copy Wird für identische Zeilen genutzt.
  • Text_Diff_Op_change Enthält Zeilen, die sich geändert haben.
  • Text_Diff_Op_add Zeilen, die in der Ziel-Version der Datei hinzugefügt wurden (zurzeit nicht genutzt).
  • Text_Diff_Op_delete Zeilen, die in der Ziel-Version der Datei gelöscht wurden (zurzeit nicht genutzt).

Momentan reicht es also, wenn Sie zwischen den ersten beiden Klassen unterscheiden.

Innerhalb eines solchen Objekts gibt es wiederum zwei Arrays. Eines verbirgt sich hinter dem Schlüssel 'orig' und das andere hinter dem Schlüssel 'final'. Innerhalb dieser Arrays befindet sich dann immer ein Feld für jede Zeile der Datei, so dass diese gegenübergestellt werden können. In Listing 11.9 finden Sie eine Möglichkeit, um eine solche Gegenüberstellung in Form einer Tabelle zu realisieren.

require_once 'Text/Diff.php'; 
 
$datei1='eins.txt'; 
$datei2='zwei.txt'; 
 
$zeilen1 = file($datei1); 
$zeilen2 = file($datei2); 
 
$diff = new Text_Diff($zeilen1, $zeilen2); 
// Aenderungen vorhanden 
if (false==$diff->isEmpty()) 
{ 
   echo '<table border="1">'; 
   // Kopf der Tabelle 
   echo "<tr><th>$datei1</th> 
             <th>$datei2</th></tr>"; 
   $daten=$diff->getDiff(); 
   // Zurueckgeliefertes Array abarbeiten 
   foreach ($daten as $objekt) 
   { 
      // Sind die Daten identisch? 
      $identisch=($objekt instanceof Text_Diff_Op_copy); 
      for ($cnt=0;$cnt < count ($objekt->final); $cnt+=1) 
      { 
         // Nicht identische Zeilen rot hinterlegen 
         if (true===$identisch) 
         { 
            echo '<tr>'; 
         } 
         else 
         { 
          echo '<tr bgcolor="red">'; 
         } 
         echo "<td>{$objekt->orig[$cnt]}</td> 
               <td>{$objekt->final[$cnt]}</td></tr>"; 
      } 
   } 
   echo '</table>'; 
}

Listing 11.9 Manuelle Auswertung der ermittelten Daten

Um zu gewährleisten, dass Listing 11.9 zukunftssicher ist, wird auf Basis des mit PHP 5 eingeführten instanceof-Operators nur geprüft, ob das gefundene Objekt nicht von der Klasse Text_Diff_Op_copy abstammt. Natürlich könnte hier noch explizit geprüft werden, ob das Objekt von einer der anderen Klassen abstammt, um die Tabellenzeilen farblich unterschiedlich zu hinterlegen.

Nicht verschweigen möchte ich, dass Sie mit dem Paket auch drei Dateien miteinander vergleichen können. In dem Fall müsste die Datei Diff3.php inkludiert werden, und die Klasse, mit der Sie arbeiten müssten, heißt Text_Diff3 und bekommt natürlich drei Arrays mit Datei-Inhalten übergeben.

Die Nutzung der anderen Methoden verändert sich nicht. Allerdings liefert getDiff() Ihnen natürlich auch immer drei Arrays in einem Objekt zurück. Das erste ist nach wie vor unter dem Schlüssel 'orig' zu finden und die beiden anderen unter den Schlüsseln 'final1' und 'final2'.

 <<   zurück
     
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: PHP PEAR
PHP PEAR
Jetzt Buch bestellen!
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: PHP 5.6 und MySQL 5.7






 PHP 5.6 und
 MySQL 5.7


Zum Rheinwerk-Shop: Einstieg in PHP 5.6 und MySQL 5.6






 Einstieg in PHP 5.6
 und MySQL 5.6


Zum Rheinwerk-Shop: Responsive Webdesign






 Responsive Webdesign


Zum Rheinwerk-Shop: Moderne Websites entwickeln






 Moderne Websites
 entwickeln


Zum Rheinwerk-Shop: MySQL 5.6






 MySQL 5.6


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo








Copyright © Rheinwerk Verlag GmbH 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern