xml_set_object()
Функция xml_set_object() в PHP привязывает XML-парсер к объекту, методы которого будут использоваться в качестве обработчиков при разборе XML.
Функция xml_set_object() — это встроенная функция PHP, которая устанавливает объект, к методам которого будут применяться функции-обработчики XML-парсера. Она входит в состав устаревшего расширения XML Parser. После её вызова парсер перестаёт воспринимать имена, передаваемые таким функциям, как xml_set_element_handler(), как глобальные функции и вместо этого рассматривает их как методы указанного объекта.
На этой странице описывается назначение функции, её сигнатура и параметры, полный рабочий пример, типичные подводные камни, а также связь с остальными функциями API XML Parser.
Примечание:
xml_set_object()относится к устаревшему расширению XML Parser (Expat) и объявлена устаревшей начиная с PHP 8.4 — вместо неё следует передавать корректный вызываемый метод (например,[$object, 'method']) непосредственно в функцииxml_set_*_handler(). В новом коде предпочтительнее использовать SimpleXML или DOMDocument, которые моделируют документ как объекты напрямую, без использования обработчиков-коллбэков.
Зачем её использовать
Без xml_set_object() каждый регистрируемый обработчик должен быть самостоятельной функцией (или парой из строки и статического метода). Это затрудняет совместное использование состояния между обработчиками — приходится прибегать к глобальным переменным.
Привязав парсер к объекту, вы можете:
- Хранить состояние разбора (стек, счётчик, строящийся документ) в свойствах объекта.
- Регистрировать простые имена методов в качестве обработчиков и разрешать их на этом объекте.
- Инкапсулировать весь парсер в виде переиспользуемого класса.
Это идиоматический способ обернуть процедурный Expat API в объектно-ориентированный код.
Синтаксис
xml_set_object(XMLParser $parser, object $object): boolПараметры
| Параметр | Описание |
|---|---|
$parser | XML-парсер для настройки. Создаётся с помощью xml_parser_create(). |
$object | Объект, методы которого будут использоваться в качестве обработчиков. Имена обработчиков, зарегистрированных после вызова функции, разрешаются как методы этого объекта. |
Возвращаемое значение
Возвращает true в случае успеха и false в случае ошибки. (Начиная с PHP 8.0 параметр $parser является экземпляром XMLParser; в PHP 7 и ниже это был ресурс.)
Порядок важен: вызывайте
xml_set_object()до регистрации обработчиков, таких какxml_set_element_handler()илиxml_set_character_data_handler(). Имена обработчиков, зарегистрированных после установки объекта, будут разрешены именно на этом объекте.
Пример: привязка парсера к объекту
Предположим, у вас есть XML-строка для разбора с помощью расширения XML Parser. Создайте парсер с xml_parser_create(), привяжите его к объекту-обработчику с помощью xml_set_object(), а затем зарегистрируйте обработчики элементов, передав имена методов:
class MyHandler {
function startElement($parser, $name, $attribs) {
echo "Start element: $name\n";
}
function endElement($parser, $name) {
echo "End element: $name\n";
}
}
$handler = new MyHandler();
$xmlParser = xml_parser_create();
xml_set_object($xmlParser, $handler);
xml_set_element_handler($xmlParser, "startElement", "endElement");
$xmlData = '<root><item>Test</item></root>';
xml_parse($xmlParser, $xmlData, true);
xml_parser_free($xmlParser);Вывод:
Start element: ROOT
Start element: ITEM
End element: ITEM
End element: ROOTПо умолчанию имена элементов поступают в верхнем регистре, поскольку свёртка регистра включена, если её не отключить с помощью xml_parser_set_option(). Первый параметр каждого обработчика — сам парсер, а не привязанный объект — внутри метода у вас уже есть $this, поэтому первый аргумент используется редко.
Пример: накопление состояния в объекте
Главное преимущество — совместное состояние. Здесь объект ведёт текущую глубину вложенности для красивого вывода дерева — то, для чего без xml_set_object() потребовалась бы глобальная переменная:
class TreePrinter {
private int $depth = 0;
function open($parser, $name) {
echo str_repeat(" ", $this->depth) . "<$name>\n";
$this->depth++;
}
function close($parser, $name) {
$this->depth--;
echo str_repeat(" ", $this->depth) . "</$name>\n";
}
}
$parser = xml_parser_create();
xml_set_object($parser, new TreePrinter());
xml_set_element_handler($parser, "open", "close");
xml_parse($parser, "<a><b><c/></b></a>", true);
xml_parser_free($parser);Вывод:
<A>
<B>
<C>
</C>
</B>
</A>Типичные подводные камни
- Устанавливайте объект первым. Если зарегистрировать обработчик до вызова
xml_set_object(), имя будет разрешено как глобальная функция, а не как метод. - Имена обработчиков — строки. Передавайте имя метода (
"open"), а не вызываемый массив. Именно привязка сообщает парсеру, что имя нужно искать на объекте. - Освобождайте парсер. Вызывайте
xml_parser_free()по завершении (современный PHP также выполняет очистку автоматически). - Это устаревший API. В новых проектах следует использовать SimpleXML или DOMDocument.
Связанные функции
xml_parser_create()— создание парсера для привязки.xml_set_element_handler()— регистрация обработчиков открывающих и закрывающих тегов.xml_set_character_data_handler()— обработка текста между тегами.xml_parse()— передача XML парсеру.xml_parser_free()— освобождение парсера.
Заключение
xml_set_object() привязывает XML-парсер к объекту, чтобы зарегистрированные впоследствии имена обработчиков разрешались как методы этого объекта. Преимущество — инкапсуляция: состояние разбора хранится в свойствах объекта, а не в глобальных переменных, и весь парсер можно оформить в виде класса. Не забывайте вызывать функцию до регистрации обработчиков, а также помните, что она относится к устаревшему расширению Expat — для нового кода используйте SimpleXML или DOMDocument.