xml_set_unparsed_entity_decl_handler()
Die Funktion xml_set_unparsed_entity_decl_handler() setzt eine benutzerdefinierte Funktion als Handler für nicht geparste Entitätsdeklarationen.
Die Funktion xml_set_unparsed_entity_decl_handler() setzt einen benutzerdefinierten Callback als Handler für nicht geparste Entitätsdeklarationen in einem XML-Parser. Sie gehört zur XML Parser (SAX)-Erweiterung von PHP und ist Teil derselben Familie wie xml_set_element_handler() und xml_set_character_data_handler() — sie gilt nicht für SimpleXML oder DOM.
Eine nicht geparste Entität ist eine Entität, deren Inhalt der XML-Prozessor nicht als XML parsen soll — typischerweise ein Verweis auf externe Binärdaten wie ein Bild, eine PDF- oder eine Audiodatei. Sie wird mit dem Schlüsselwort NDATA und einem Notationsnamen deklariert, zum Beispiel:
<!ENTITY logo SYSTEM "logo.png" NDATA png>Wenn der Parser auf eine solche Deklaration in der DTD des Dokuments trifft, ruft er Ihren Handler auf, damit Sie festhalten können, wo sich die Ressource befindet, anstatt sie als Markup zu laden.
Syntax
xml_set_unparsed_entity_decl_handler(
XMLParser $parser,
callable $handler
): true| Parameter | Beschreibung |
|---|---|
$parser | Der mit xml_parser_create() erstellte XML-Parser. |
$handler | Ein Callable oder der String-Name einer Funktion. Übergeben Sie einen leeren String (""), um den aktuellen Handler zu entfernen. |
Rückgabewert: gibt immer true zurück.
PHP 8-Hinweis: Seit PHP 8.0 ist der Parser ein
XMLParser-Objekt statt einerresource, der Code bleibt jedoch identisch — behandeln Sie den vonxml_parser_create()zurückgegebenen Wert weiterhin als undurchsichtiges Handle.
Die Callback-Signatur
Ihr Handler wird mit sechs Argumenten in dieser Reihenfolge aufgerufen:
handler(
XMLParser $parser,
string $entityName, // e.g. "logo"
string $base, // base URI used to resolve the system id (often empty)
string $systemId, // e.g. "logo.png"
string $publicId, // public id, if any
string $notationName // e.g. "png" — declared with xml_set_notation_decl_handler()
): voidBeispiel: Nicht geparste Entitätsdeklarationen erfassen
Erstellen Sie einen SAX-Parser mit xml_parser_create(), registrieren Sie den Handler und übergeben Sie dann das XML an xml_parse():
<?php
function handleUnparsedEntity($parser, $name, $base, $systemId, $publicId, $notationName) {
echo "Unparsed entity '$name' -> $systemId (notation: $notationName)\n";
}
$xmlParser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($xmlParser, "handleUnparsedEntity");
$xml = '<?xml version="1.0"?>
<!DOCTYPE catalog [
<!NOTATION png SYSTEM "image/png">
<!ENTITY logo SYSTEM "logo.png" NDATA png>
<!ENTITY manual SYSTEM "manual.pdf" NDATA pdf>
]>
<catalog/>';
xml_parse($xmlParser, $xml, true);
xml_parser_free($xmlParser);Erwartete Ausgabe:
Unparsed entity 'logo' -> logo.png (notation: png)
Unparsed entity 'manual' -> manual.pdf (notation: pdf)Der Handler wird einmal pro NDATA-Entität in der DTD aufgerufen und liefert Ihnen den Dateipfad ($systemId) sowie die Notation. Eine echte Anwendung würde diese Referenzen speichern — etwa um die Assets später herunterzuladen — anstatt sie auszugeben.
Häufige Fallstricke
- Die DTD muss
NDATA-Deklarationen enthalten. Eine normale interne Entität (<!ENTITY name "value">) ist geparster Text, daher sieht dieser Handler sie nie. Nur mitNDATA notationmarkierte Entitäten sind „nicht geparst". - Handler vor dem Aufruf von
xml_parse()registrieren. Wie jedexml_set_*_handler()-Funktion hat diese keinen Effekt, wenn das Parsen bereits begonnen hat. - Den Parser freigeben mit
xml_parser_free(), wenn Sie fertig sind, um Ressourcen freizugeben. - Nicht in SimpleXML. Wenn Sie wohlgeformtes XML lesen und nicht auf DTD-Entitätsdeklarationen reagieren müssen, ist der einfachere SimpleXML-Parser in der Regel die bessere Wahl.
Verwandte Funktionen
xml_parser_create()— erstellt den SAX-Parser, an den dieser Handler angehängt wird.xml_set_notation_decl_handler()— verarbeitet die<!NOTATION ...>-Deklarationen, auf die nicht geparste Entitäten verweisen.xml_set_external_entity_ref_handler()— verarbeitet geparste externe Entitätsreferenzen.xml_set_element_handler()— verarbeitet Element-Start-/End-Ereignisse.
Fazit
xml_set_unparsed_entity_decl_handler() ermöglicht es einem SAX-Parser, Sie über NDATA-Entitäten — Verweise auf externe Binärdaten — zu benachrichtigen, damit Sie deren Pfade und Notationen erfassen können, ohne sie als XML zu parsen. Registrieren Sie den Handler vor xml_parse(), erwarten Sie den Callback mit sechs Argumenten, und denken Sie daran, dass die Funktion nur für die prozedurale XML Parser-Erweiterung gilt, nicht für SimpleXML oder DOM.