W3docs

xml_set_object()

The xml_set_object() function is a PHP built-in function that sets the object to which the handler function should be applied for an XML parser. When parsing

The xml_set_object() function is a PHP built-in function that sets the object to which the handler functions of an XML parser should be applied. It is part of the legacy XML Parser extension. When you call it, the parser stops treating the names you pass to functions like xml_set_element_handler() as global functions and instead treats them as methods of the supplied object.

This page explains what the function does, its signature and parameters, a complete runnable example, the common gotchas, and how it relates to the rest of the XML Parser API.

Note: xml_set_object() belongs to the legacy XML Parser (Expat) extension and is deprecated as of PHP 8.4 — instead, pass a proper method callable (e.g. [$object, 'method']) directly to the xml_set_*_handler() functions. For new code, prefer SimpleXML or DOMDocument, which model the document as objects directly instead of using callback handlers.

Why use it

Without xml_set_object(), every handler you register must be a free-standing function (or a string-and-static-method pair). That makes it hard to share state between handlers — you end up reaching for globals.

By binding the parser to an object, you can:

  • Keep parsing state (a stack, a counter, the document being built) in object properties.
  • Register plain method names as handlers and have them resolve against that object.
  • Encapsulate an entire parser as a reusable class.

This is the idiomatic way to wrap the procedural Expat API in object-oriented code.

Syntax

xml_set_object(XMLParser $parser, object $object): bool

Parameters

ParameterDescription
$parserThe XML parser to configure. Create one with xml_parser_create().
$objectThe object whose methods will be used as handlers. Handler names registered afterward are resolved as methods of this object.

Return value

Returns true on success and false on failure. (Since PHP 8.0 $parser is an XMLParser instance; in PHP 7 and earlier it was a resource.)

Order matters: call xml_set_object() before registering handlers such as xml_set_element_handler() or xml_set_character_data_handler(). Handler names registered after the object is set are looked up on that object.

Example: binding a parser to an object

Suppose you have an XML string to parse with the XML Parser extension. Create a parser with xml_parser_create(), bind it to a handler object with xml_set_object(), then register the element handlers by method name:

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);

Output:

Start element: ROOT
Start element: ITEM
End element: ITEM
End element: ROOT

Element names arrive in upper case by default, because case folding is on unless you turn it off with xml_parser_set_option(). The first parameter of every handler is the parser itself, not the bound object — inside the method you already have $this, so that first argument is rarely used.

Example: accumulating state in the object

The real payoff is shared state. Here the object keeps a running depth so it can pretty-print the tree — something that would need a global without 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);

Output:

<A>
  <B>
    <C>
    </C>
  </B>
</A>

Common gotchas

  • Set the object first. Registering a handler before xml_set_object() resolves the name as a global function, not a method.
  • Handler names are strings. Pass the method name ("open"), not a callable array. The binding is what tells the parser to look the name up on the object.
  • Free the parser. Call xml_parser_free() when done (modern PHP also cleans up automatically).
  • It is legacy. New projects should use SimpleXML or DOMDocument instead.

Conclusion

xml_set_object() binds an XML parser to an object so that handler names you register afterward resolve as that object's methods. The benefit is encapsulation: parsing state lives in object properties instead of globals, and a whole parser can be packaged as a class. Remember to call it before registering handlers, and that the function is part of the legacy Expat extension — for new code, reach for SimpleXML or DOMDocument.

Practice

Practice
What is the purpose of the XML_Set_Object() function in PHP?
What is the purpose of the XML_Set_Object() function in PHP?
Was this page helpful?