W3docs

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

Параметры

ПараметрОписание
$parserXML-парсер для настройки. Создаётся с помощью 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_set_object() привязывает XML-парсер к объекту, чтобы зарегистрированные впоследствии имена обработчиков разрешались как методы этого объекта. Преимущество — инкапсуляция: состояние разбора хранится в свойствах объекта, а не в глобальных переменных, и весь парсер можно оформить в виде класса. Не забывайте вызывать функцию до регистрации обработчиков, а также помните, что она относится к устаревшему расширению Expat — для нового кода используйте SimpleXML или DOMDocument.

Практика

Практика
Каково назначение функции XML_Set_Object() в PHP?
Каково назначение функции XML_Set_Object() в PHP?
Was this page helpful?