W3docs

xml_set_unparsed_entity_decl_handler()

Функция xml_set_unparsed_entity_decl_handler() в PHP устанавливает пользовательский обработчик для необработанных объявлений сущностей в XML

Функция xml_set_unparsed_entity_decl_handler() устанавливает пользовательский callback-обработчик для необработанных объявлений сущностей в XML-парсере. Она входит в расширение XML Parser (SAX) PHP и принадлежит к тому же семейству функций, что xml_set_element_handler() и xml_set_character_data_handler() — она не применима к SimpleXML или DOM.

Необработанная сущность — это сущность, содержимое которой XML-процессор не должен разбирать как XML. Как правило, это ссылка на внешние двоичные данные: изображение, PDF или аудиофайл. Такие сущности объявляются с ключевым словом NDATA и именем нотации, например:

<!ENTITY logo SYSTEM "logo.png" NDATA png>

Когда парсер встречает подобное объявление в DTD документа, он вызывает ваш обработчик, чтобы вы могли зафиксировать расположение ресурса, не пытаясь загрузить его как разметку.

Синтаксис

xml_set_unparsed_entity_decl_handler(
    XMLParser $parser,
    callable $handler
): true
ПараметрОписание
$parserXML-парсер, созданный с помощью xml_parser_create().
$handlerCallable-значение или строковое имя функции. Передайте пустую строку ("") для удаления текущего обработчика.

Возвращаемое значение: всегда возвращает true.

Примечание о PHP 8: начиная с PHP 8.0 парсер является объектом XMLParser, а не resource, однако код пишется одинаково — продолжайте обращаться со значением, возвращаемым xml_parser_create(), как с непрозрачным дескриптором.

Сигнатура callback-функции

Ваш обработчик вызывается с шестью аргументами в следующем порядке:

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()
): void

Пример: перехват объявлений необработанных сущностей

Создайте SAX-парсер с помощью xml_parser_create(), зарегистрируйте обработчик, затем передайте XML в 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);

Ожидаемый вывод:

Unparsed entity 'logo' -> logo.png (notation: png)
Unparsed entity 'manual' -> manual.pdf (notation: pdf)

Обработчик вызывается один раз для каждой сущности NDATA в DTD, предоставляя путь к файлу ($systemId) и нотацию. В реальном приложении эти ссылки сохраняются — например, для последующей загрузки ресурсов — а не выводятся в консоль.

Типичные ошибки

  • DTD должен содержать объявления NDATA. Обычная внутренняя сущность (<!ENTITY name "value">) является разбираемым текстом, поэтому данный обработчик её не видит. Только сущности, помеченные NDATA notation, являются «необработанными».
  • Регистрируйте обработчики до вызова xml_parse(). Как и все функции xml_set_*_handler(), эта не имеет никакого эффекта после начала разбора.
  • Освобождайте парсер с помощью xml_parser_free() по завершении работы, чтобы освободить ресурсы.
  • Не применяется в SimpleXML. Если вы читаете корректно сформированный XML и не нуждаетесь в реакции на объявления сущностей DTD, более простой парсер SimpleXML обычно является лучшим выбором.

Связанные функции

  • xml_parser_create() — создаёт SAX-парсер, к которому привязывается данный обработчик.
  • xml_set_notation_decl_handler() — обрабатывает объявления <!NOTATION ...>, на которые ссылаются необработанные сущности.
  • xml_set_external_entity_ref_handler() — обрабатывает ссылки на разбираемые внешние сущности.
  • xml_set_element_handler() — обрабатывает события начала и окончания элементов.

Заключение

xml_set_unparsed_entity_decl_handler() позволяет SAX-парсеру уведомлять вас о сущностях NDATA — ссылках на внешние двоичные данные — чтобы вы могли зафиксировать пути и нотации, не пытаясь разобрать их как XML. Регистрируйте обработчик до вызова xml_parse(), ожидайте callback с шестью аргументами и помните, что функция применяется только к процедурному расширению XML Parser, а не к SimpleXML или DOM.

Практика

Практика
Какова функция xml_set_unparsed_entity_decl_handler в PHP?
Какова функция xml_set_unparsed_entity_decl_handler в PHP?
Was this page helpful?