Signatur
Beschreibung
xml_set_element_handler() legt fest, welche PHP-Funktionen aufgerufen werden, wenn der XML-Parser ein öffnendes Tag (Start-Element) oder ein schließendes Tag (End-Element) findet. Diese Funktion ist essenziell, um mit dem SAX-Parsing-Modell von PHP XML-Dokumente effizient zu verarbeiten, ohne den gesamten Dokument-Baum im Speicher aufzubauen.
Der Start-Handler erhält als Argumente die Parser-Ressource, den Element-Namen sowie ein assoziatives Array aller Attribute des Elements. Der End-Handler erhält nur den Parser und den Element-Namen. Beide Callbacks können als null übergeben werden, um einen zuvor gesetzten Handler zu entfernen.
Typischer Einsatz ist die Verarbeitung großer XML-Dokumente (z. B. RSS-Feeds, SOAP-Antworten oder Daten-Importe), bei denen ein DOM-basierter Ansatz zu viel Speicher verbrauchen würde. Die Callbacks werden event-gesteuert ausgeführt, sobald xml_parse() den entsprechenden Tag-Beginn oder das Tag-Ende liest.
Seit PHP 8.0 ist der erste Parameter ein XMLParser-Objekt statt einer Ressource.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $parser Pflicht | XMLParser | Eine gültige XML-Parser-Instanz, erzeugt mit xml_parser_create() oder xml_parser_create_ns(). |
|
| $start_handler Pflicht | callable|string|null | Callback für öffnende Tags. Wird aufgerufen mit (XMLParser $parser, string $name, array $attributes). null entfernt einen vorhandenen Handler. |
|
| $end_handler Pflicht | callable|string|null | Callback für schließende Tags. Wird aufgerufen mit (XMLParser $parser, string $name). null entfernt einen vorhandenen Handler. |
Rückgabewert
true bei Erfolg zurück, false wenn der übergebene Parser ungültig ist.Beispiele
Einfaches SAX-Parsing eines XML-Dokuments
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="1" lang="de">
<title>PHP-Referenz</title>
</book>
<book id="2" lang="en">
<title>PHP Manual</title>
</book>
</catalog>
XML;
$parser = xml_parser_create('UTF-8');
function startElement(XMLParser $parser, string $name, array $attrs): void {
echo "Öffnendes Tag: <{$name}>";
if (!empty($attrs)) {
foreach ($attrs as $key => $value) {
echo " {$key}=\"{$value}\"";
}
}
echo PHP_EOL;
}
function endElement(XMLParser $parser, string $name): void {
echo "Schließendes Tag: </{$name}>" . PHP_EOL;
}
xml_set_element_handler($parser, 'startElement', 'endElement');
if (!xml_parse($parser, $xml, true)) {
echo 'Fehler: ' . xml_error_string(xml_get_error_code($parser));
}
xml_parser_free($parser);
Verwendung mit Objekt-Methoden als Callbacks
<?php
class RssFeedParser {
private array $items = [];
private string $currentTag = '';
private array $currentItem = [];
public function parse(string $xml): array {
$parser = xml_parser_create('UTF-8');
xml_set_element_handler(
$parser,
[$this, 'onStart'],
[$this, 'onEnd']
);
xml_set_character_data_handler($parser, [$this, 'onData']);
xml_parse($parser, $xml, true);
xml_parser_free($parser);
return $this->items;
}
public function onStart(XMLParser $parser, string $name, array $attrs): void {
$this->currentTag = $name;
if ($name === 'ITEM') {
$this->currentItem = [];
}
}
public function onEnd(XMLParser $parser, string $name): void {
if ($name === 'ITEM' && !empty($this->currentItem)) {
$this->items[] = $this->currentItem;
}
$this->currentTag = '';
}
public function onData(XMLParser $parser, string $data): void {
$data = trim($data);
if ($data !== '' && in_array($this->currentTag, ['TITLE', 'LINK'], true)) {
$this->currentItem[$this->currentTag] = $data;
}
}
}
$xml = '<?xml version="1.0"?><rss><channel>'
. '<item><title>Eintrag 1</title><link>https://example.com/1</link></item>'
. '<item><title>Eintrag 2</title><link>https://example.com/2</link></item>'
. '</channel></rss>';
$rssParser = new RssFeedParser();
$items = $rssParser->parse($xml);
foreach ($items as $item) {
echo $item['TITLE'] . ' => ' . $item['LINK'] . PHP_EOL;
}
// Wichtig · Fallstricke
Groß-/Kleinschreibung: Standardmäßig konvertiert der XML-Parser alle Element- und Attribut-Namen in Großbuchstaben. Dieses Verhalten kann mit xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false) deaktiviert werden, wenn die originale Schreibweise benötigt wird.
Attribute-Array: Das Array im Start-Handler enthält Attribut-Namen als Schlüssel und deren Werte als Strings. Ist kein Attribut vorhanden, wird ein leeres Array übergeben.
Kein Rückgabewert aus Callbacks: Rückgabewerte der Handler-Callbacks werden ignoriert. Um Daten zwischen Callbacks auszutauschen, empfiehlt sich die Verwendung einer Klassen-Instanz als Kontext (wie im zweiten Beispiel gezeigt) oder globaler Variablen.
Alternative: Für kleinere oder komplex verschachtelte Dokumente ist SimpleXML oder DOMDocument oft komfortabler. xml_set_element_handler() glänzt bei großen Datenmengen mit minimalem Speicherbedarf.