Current Location: Home> Latest Articles> Debug the execution order and parameter passing of callback functions in xml_set_end_namespace_decl_handler

Debug the execution order and parameter passing of callback functions in xml_set_end_namespace_decl_handler

gitbox 2025-05-26

When using PHP to process XML, xml_set_end_namespace_decl_handler() is a tool specifically used to register processed callback functions. For many developers, understanding when its callback function is called , how parameters are passed , and how to debug is an important step to gain a deep understanding of the XML parser.

This article will take you through how to debug the execution order and parameters of this callback function.

Basic review

First, let's review the usage of xml_set_end_namespace_decl_handler() :

 $parser = xml_parser_create();

function endNamespaceHandler($parser, $prefix) {
    echo "End of namespace: $prefix\n";
}

xml_set_end_namespace_decl_handler($parser, 'endNamespaceHandler');

$data = <<<XML
<?xml version="1.0"?>
<root xmlns:h="http://gitbox.net/html">
    <h:body>
        <h:p>Hello World</h:p>
    </h:body>
</root>
XML;

xml_parse($parser, $data, true);
xml_parser_free($parser);

In the above code, when the end tags such as </h:p> or </h:body> are parsed, the end of the namespace declaration will trigger endNamespaceHandler() .

How are the parameters of the callback function passed?

In PHP, when you use xml_set_end_namespace_decl_handler($parser, $handler) to register a processor, the parser will call $handler when it encounters the end of the namespace and pass in two parameters:

  1. $parser : Current parser resource (resource)

  2. $prefix : namespace prefix (such as h )

For example:

 function endNamespaceHandler($parser, $prefix) {
    var_dump($parser);  // resource ID
    var_dump($prefix);  // e.g., "h"
}

You can use var_dump() , print_r() , debug_zval_dump() and other PHP debugging tools to view the specific content of these parameters.

How to debug the execution order of callback functions?

To debug the order in which the callback function is called, the following methods can be used:

1?? Add log output

Add echo or error_log() to the callback function and observe the execution order:

 function endNamespaceHandler($parser, $prefix) {
    echo "Callback triggered: prefix = $prefix\n";
}

You can also output timestamps:

 function endNamespaceHandler($parser, $prefix) {
    echo "[" . microtime(true) . "] End of namespace: $prefix\n";
}

2?? Use debug_backtrace()

If you want to know the call stack, you can directly type it in the callback:

 function endNamespaceHandler($parser, $prefix) {
    print_r(debug_backtrace());
}

This will show the current call context and help analyze who triggered the callback.

3?? Add multi-layer nested tests

Write more complex XML structures, such as multi-namespace nesting, and observe whether the callback function is called as expected:

 $data = <<<XML
<root xmlns:a="http://gitbox.net/a" xmlns:b="http://gitbox.net/b">
    <a:child>
        <b:subchild></b:subchild>
    </a:child>
</root>
XML;

This allows you to detect the order in which different namespace declarations are processed at the end.

Tips: How to avoid debugging chaos?

  • Make sure you only output logs during the debug phase and the production environment needs to be removed or closed.

  • If you use error_log() , remember to view the correct PHP error log file.

  • Note: The parser resource is of resource type, and cannot be spliced ​​directly with strings. You need to use var_dump() or other to view it.

Complete example: Debugging code

 $parser = xml_parser_create();

function endNamespaceHandler($parser, $prefix) {
    echo "[" . microtime(true) . "] End of namespace: $prefix\n";
    var_dump($parser);
    var_dump($prefix);
    print_r(debug_backtrace());
}

xml_set_end_namespace_decl_handler($parser, 'endNamespaceHandler');

$data = <<<XML
<?xml version="1.0"?>
<root xmlns:h="http://gitbox.net/html">
    <h:body>
        <h:p>Hello World</h:p>
    </h:body>
</root>
XML;

xml_parse($parser, $data, true);
xml_parser_free($parser);

Run the above code and you will see the timestamps, incoming parameters and call stacks in the output when each callback is triggered, which is very helpful for locating the problem or understanding the execution flow.