Xml set unparsed entity decl handler: примеры (PHP)
xml_set_unparsed_entity_decl_handler(resource parser, callable handler): boolОписание функции xml_set_unparsed_entity_decl_handler
Функция xml_set_unparsed_entity_decl_handler() устанавливает обработчик для неразобранных объявлений сущностей в XML-документе. Она используется при работе с XML-парсером Expat в PHP, когда требуется обработка внешних или бинарных сущностей, которые парсер не может обработать самостоятельно.
- parser (resource) - ссылка на XML-парсер, созданный функцией
xml_parser_create() - handler (callable) - имя функции-обработчика, которая будет вызвана при обнаружении неразобранного объявления сущности
Обработчик принимает шесть параметров:
- parser - ссылка на XML-парсер
- entity_name - имя сущности
- base - базовый URL для разрешения системного идентификатора
- system_id - системный идентификатор
- public_id - публичный идентификатор
- notation_name - имя нотации
Функция возвращает логическое значение: true при успешной установке обработчика, false при ошибке.
Примеры использования xml_set_unparsed_entity_decl_handler
<?php
function unparsedHandler($parser, $entity_name, $base, $system_id, $public_id, $notation_name) {
echo "Обнаружена неразобранная сущность: $entity_name\n";
echo "Системный идентификатор: $system_id\n";
return true;
}
$xml_parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($xml_parser, 'unparsedHandler');
$xml = '<!DOCTYPE doc [
<!ENTITY logo SYSTEM "logo.png" NDATA png>
]>
<doc>Пример документа</doc>';
xml_parse($xml_parser, $xml);
xml_parser_free($xml_parser);
?>Обнаружена неразобранная сущность: logo Системный идентификатор: logo.png
<?php
$xml_parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($xml_parser,
function($parser, $entity, $base, $system, $public, $notation) {
file_put_contents('log.txt',
"[$entity] $system\n",
FILE_APPEND);
return true;
}
);
$xml = '<?xml version="1.0"?>
<!DOCTYPE article [
<!ENTITY photo SYSTEM "image.jpg" NDATA jpeg>
]>
<article>Текст статьи</article>';
xml_parse($xml_parser, $xml);
?>// Содержимое файла log.txt: [photo] image.jpg
Альтернативные функции в PHP
Класс DOMDocument предоставляет более современный и объектно-ориентированный подход к работе с XML. Он включает методы для работы с DTD и сущностями, автоматически обрабатывая многие аспекты разбора.
SimpleXML упрощает работу с XML, преобразуя элементы в объекты. Этот модуль не предоставляет прямого доступа к обработке объявлений сущностей, но подходит для большинства задач чтения XML.
Класс XMLReader реализует pull-парсер с низким потреблением памяти. Он предоставляет метод setParserProperty() для настройки обработки сущностей, но без детального контроля над неразобранными объявлениями.
Выбор зависит от требований: Expat подходит для потоковой обработки больших файлов, DOMDocument — для манипуляций с деревом, SimpleXML — для простого доступа к данным, XMLReader — для последовательного чтения.
Альтернативы в других языках программирования
import xml.sax
class UnparsedHandler(xml.sax.handler.EntityDeclHandler):
def unparsedEntityDecl(self, name, public_id, system_id, notation_name):
print(f"Неразобранная сущность: {name}")
print(f"Файл: {system_id}")
return
parser = xml.sax.make_parser()
parser.setEntityDeclHandler(UnparsedHandler())
parser.feed('''<!DOCTYPE doc [
<!ENTITY img SYSTEM "picture.png" NDATA png>
]>
<doc/>''')
Неразобранная сущность: img Файл: picture.png
const parser = new DOMParser();
const xmlString = `<!DOCTYPE doc [
<!ENTITY example SYSTEM "data.bin" NDATA bin>
]>
<doc>Содержимое</doc>`;
try {
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
console.log(xmlDoc.doctype.internalSubset);
} catch(e) {
console.error('Ошибка разбора:', e);
}<!ENTITY example SYSTEM "data.bin" NDATA bin>
import org.xml.sax.*;
public class CustomEntityResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) {
System.out.println("Сущность: " + systemId);
return null; // Парсер использует стандартное разрешение
}
}
// Использование:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setEntityResolver(new CustomEntityResolver());В отличие от PHP, Python и Java используют объектно-ориентированный интерфейс, а JavaScript работает через DOM API. PHP функция предоставляет более низкоуровневый контроль.
Типичные ошибки при использовании
<?php
$parser = xml_parser_create();
$result = xml_set_unparsed_entity_decl_handler($parser, 'nonexistent_function');
// $result === false
?><?php
$parser = xml_parser_create();
xml_parse($parser, '<root>');
// Следующая строка не будет иметь эффекта
xml_set_unparsed_entity_decl_handler($parser, 'handler');
?><?php
function handler($parser, $entity) {
// Нет return
}
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'handler');
// Может вызвать неопределенное поведение
?><?php
$result = xml_set_unparsed_entity_decl_handler(999, 'handler');
// Warning: xml_set_unparsed_entity_decl_handler() expects parameter 1 to be resource
?>Для избежания ошибок следует проверять существование функций-обработчиков, устанавливать обработчики до начала разбора и всегда возвращать логическое значение из callback-функции.
Изменения в версиях PHP
Тип параметра parser изменен с resource на XMLParser (объект). Функции Expat теперь используют объектно-ориентированный интерфейс.
<?php
// До PHP 8.0
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'handler');
// PHP 8.0 и выше
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'handler');
// Тип $parser теперь XMLParser, а не resource
?>Добавлена поддержка передача null в качестве обработчика для отключения ранее установленного обработчика.
<?php
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, null);
// Отключает обработчик неразобранных сущностей
?>В современных версиях PHP расширение XML (Expat) сохраняет обратную совместимость, но рекомендуется использовать новые объектно-ориентированные интерфейсы для будущей совместимости.
Расширенные примеры использования
<?php
class EntityHandler {
private $entities = [];
public function handle($parser, $name, $base, $system, $public, $notation) {
$this->entities[] = [
'name' => $name,
'system' => $system,
'public' => $public,
'notation' => $notation,
'base' => $base
];
if ($notation === 'png') {
$this->processImage($system);
}
return true;
}
private function processImage($path) {
// Логика обработки изображений
echo "Обработка изображения: $path\n";
}
public function getStats() {
return count($this->entities);
}
}
$handler = new EntityHandler();
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, [$handler, 'handle']);
$xml = '<!DOCTYPE data [
<!ENTITY img1 SYSTEM "1.png" NDATA png>
<!ENTITY img2 SYSTEM "2.jpg" NDATA jpeg>
<!ENTITY sound SYSTEM "audio.mp3" NDATA mp3>
]>
<data/>';
xml_parse($parser, $xml);
echo "Найдено сущностей: " . $handler->getStats();
?>Обработка изображения: 1.png Найдено сущностей: 3
<?php
function validateEntities($parser, $name, $base, $system, $public, $notation) {
$allowed = ['png', 'jpg', 'gif'];
if (!in_array($notation, $allowed)) {
xml_parser_get_option($parser, XML_OPTION_CASE_FOLDING) ?
trigger_error("Недопустимая нотация: $notation", E_USER_WARNING) : null;
return false;
}
if (!filter_var($system, FILTER_VALIDATE_URL) && !file_exists($system)) {
trigger_error("Недоступный ресурс: $system", E_USER_NOTICE);
}
return true;
}
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'validateEntities');
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
$xml = '<!DOCTYPE doc [
<!ENTITY secure SYSTEM "https://example.com/image.png" NDATA png>
<!ENTITY invalid SYSTEM "script.exe" NDATA exe>
]>
<doc/>';
xml_parse($parser, $xml);
?>Warning: Недопустимая нотация: exe in ...
<?php
$cache = [];
function cacheHandler($parser, $name, $base, $system, $public, $notation) {
global $cache;
$key = md5($system);
if (!isset($cache[$key])) {
$content = @file_get_contents($system);
$cache[$key] = $content !== false ? $content : null;
echo "Загружено в кэш: $system\n";
} else {
echo "Использован кэш для: $system\n";
}
return true;
}
$parser = xml_parser_create();
xml_set_unparsed_entity_decl_handler($parser, 'cacheHandler');
$xml = '<!DOCTYPE data [
<!ENTITY bg SYSTEM "background.png" NDATA png>
<!ENTITY logo SYSTEM "logo.png" NDATA png>
<!ENTITY bg2 SYSTEM "background.png" NDATA png>
]>
<data/>';
xml_parse($parser, $xml);
?>Загружено в кэш: background.png Загружено в кэш: logo.png Использован кэш для: background.png
<?php
function loggingHandler($parser, $name, $base, $system, $public, $notation) {
$logEntry = sprintf(
"[%s] Entity: %s, System: %s, Notation: %s\n",
date('Y-m-d H:i:s'),
$name,
$system,
$notation
);
// Запись в несколько мест
error_log($logEntry, 3, 'entities.log');
if (strpos($system, 'http') === 0) {
error_log($logEntry, 3, 'external_entities.log');
}
return true;
}
$parser = xml_parser_create();
xml_set_object($parser, new stdClass());
xml_set_unparsed_entity_decl_handler($parser, 'loggingHandler');
$xml = '<!DOCTYPE doc [
<!ENTITY local SYSTEM "file.bin" NDATA binary>
<!ENTITY remote SYSTEM "https://site.com/resource" NDATA data>
]>
<doc/>';
xml_parse($parser, $xml);
?>// Содержимое entities.log: [2024-01-15 10:30:00] Entity: local, System: file.bin, Notation: binary [2024-01-15 10:30:00] Entity: remote, System: https://site.com/resource, Notation: data
PHP xml_set_unparsed_entity_decl_handler function comments
- Php xml set unparsed entity decl handler - аргументы и возвращаемое значение
- Функция php xml_set_unparsed_entity_decl_handler - описание
- xml set unparsed entity decl handler - примеры
- xml set unparsed entity decl handler - похожие методы на php
- xml_set_unparsed_entity_decl_handler на js, python, mysql
- xml set unparsed entity decl handler изменения php
- Примеры xml_set_unparsed_entity_decl_handler на php