xml_set_unparsed_entity_decl_handler()
A função xml_set_unparsed_entity_decl_handler() define um callback personalizado como handler para declarações de entidades não analisadas no PHP
A função xml_set_unparsed_entity_decl_handler() define um callback personalizado como handler para declarações de entidades não analisadas em um parser XML. Ela pertence à extensão XML Parser (SAX) do PHP e faz parte da mesma família que xml_set_element_handler() e xml_set_character_data_handler() — não se aplica ao SimpleXML ou DOM.
Uma entidade não analisada é uma entidade cujo conteúdo o processador XML não deve analisar como XML — tipicamente uma referência a dados binários externos, como uma imagem, PDF ou arquivo de áudio. Ela é declarada com a palavra-chave NDATA seguida de um nome de notação, por exemplo:
<!ENTITY logo SYSTEM "logo.png" NDATA png>Quando o parser encontra tal declaração no DTD do documento, ele invoca seu handler para que você possa registrar onde o recurso está localizado em vez de tentar carregá-lo como marcação.
Sintaxe
xml_set_unparsed_entity_decl_handler(
XMLParser $parser,
callable $handler
): true| Parâmetro | Descrição |
|---|---|
$parser | O parser XML criado com xml_parser_create(). |
$handler | Um callable, ou o nome em string de uma função. Passe uma string vazia ("") para remover o handler atual. |
Valor de retorno: sempre retorna true.
Nota sobre PHP 8: desde o PHP 8.0, o parser é um objeto
XMLParserem vez de umresource, mas o código que você escreve é idêntico — continue tratando o valor retornado porxml_parser_create()como um identificador opaco.
A assinatura do callback
Seu handler é chamado com seis argumentos, nesta ordem:
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()
): voidExemplo: capturando declarações de entidades não analisadas
Crie um parser SAX com xml_parser_create(), registre o handler e, em seguida, alimente o XML em 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);Saída esperada:
Unparsed entity 'logo' -> logo.png (notation: png)
Unparsed entity 'manual' -> manual.pdf (notation: pdf)O handler é acionado uma vez por entidade NDATA no DTD, fornecendo o caminho do arquivo ($systemId) e a notação. Uma aplicação real armazenaria essas referências — por exemplo, para baixar os recursos posteriormente — em vez de exibi-las com echo.
Armadilhas comuns
- O DTD deve conter declarações
NDATA. Uma entidade interna normal (<!ENTITY name "value">) é texto analisado, portanto este handler nunca a verá. Apenas entidades marcadas comNDATA notationsão "não analisadas". - Registre os handlers antes de chamar
xml_parse(). Como qualquer funçãoxml_set_*_handler(), esta não tem efeito depois que a análise foi iniciada. - Libere o parser com
xml_parser_free()quando terminar para liberar recursos. - Não funciona no SimpleXML. Se você está lendo XML bem formado e não precisa reagir às declarações de entidades do DTD, o parser SimpleXML mais simples geralmente é a melhor escolha.
Funções relacionadas
xml_parser_create()— cria o parser SAX ao qual este handler é vinculado.xml_set_notation_decl_handler()— trata as declarações<!NOTATION ...>referenciadas por entidades não analisadas.xml_set_external_entity_ref_handler()— trata referências a entidades externas analisadas.xml_set_element_handler()— trata eventos de início/fim de elementos.
Conclusão
xml_set_unparsed_entity_decl_handler() permite que um parser SAX notifique você sobre entidades NDATA — referências a dados binários externos — para que você possa capturar seus caminhos e notações sem tentar analisá-los como XML. Registre o handler antes de xml_parse(), espere o callback com seis argumentos e lembre-se de que a função se aplica apenas à extensão procedural XML Parser, não ao SimpleXML ou DOM.