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 23 XML
  gp 23.1 XML_Util
  gp 23.2 XML_Beautifier
  gp 23.3 XML_RSS
  gp 23.4 XML_Tree
  gp 23.5 XML_DTD
  gp 23.6 XML_Parser
  gp 23.7 XML_Wddx
  gp 23.8 XML_Serializer
  gp 23.9 XML_Indexing


Rheinwerk Computing

23.8 XML_Serializer  toptop


Besprochene Version: 0.15.0 Lizenz: PHP-Lizenz 2.0
Klassendatei(en): XML/Serializer.php; XML/Deserializer.php

Dem Paket XML_Serializer liegt eine ähnliche Idee zugrunde wie XML_Wddx. Auch XML_Serializer ist in der Lage, Daten aus Variablen zu übernehmen und sie nach XML zu konvertieren. Die so erstellte PHP-Datei kann entweder durch ein anderes Script weiterverarbeitet werden oder als Datei abgelegt werden, um später wieder eingelesen zu werden.

Um die Daten zu kodieren, ist die Methode serialize() vorgesehen, die aus einem XML_Serializer-Objekt heraus aufgerufen werden muss. Dem Konstruktor des Objekts werden die Informationen übergeben, wie der Serialisierungsvorgang durchgeführt werden soll.

require_once ('XML/Serializer.php'); 
 
// Daten, die serialisiert werden sollen 
$obst = array('Äpfel', 'Birnen', 'Bananen'); 
 
// Optionen fuer den Serializer 
$options = array ( 
   'addDecl' => true, 
   'encoding' => 'ISO-8859–1', 
   'indent' => '  ', 
   'rootName' => 'gruenzeug', 
   'defaultTagName' => 'obst' 
); 
 
// Neues XML_Serializer-Objekt ableiten 
$serializer = new XML_Serializer($options); 
 
// Serialisierung durchfuehren 
$erg = $serializer->serialize($obst); 
 
// Fehler aufgetreten? 
if (true===PEAR::isError($erg)) 
{ 
   die($erg->getMessage()); 
} 
 
// Daten auslesen und ausgeben 
echo $serializer->getSerializedData();

Listing 23.14 Nutzung von XML_Serializer

In diesem Beispiel wird ein indiziertes Array serialisiert. Um diese Serialisierung durchzuführen, wird zunächst ein XML_Serializer-Objekt instanziiert, das mit einem Array von Optionen initialisiert wird. Dies erläutere ich ein wenig später im Text. Der Serialisierungsvorgang wird von der Methode serialize() durchgeführt, die die Daten als Parameter übergeben bekommt. Um die fertig serialisierten Daten aus dem Objekt auszulesen, ist die Methode getSerializedData() vorgesehen, die Ihnen die Daten als String zurückgibt.

Das Script aus Listing 23.14 gibt das folgende XML-Dokument aus:

<?xml version="1.0" encoding="ISO-8859–1"?> 
<gruenzeug> 
  <obst>Äpfel</obst> 
  <obst>Birnen</obst> 
  <obst>Bananen</obst> 
</gruenzeug>

Wie Sie sehen, sind die Daten komplett übernommen worden. Die Informationen für die Struktur der Datei wurden aus den Optionen übernommen.

Die Deklaration der Version (<?xml... ?>) wurde eingefügt, weil die Option addDecl den Wert true übergeben bekommen hat. Die Zeichensatzinformation wurde mit dem Schlüssel encoding übergeben, und die Namen der Tags finden sich in den Schlüsseln rootName und defaultTagName. Würden die Namen hier nicht übergeben, würde das Root-Element den Datentyp wiedergeben. In diesem Fall würde es array heißen. Die Inhalte des Arrays würden alle zu Elementen vom Typ <XML_Serializer_Tag>. In Tabelle 23.3 finden Sie eine Liste aller Optionen.

[Diese Option hat zurzeit noch keine Auswirkung auf die Ausgabe. ]
Tabelle 23.3 Optionen für die Initialisierung eines XML_Serializier-Objekts
Option Bedeutung
'indent' Das oder die Zeichen, die zum Einrücken der Tags genutzt werden sollen. Standard ist ein Leerzeichen.
'linebreak' Zeichen, die für den Zeilenumbruch genutzt werden sollen. Standard ist '\n'.
'typeHints' Definiert, ob Informationen zu den Datentypen der Elemente eingebettet werden sollen, was mit true passiert.
'addDecl' Legt mit einem booleschen Wert fest, ob die XML-Deklaration <?xml …?> ausgegeben werden soll. Der Standardwert ist false und verhindert eine Ausgabe.
'encoding' Typ des verwendeten Zeichensatzes für die XML-Deklaration. Standard ist keine Zeichensatzdefinition.
'defaultTagName' Name, der standardmäßig für die Tags genutzt wird. Vorgabe ist 'XML_Serializer_Tag'.
'classAsTagName' Wenn Sie hier ein true übergeben, wird der Name der Klasse, aus der ein Objekt abgeleitet wurde, als Root-Element genutzt. Die Namen der Elemente ergeben sich aus den Namen der Eigenschaften.
'keyAttribute' Name des Attributs, in dem der ursprüngliche Schlüssel eines Datensatzes abgelegt ist. Standard ist '_originalKey'.
'typeAttribute' Name des Attributs, in dem der Typ einer Variable abgelegt wird. Standard ist '_type'.
'classAttribute' Name des Attributs, in dem der Name einer Klasse abgelegt wird. Standard ist '_class'.
'scalarAsAttributes' Wenn Sie hier ein true übergeben, werden skalare Daten (Strings, Integers …) als Attribute abgelegt.
'prependAttributes' String, der dem Namen der Attribute vorangestellt wird. Standard ist ''.
'indentAttributes' Die Standardeinstellung false verhindert ein Einrücken der Attribute. Der Wert '_auto' rückt sie ein.
'mode' Wenn Sie hier 'simplexml' übergeben, bekommen Array-Felder dieselben Elementnamen zugewiesen wie ihre Eltern.
'addDoctype' Wenn Sie hier true übergeben, wird die Processing Instruction <!DOCTYPE…> eingefügt.
'doctype' Ein String mit der URI einer lokalen DTD oder ein Array mit dem öffentlichen Bezeichner und der URI einer öffentlichen DTD.
'rootName' Name des Root-Elements.
'rootAttributes' Assoziatives Array mit Attributen für das Root-Element.
'tagMap' Ein assoziatives Array, das Namen von Elementen als Schlüssel hat, deren Namen durch die Werte ersetzt werden.
'namespace' Hiermit kann ein Namensraum übergeben werden, der genutzt werden soll.
'replaceEntities' Legt fest, wie mit Entitäten verfahren werden soll. XML_SERIALIZER_ENITITES_XML (Default-Einstellung) ersetzt die XML-Sonderzeichen durch ihre Entitäten. XML_SERIALIZER_ENTITIES_NONE ignoriert Sonderzeichen, und XML_SERIALIZER_ENTITIES_HTML ersetzt alle Sonderzeichen durch die HTML-Entitäten.
'returnResult' Mit einem true können Sie hier definieren, dass die Methode serialize() sofort die serialisierten Daten zurückgibt.

Wie Sie sehen, sind die Möglichkeiten, die das Paket bietet, recht vielfältig, wie auch das folgende Beispiel zeigt, in dem ein Objekt serialisiert wird:

// Klasse, deren Objekt serialisiert werden soll 
class myObst 
{ 
   function __construct() 
   { 
      $this->obst=array('Äpfel','Birnen'); 
      $this->anzahl=4; 
   } 
} 
 
// Optionen zum Initialisieren des Objekts 
$options = array ( 
   'addDecl' => true, 
   'encoding' => 'ISO-8859–1', 
   'addDecl'=>true, 
   'addDoctype' => true, 
   'doctype'=>'obst.dtd', 
   'indent' => '  ', 
   'typeHints' => true, 
   'classAsTagName' =>true, 
   'defaultTagName'=>'daten' 
); 
 
$obst = new myObst;; 
 
$serializer = new XML_Serializer($options); 
$erg = $serializer->serialize($obst); 
if (true===PEAR::isError($erg)) 
{ 
   die($erg->getMessage()); 
} 
echo $serializer->getSerializedData();

Listing 23.15 Serialisierung eines Objekts

Wie Sie an den generierten Daten erkennen können, sind in diesem Fall deutlich mehr Informationen enthalten:

<?xml version="1.0" encoding="ISO-8859–1"?> 
<!DOCTYPE myObst SYSTEM "obst.dtd"> 
<myObst _class="myObst" _type="object"> 
  <obst _type="array"> 
    <daten _originalKey="0" _type="string">Äpfel</daten> 
    <daten _originalKey="1" _type="string">Birnen</daten> 
  </obst> 
  <anzahl _type="integer">4</anzahl> 
</myObst>

Diese Daten könnten sowohl mit einer DTD validiert werden als auch wieder zurück in PHP-Daten konvertiert werden.

Um solche XML-Daten wieder zurück in PHP-Daten zu konvertieren, steht der Unserializer zur Verfügung, der in der Datei XML/Unserializer.php deklariert ist. Nachdem Sie ein Objekt der Klasse abgeleitet haben, können Sie hier die Methode unserialize() nutzen, um serialisierte Daten zurückzuverwandeln.

Damit der Unserializer seine Aufgabe lösen kann, benötigt er die Information, wie die Daten kodiert sind. Hierzu müssen Sie die Optionen, die Sie bei der Serialisierung genutzt haben, auch hier wieder bei der Instanziierung übergeben.

Die Optionen sind teilweise mit denen identisch, die bei der Serialisierung genutzt werden. Unterstützt werden hier die Optionen 'keyAttribute', 'typeAttribute', 'classAttribute', 'tagAsClass', 'tagMap' und 'prependAttributes'.

'keyAttribute' verhält sich in diesem Fall allerdings ein wenig anders. Und zwar können Sie hier auch ein assoziatives Array übergeben, das definiert, welcher Name (Schlüssel des Feldes) in welchen String (Wert des Feldes) konvertiert werden soll. In diesem Array können Sie einen Schlüssel namens _default definieren, der immer dann genutzt wird, wenn kein anderer Schlüssel zutrifft.

Zusätzlich stehen die folgenden Schlüssel zur Verfügung: 'complexType' kann den Wert 'array' oder 'object' übergeben bekommen. Hiermit wird definiert, in welcher Form komplexe Datenstrukturen zurückgegeben werden. Der Schlüssel 'defaultClass' definiert den Namen der Klasse, die genutzt werden soll, um Objekte zu extrahieren. Die Default-Einstellung ist 'stdClass'. Mit 'parseAttributes', das einen booleschen Wert akzeptiert, können Sie festlegen, ob die Attribute, die in den XML-Daten übergeben werden, als Array zurückgegeben werden sollen. Standardmäßig wird das nicht gemacht. Die Option 'forceEnum' fordert ein Array mit Namen von Elementen. Diese Elemente werden dann immer als indiziertes Array zurückgegeben. Den Quell-Zeichensatz können Sie mit der Option 'encoding' festlegen, und den Zeichensatz für die Ausgabe können Sie über 'targetEncoding' bestimmen. Mit der Option 'returnResult' können Sie schließlich definieren, ob die Methode unserialize() die Daten sofort zurückgibt (true) oder ob diese nur mit getUnserializedData() ausgelesen werden können (false).

Da auch hier die Einschränkungen bezüglich des verwendeten Zeichensatzes gelten, die Sie auf Seite 705 im Abschnitt über XML_Util nachlesen können, kann es durchaus passieren, dass Dateien mit Sonderzeichen nicht korrekt interpretiert werden, weil PHP sie falsch erkennt. Daher macht es Sinn, wenn Sie versuchen, auf Sonderzeichen in den XML-Daten zu verzichten. Auch Entitäten werden zurzeit noch nicht immer korrekt gehandhabt.

Ein möglicher Ausweg wäre, komplett mit UTF-8 zu arbeiten, oder Sie nutzen eine URL-Kodierung für die Sonderzeichen.

require_once('XML/Unserializer.php'); 
 
// XML-Daten ohne Umlaute 
$origin=' 
<!DOCTYPE myObst SYSTEM "obst.dtd"> 
<myObst _class="myObst" _type="object"> 
  <obst _type="array"> 
    <daten _originalKey="0" _type="string">Aepfel</daten> 
    <daten _originalKey="1" _type="string">Birnen</daten> 
  </obst> 
  <anzahl _type="integer">4</anzahl> 
</myObst>'; 
 
// Klasse, die genutzt werden kann 
class myObst{}; 
 
$options = array('encoding' => 'ISO-8859–1', 
                 'tagAsClass' => true); 
$unserializer = new XML_Unserializer($options); 
 
$erg = $unserializer->unserialize($origin); 
if (true===PEAR::isError($erg)) 
{ 
   die( $erg->getMessage()) ; 
} 
$target = $unserializer->getUnserializedData(); 
echo '<pre>'; 
var_dump( $target); 
echo '</pre>';

Listing 23.16 Deserialisierung von Daten

Die Ausgabe, die generiert wird, lautet:

object(myObst)#3 (2) { 
  ["obst"]=> 
  array(2) { 
    [0]=> 
    string(6) "Aepfel" 
    [1]=> 
    string(6) "Birnen" 
  } 
  ["anzahl"]=> 
  int(4) 
}

Vielleicht sind Sie über die minimalistische Definition der Klasse myObst in der Zeile

class myObst{};

gestolpert. Damit ein Objekt dieser Klasse zurückgegeben werden kann, muss sie deklariert sein. Andernfalls würde ein Objekt der Klasse stdClass bzw. ein Objekt der Klasse zurückgegeben, deren Namen Sie mit der Option 'defaultClass' übergeben haben. Dass keine Eigenschaften deklariert sind, ist zwar nicht elegant, aber in PHP durchaus möglich.

Der Methode uneserialize() können Sie auch den Namen einer Datei übergeben, die eingelesen werden soll. Der zweite Parameter muss dann true sein. Das ist besonders interessant, da Sie auf dieser Basis z. B. auch eine RSS-Datei von einem anderen Server als Datenquelle verwenden können, um sie einfacher verarbeiten zu können.

Sowohl der Serializer als auch der Unserializer unterstützen noch die Methoden resetOptions(), setOptions() und setOption(). Die erste löscht alle definierten Optionen, und die zweite bekommt ein Array mit Optionen übergeben, das so aufgebaut sein muss wie das, das beim Konstruktor Verwendung findet. Mit der dritten Methode können Sie eine einzelne Option direkt setzen, indem Sie den Namen der Option sowie den Wert als getrennte Parameter übergeben. Das ist immer dann sehr hilfreich, wenn ein XML_Serialize- oder XML_Unserialize-Objekt mehrfach genutzt werden soll.

 <<   zurück
     
  Zum Katalog
Zum Katalog: PHP PEAR
PHP PEAR
Jetzt bestellen!
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: PHP 5.6 und MySQL 5.7






 PHP 5.6 und
 MySQL 5.7


Zum Katalog: Einstieg in PHP 5.6 und MySQL 5.6






 Einstieg in PHP 5.6
 und MySQL 5.6


Zum Katalog: Responsive Webdesign






 Responsive Webdesign


Zum Katalog: Moderne Websites entwickeln






 Moderne Websites
 entwickeln


Zum Katalog: MySQL 5.6






 MySQL 5.6


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
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.


[Rheinwerk Computing]

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