1--TEST--
2Test xml_set_element_handler handlers as trampoline callback
3--EXTENSIONS--
4xml
5--FILE--
6<?php
7
8class CustomXmlParser
9{
10    public function startHandler($XmlParser, $tag, $attr)
11    {
12        echo 'Method start handler: ', $tag, PHP_EOL;
13    }
14
15    public function endHandler($XmlParser, $tag)
16    {
17        echo 'Method end handler: ', $tag, PHP_EOL;
18    }
19}
20
21$customParser = new CustomXmlParser;
22
23class TrampolineTest {
24    public function __call(string $name, array $arguments) {
25        echo 'Trampoline for ', $name, PHP_EOL;
26        echo 'Tag: ', $arguments[1], PHP_EOL;
27    }
28}
29
30$o = new TrampolineTest();
31$startCallback = [$o, 'start_handler'];
32$endCallback = [$o, 'end_handler'];
33
34$xml = <<<HERE
35<a>
36  <b/>
37  <c>Text</c>
38</a>
39HERE;
40
41echo "Both handlers are trampolines:\n";
42$parser = xml_parser_create();
43xml_set_element_handler($parser, $startCallback, $endCallback);
44xml_parse($parser, $xml, true);
45xml_parser_free($parser);
46
47echo "\nStart handler is trampoline, end handler method string:\n";
48$parser = xml_parser_create();
49xml_set_object($parser, $customParser);
50xml_set_element_handler($parser, $startCallback, 'endHandler');
51xml_parse($parser, $xml, true);
52xml_parser_free($parser);
53
54echo "\nEnd handler is trampoline, start handler method string:\n";
55$parser = xml_parser_create();
56xml_set_object($parser, $customParser);
57xml_set_element_handler($parser, 'startHandler', $endCallback);
58xml_parse($parser, $xml, true);
59xml_parser_free($parser);
60
61?>
62--EXPECT--
63Both handlers are trampolines:
64Trampoline for start_handler
65Tag: A
66Trampoline for start_handler
67Tag: B
68Trampoline for end_handler
69Tag: B
70Trampoline for start_handler
71Tag: C
72Trampoline for end_handler
73Tag: C
74Trampoline for end_handler
75Tag: A
76
77Start handler is trampoline, end handler method string:
78Trampoline for start_handler
79Tag: A
80Trampoline for start_handler
81Tag: B
82Method end handler: B
83Trampoline for start_handler
84Tag: C
85Method end handler: C
86Method end handler: A
87
88End handler is trampoline, start handler method string:
89Method start handler: A
90Method start handler: B
91Trampoline for end_handler
92Tag: B
93Method start handler: C
94Trampoline for end_handler
95Tag: C
96Trampoline for end_handler
97Tag: A
98