xml_set_element_handler()
La funzione xml_set_element_handler() imposta funzioni definite dall'utente come handler per i tag di apertura e chiusura di un elemento XML in PHP.
xml_set_element_handler() registra due callback su un parser XML: una che si attiva ogni volta che il parser incontra un tag di apertura (<book>) e una che si attiva su ogni tag di chiusura (</book>). Appartiene al parser Expat basato sugli eventi di PHP — la famiglia xml_parser_* — non a SimpleXML o DOM. Mentre SimpleXML carica l'intero documento in un albero in memoria, Expat scorre il documento in streaming e chiama i tuoi handler man mano che procede, il che lo rende adatto a file di grandi dimensioni che non si vuole caricare tutti in una volta.
Questa pagina tratta la firma della funzione, gli argomenti esatti che ricevono i tuoi handler, un esempio completo eseguibile e le insidie più comuni (case folding dei nomi dei tag e la forma di callback con metodo di oggetto).
Sintassi
xml_set_element_handler(
XMLParser $parser,
callable $start_handler,
callable $end_handler
): bool| Parametro | Descrizione |
|---|---|
$parser | Il parser creato da xml_parser_create(). |
$start_handler | Chiamato su ogni tag di apertura. Riceve ($parser, $name, $attributes). |
$end_handler | Chiamato su ogni tag di chiusura. Riceve ($parser, $name). |
La funzione restituisce true in caso di successo e false in caso di errore. Una callback può essere fornita come stringa con il nome della funzione ("startTag"), come closure o come coppia oggetto-metodo ([$object, 'method']).
Cosa ricevono gli handler
- Start handler —
$nameè il nome del tag e$attributesè un array associativo degli attributi di quel tag (['ID' => 'b1']). - End handler — solo
$name, poiché i tag di chiusura non portano attributi.
Per impostazione predefinita, Expat converte i nomi di tag e attributi in maiuscolo (
<book>arriva comeBOOK). Confronta i nomi senza distinzione tra maiuscole e minuscole, oppure disattiva il folding conxml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false). Vedixml_parser_set_option().
Esempi d'uso
Esempio: Stampa dell'albero degli elementi
Questo script completo analizza una stringa XML e usa gli handler di apertura/chiusura per stampare uno schema indentato del documento, inclusi gli attributi di ogni tag.
<?php
$xml = '<?xml version="1.0"?>
<library>
<book id="b1">PHP Basics</book>
<book id="b2">Advanced XML</book>
</library>';
$depth = 0;
function startTag($parser, $name, $attrs) {
global $depth;
echo str_repeat(" ", $depth) . "START: $name";
foreach ($attrs as $key => $value) {
echo " ($key=\"$value\")";
}
echo "\n";
$depth++;
}
function endTag($parser, $name) {
global $depth;
$depth--;
echo str_repeat(" ", $depth) . "END: $name\n";
}
$parser = xml_parser_create();
xml_set_element_handler($parser, "startTag", "endTag");
if (!xml_parse($parser, $xml, true)) {
die(sprintf(
"XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
xml_parser_free($parser);Output:
START: LIBRARY
START: BOOK (ID="b1")
END: BOOK
START: BOOK (ID="b2")
END: BOOK
END: LIBRARYSi noti che library arriva come LIBRARY e id come ID: è il case folding menzionato sopra. Il terzo argomento di xml_parse() è impostato su true per indicare al parser che questo è il blocco finale (e unico) di dati. Rilascia sempre il parser con xml_parser_free() al termine.
Esempio: Utilizzo di un metodo di oggetto come handler
Gli handler non devono essere funzioni libere. Passare [$object, 'method'] consente di mantenere lo stato del parsing su un oggetto invece che nelle variabili globali — utile quando più handler devono condividere dati.
<?php
$xml = '<note><to>Tove</to><from>Jani</from></note>';
class TagCounter {
public int $open = 0;
public function onStart($parser, $name, $attrs) { $this->open++; }
public function onEnd($parser, $name) {}
}
$counter = new TagCounter();
$parser = xml_parser_create();
xml_set_element_handler($parser, [$counter, 'onStart'], [$counter, 'onEnd']);
xml_parse($parser, $xml, true);
xml_parser_free($parser);
echo "Opening tags seen: {$counter->open}\n";Output:
Opening tags seen: 3Quando usarlo
Ricorri agli handler Expat quando hai bisogno di una lettura in streaming con basso consumo di memoria su XML — feed di grandi dimensioni, file di log o sitemap — oppure quando ti interessano solo alcuni tag e non vuoi costruire un albero completo. Per leggere il testo all'interno di un elemento (PHP Basics in <book>PHP Basics</book>), abbinalo a xml_set_character_data_handler(). Se preferisci interrogare un documento piccolo con accesso simile a XPath, SimpleXML è più semplice. Per una panoramica di ogni approccio, consulta PHP XML Parsers.
Conclusione
xml_set_element_handler() collega le callback di apertura e chiusura dei tag al parser Expat event-driven di PHP, permettendoti di reagire alla struttura di un documento mentre viene letto in streaming. Ricorda i tre elementi essenziali: crea prima il parser, tieni conto dei nomi dei tag in maiuscolo e libera il parser al termine.