W3docs

xml_set_external_entity_ref_handler()

Die Funktion xml_set_external_entity_ref_handler() registriert einen Callback für externe Entitätsreferenzen in einem PHP XML-Parser.

Die Funktion xml_set_external_entity_ref_handler() ist eine in PHP eingebaute Funktion, die einen benutzerdefinierten Callback registriert, um externe Entitätsreferenzen in einem veralteten SAX (Expat) XML-Parser zu verarbeiten. Eine externe Entität ist eine Referenz in einem XML-Dokument — deklariert mit <!ENTITY name SYSTEM "uri"> — die auf Inhalte verweist, die außerhalb des Dokuments gespeichert sind. Wenn der Parser während des Parsens auf eine solche Referenz trifft, ruft er Ihren Callback auf, damit Sie entscheiden können, was damit geschehen soll: ignorieren, genehmigte Daten aus einer Datenbank laden oder sie als Teil der Sicherheitsvalidierung ablehnen.

Diese Seite behandelt die Syntax der Funktion, die Parameter, die PHP an Ihren Callback übergibt, den Rückgabewert, ein vollständiges ausführbares Beispiel sowie Sicherheits- und Deprecation-Hinweise, die Sie vor der Verwendung kennen sollten.

Syntax

xml_set_external_entity_ref_handler(XMLParser $parser, callable $handler): bool

Parameter

ParameterBeschreibung
$parserDie XML-Parser-Ressource, die mit xml_parser_create() erstellt wurde. Der Handler wird an diesen spezifischen Parser gebunden.
$handlerDer Callback, der bei jeder externen Entitätsreferenz ausgeführt wird. Er kann der Name einer Funktion (als string) sein oder — wenn xml_set_object() verwendet wurde — ein Methodenname. Das Übergeben eines leeren Strings hebt den Handler auf.

Rückgabewert

Gibt true bei Erfolg zurück oder false bei einem Fehler (zum Beispiel, wenn $parser kein gültiger Parser ist).

Die Callback-Signatur

PHP ruft Ihren Handler mit fünf Argumenten in dieser Reihenfolge auf:

handler(XMLParser $parser, string $open_entity_names, string $base, string $system_id, ?string $public_id): int
  • $open_entity_names — eine leerzeichen-getrennte Liste der aktuell geöffneten Entitäten, verwendet zur Erkennung von Rekursion.
  • $base — der Basis-URI zur Auflösung von $system_id (normalerweise ein leerer string).
  • $system_id — der Systembezeichner (der SYSTEM "..." URI) der externen Entität.
  • $public_id — der öffentliche Bezeichner oder null, wenn keiner deklariert wurde.

Ihr Callback muss einen Wert ungleich null (truthy) zurückgeben, damit das Parsing fortgesetzt wird. Die Rückgabe von 0, false oder nichts bricht das Parsing mit einem XML_ERROR_EXTERNAL_ENTITY_HANDLING-Fehler ab.

Verwendungsbeispiele

Schauen wir uns ein praktisches Beispiel der Verwendung von xml_set_external_entity_ref_handler() in PHP an.

Beispiel: Festlegen einer Handlerfunktion für externe Entitätsreferenzen

Angenommen, Sie haben ein XML-Dokument, das auf eine externe Entität verweist, und möchten diese Referenz beim Parsen des Dokuments überprüfen. Sie erstellen einen Parser mit xml_parser_create(), registrieren den Handler, parsen die Daten mit xml_parse() und geben den Parser mit xml_parser_free() frei:

Festlegen einer Handlerfunktion für externe Entitätsreferenzen in PHP

function handle_external_entity_ref($parser, $open_entity_names, $base, $system_id, $public_id) {
    // Inspect — but do NOT blindly load — the external entity.
    echo "External entity referenced: {$system_id}\n";

    // Return a non-zero value so parsing continues.
    return 1;
}

$xml_parser = xml_parser_create();
xml_set_external_entity_ref_handler($xml_parser, "handle_external_entity_ref");

$xml_data = '<?xml version="1.0"?>
<!DOCTYPE root [
  <!ENTITY ext SYSTEM "data.xml">
]>
<root>&ext;</root>';

xml_parse($xml_parser, $xml_data, true);
xml_parser_free($xml_parser);

Der Handler wird einmal für die &ext;-Referenz ausgelöst und gibt aus:

External entity referenced: data.xml

Da der Callback nur den Systembezeichner ausgibt und 1 zurückgibt, wird dem Parser mitgeteilt, ohne das tatsächliche Abrufen von data.xml fortzufahren — was genau der sichere Standardfall ist, den Sie anstreben.

Warum der Handler möglicherweise nie ausgelöst wird

In den meisten modernen PHP-Builds ist das Laden externer Entitäten auf libxml-Ebene deaktiviert, sodass der Parser Entitätsreferenzen stillschweigend ignoriert und Ihr Callback niemals aufgerufen wird. Dies ist eine bewusste Sicherheitsmaßnahme. Wenn Sie sich dennoch dafür entscheiden müssen, kontrollieren Sie es global mit libxml_disable_entity_loader() — aber für alles außer vertrauenswürdigen, kontrollierten Eingaben sollten Sie das Laden deaktiviert lassen.

Sicherheitswarnung: Die Verarbeitung externer Entitäten ist ein klassischer Angriffsvektor für XML External Entity (XXE)-Angriffe, die lokale Dateien (file:///etc/passwd) preisgeben, serverseitige Anfragen auslösen oder einen Denial-of-Service verursachen können. Lösen Sie $system_id niemals auf, um beliebige URIs oder lokale Pfade aus nicht vertrauenswürdigen Eingaben abzurufen. Für sicherheitskritisches Parsing bevorzugen Sie moderne Bibliotheken wie DOMDocument oder XMLReader mit deaktiviertem Entitätsladen.

Deprecation-Hinweis: Ab PHP 8.4 ist das Übergeben eines nicht aufrufbaren Strings als Handler deprecated — ein einfacher Funktionsname, der tatsächlich existiert, funktioniert noch, aber ein nicht aufgelöster string löst nun eine Deprecation-Meldung aus. Für zukunftssicheren Code übergeben Sie ein echtes callable wie eine Closure oder ein [$object, 'method']-Array. Die veraltete Expat-SAX-Erweiterung befindet sich insgesamt im Wartungsmodus — neuer Code sollte XMLReader oder DOMDocument bevorzugen.

Fazit

In diesem Artikel haben wir die PHP-Funktion xml_set_external_entity_ref_handler() behandelt: ihre Syntax, die fünf Argumente, die PHP an Ihren Callback übergibt, warum der Callback einen Wert ungleich null zurückgeben muss, um das Parsing am Laufen zu halten, sowie ein vollständiges ausführbares Beispiel. Wir haben auch auf die zwei häufigsten Fallstricke hingewiesen — der Handler wird oft nie ausgelöst, weil das Laden externer Entitäten standardmäßig deaktiviert ist, und das Routing nicht vertrauenswürdiger Eingaben durch diesen Handler öffnet die Tür für XXE-Angriffe. Verwenden Sie ihn nur mit vertrauenswürdigen Eingaben, bevorzugen Sie ein echtes callable gegenüber einem string-Namen auf PHP 8.4+ und greifen Sie für sicherheitskritische Aufgaben auf XMLReader oder DOMDocument zurück.

Für verwandte SAX-Handler siehe xml_set_element_handler() und xml_set_object().

Übungen

Übung
Welche Funktion in PHP wird verwendet, um eine externe Entitätsreferenz für XML-Dateien zu erstellen?
Welche Funktion in PHP wird verwendet, um eine externe Entitätsreferenz für XML-Dateien zu erstellen?
Was this page helpful?