W3docs

xml_set_external_entity_ref_handler()

La fonction xml_set_external_entity_ref_handler() enregistre un callback pour gérer les références d'entités externes dans un parseur XML PHP.

La fonction xml_set_external_entity_ref_handler() est une fonction PHP intégrée qui enregistre un callback défini par l'utilisateur pour gérer les références d'entités externes dans un parseur XML SAX (Expat) classique. Une entité externe est une référence dans un document XML — déclarée avec <!ENTITY name SYSTEM "uri"> — qui pointe vers un contenu stocké en dehors du document. Lorsque le parseur rencontre une telle référence pendant l'analyse, il invoque votre callback afin que vous puissiez décider quoi en faire : l'ignorer, charger des données approuvées depuis une base de données, ou la rejeter dans le cadre d'une validation de sécurité.

Cette page couvre la syntaxe de la fonction, les paramètres que PHP passe à votre callback, sa valeur de retour, un exemple complet et exécutable, ainsi que les mises en garde de sécurité et de dépréciation à connaître avant de l'utiliser.

Syntaxe

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

Paramètres

ParamètreDescription
$parserLa ressource de parseur XML créée avec xml_parser_create(). Le handler est attaché à ce parseur spécifique.
$handlerLe callback à exécuter pour chaque référence d'entité externe. Il peut s'agir du nom d'une fonction (sous forme de chaîne), ou — lorsque xml_set_object() a été utilisé — d'un nom de méthode. Passer une chaîne vide supprime le handler.

Valeur de retour

Retourne true en cas de succès, ou false en cas d'échec (par exemple, si $parser n'est pas un parseur valide).

La signature du callback

PHP appelle votre handler avec cinq arguments, dans cet ordre :

handler(XMLParser $parser, string $open_entity_names, string $base, string $system_id, ?string $public_id): int
  • $open_entity_names — une liste séparée par des espaces des entités actuellement ouvertes, utilisée pour détecter la récursion.
  • $base — l'URI de base pour résoudre $system_id (généralement une chaîne vide).
  • $system_id — l'identifiant système (l'URI SYSTEM "...") de l'entité externe.
  • $public_id — l'identifiant public, ou null si aucun n'a été déclaré.

Votre callback doit retourner une valeur non nulle (vraie) pour que l'analyse continue. Retourner 0, false ou rien interrompt l'analyse avec une erreur XML_ERROR_EXTERNAL_ENTITY_HANDLING.

Exemples d'utilisation

Voici un exemple pratique d'utilisation de xml_set_external_entity_ref_handler() en PHP.

Exemple : Définir une fonction de gestion des références d'entités externes

Supposons que vous ayez un document XML qui référence une entité externe et que vous souhaitiez inspecter cette référence lors de l'analyse du document. Vous créez un parseur avec xml_parser_create(), enregistrez le handler, analysez les données avec xml_parse() et libérez le parseur avec xml_parser_free() :

Définir une fonction de gestion des références d'entités externes en 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);

Le handler se déclenche une fois pour la référence &ext; et affiche :

External entity referenced: data.xml

Étant donné que le callback se contente d'afficher l'identifiant système et retourne 1, le parseur est invité à continuer sans récupérer réellement data.xml — ce qui est exactement le comportement sécurisé par défaut souhaité.

Pourquoi le handler peut ne jamais se déclencher

Dans la plupart des versions modernes de PHP, le chargement des entités externes est désactivé au niveau de libxml, de sorte que le parseur ignore silencieusement les références d'entités et votre callback n'est jamais appelé. Il s'agit d'un renforcement intentionnel. Si vous devez l'activer, vous le contrôlez globalement avec libxml_disable_entity_loader() — mais pour tout ce qui n'est pas une entrée fiable et contrôlée, vous devriez laisser le chargement désactivé.

⚠️ Avertissement de sécurité : La gestion des entités externes est un vecteur classique d'attaques XML External Entity (XXE), qui peuvent exposer des fichiers locaux (file:///etc/passwd), déclencher des requêtes côté serveur, ou provoquer un déni de service. Ne résolvez jamais $system_id pour récupérer des URI arbitraires ou des chemins locaux provenant d'entrées non fiables. Pour une analyse sensible à la sécurité, préférez des bibliothèques modernes telles que DOMDocument ou XMLReader avec le chargement des entités désactivé.

Note de dépréciation : Depuis PHP 8.4, passer une chaîne non-callable comme handler est déprécié — un nom de fonction simple qui existe réellement fonctionne encore, mais une chaîne non résolue génère désormais un avertissement de dépréciation. Pour un code compatible avec les futures versions, passez un callable réel tel qu'une Closure ou un tableau [$object, 'method']. L'extension SAX Expat classique est en mode maintenance — le nouveau code devrait privilégier XMLReader ou DOMDocument.

Conclusion

Dans cet article, nous avons couvert la fonction PHP xml_set_external_entity_ref_handler() : sa syntaxe, les cinq arguments que PHP passe à votre callback, pourquoi le callback doit retourner une valeur non nulle pour maintenir l'analyse en cours, et un exemple complet et exécutable. Nous avons également signalé les deux points qui posent problème — le handler ne se déclenche souvent jamais car le chargement des entités externes est désactivé par défaut, et le traitement d'entrées non fiables via cette fonction ouvre la porte aux attaques XXE. Utilisez-la uniquement avec des entrées fiables, préférez un callable réel à un nom de chaîne sur PHP 8.4+, et tournez-vous vers XMLReader ou DOMDocument pour tout ce qui est sensible à la sécurité.

Pour les handlers SAX associés, voir xml_set_element_handler() et xml_set_object().

Pratique

Pratique
Quelle fonction PHP est utilisée pour créer une référence d'entité externe pour les fichiers XML ?
Quelle fonction PHP est utilisée pour créer une référence d'entité externe pour les fichiers XML ?
Was this page helpful?