Skip to content

Commit 6468578

Browse files
committed
Allow to call XMLReader::open() and ::XML() statically
The implementation of `XMLReader::open()` and `XMLReader::XML()` still supports calling the methods statically and non-statically. However, as of PHP 8.0.0, calling these methods statically is not allowed, because they are not declared as static methods. Since we consider it to be cleaner to call these methods statically, but had deprecated to call them statically, we properly support both variants. We implement support for static and non-static calls by overloading, so that non-static calls have access to the `$this` pointer.
1 parent 4963701 commit 6468578

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

ext/xmlreader/php_xmlreader.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ static zend_object_handlers xmlreader_object_handlers;
3737

3838
static HashTable xmlreader_prop_handlers;
3939

40+
static zend_internal_function xmlreader_open_fn;
41+
static zend_internal_function xmlreader_xml_fn;
42+
4043
typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
4144
typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
4245
typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr reader);
@@ -181,6 +184,25 @@ zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *val
181184
}
182185
/* }}} */
183186

187+
/* {{{ */
188+
static zend_function *xmlreader_get_method(zend_object **obj, zend_string *name, const zval *key)
189+
{
190+
if (ZSTR_LEN(name) == sizeof("open") - 1
191+
&& (ZSTR_VAL(name)[0] == 'o' || ZSTR_VAL(name)[0] == 'O')
192+
&& (ZSTR_VAL(name)[1] == 'p' || ZSTR_VAL(name)[1] == 'P')
193+
&& (ZSTR_VAL(name)[2] == 'e' || ZSTR_VAL(name)[2] == 'E')
194+
&& (ZSTR_VAL(name)[3] == 'n' || ZSTR_VAL(name)[3] == 'N')) {
195+
return (zend_function*)&xmlreader_open_fn;
196+
} else if (ZSTR_LEN(name) == sizeof("xml") - 1
197+
&& (ZSTR_VAL(name)[0] == 'x' || ZSTR_VAL(name)[0] == 'X')
198+
&& (ZSTR_VAL(name)[1] == 'm' || ZSTR_VAL(name)[1] == 'M')
199+
&& (ZSTR_VAL(name)[2] == 'l' || ZSTR_VAL(name)[2] == 'L')) {
200+
return (zend_function*)&xmlreader_xml_fn;
201+
}
202+
return zend_std_get_method(obj, name, key);;
203+
}
204+
/* }}} */
205+
184206
/* {{{ _xmlreader_get_valid_file_path */
185207
/* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a
186208
common function in libxml extension as code is common to a few xml extensions */
@@ -1145,7 +1167,7 @@ static const zend_function_entry xmlreader_functions[] /* {{{ */ = {
11451167
PHP_ME(xmlreader, moveToElement, arginfo_class_XMLReader_moveToElement, ZEND_ACC_PUBLIC)
11461168
PHP_ME(xmlreader, moveToFirstAttribute, arginfo_class_XMLReader_moveToFirstAttribute, ZEND_ACC_PUBLIC)
11471169
PHP_ME(xmlreader, moveToNextAttribute, arginfo_class_XMLReader_moveToNextAttribute, ZEND_ACC_PUBLIC)
1148-
PHP_ME(xmlreader, open, arginfo_class_XMLReader_open, ZEND_ACC_PUBLIC)
1170+
PHP_ME(xmlreader, open, arginfo_class_XMLReader_open, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
11491171
PHP_ME(xmlreader, read, arginfo_class_XMLReader_read, ZEND_ACC_PUBLIC)
11501172
PHP_ME(xmlreader, next, arginfo_class_XMLReader_next, ZEND_ACC_PUBLIC)
11511173
PHP_ME(xmlreader, readInnerXml, arginfo_class_XMLReader_readInnerXml, ZEND_ACC_PUBLIC)
@@ -1158,7 +1180,7 @@ static const zend_function_entry xmlreader_functions[] /* {{{ */ = {
11581180
PHP_ME(xmlreader, setParserProperty, arginfo_class_XMLReader_setParserProperty, ZEND_ACC_PUBLIC)
11591181
PHP_ME(xmlreader, setRelaxNGSchema, arginfo_class_XMLReader_setRelaxNGSchema, ZEND_ACC_PUBLIC)
11601182
PHP_ME(xmlreader, setRelaxNGSchemaSource, arginfo_class_XMLReader_setRelaxNGSchemaSource, ZEND_ACC_PUBLIC)
1161-
PHP_ME(xmlreader, XML, arginfo_class_XMLReader_XML, ZEND_ACC_PUBLIC)
1183+
PHP_ME(xmlreader, XML, arginfo_class_XMLReader_XML, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
11621184
PHP_ME(xmlreader, expand, arginfo_class_XMLReader_expand, ZEND_ACC_PUBLIC)
11631185
PHP_FE_END
11641186
}; /* }}} */
@@ -1177,12 +1199,18 @@ PHP_MINIT_FUNCTION(xmlreader)
11771199
xmlreader_object_handlers.read_property = xmlreader_read_property;
11781200
xmlreader_object_handlers.write_property = xmlreader_write_property;
11791201
xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
1202+
xmlreader_object_handlers.get_method = xmlreader_get_method;
11801203
xmlreader_object_handlers.clone_obj = NULL;
11811204

11821205
INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions);
11831206
ce.create_object = xmlreader_objects_new;
11841207
xmlreader_class_entry = zend_register_internal_class(&ce);
11851208

1209+
memcpy(&xmlreader_open_fn, zend_hash_str_find_ptr(&xmlreader_class_entry->function_table, "open", sizeof("open")-1), sizeof(zend_internal_function));
1210+
xmlreader_open_fn.fn_flags &= ~ZEND_ACC_STATIC;
1211+
memcpy(&xmlreader_xml_fn, zend_hash_str_find_ptr(&xmlreader_class_entry->function_table, "xml", sizeof("xml")-1), sizeof(zend_internal_function));
1212+
xmlreader_xml_fn.fn_flags &= ~ZEND_ACC_STATIC;
1213+
11861214
zend_hash_init(&xmlreader_prop_handlers, 0, NULL, php_xmlreader_free_prop_handler, 1);
11871215
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG);
11881216
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING);

ext/xmlreader/tests/static.phpt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Calling XMLReader::open() and ::XML() statically
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("xmlreader")) die('skip xmlreader extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$filename = __DIR__ . '/static.xml';
10+
11+
$xmlstring = '<?xml version="1.0" encoding="UTF-8"?>
12+
<books></books>';
13+
file_put_contents($filename, $xmlstring);
14+
15+
$reader = XMLReader::open($filename);
16+
while ($reader->read()) {
17+
echo $reader->name, "\n";
18+
}
19+
20+
$reader = XMLReader::XML($xmlstring);
21+
while ($reader->read()) {
22+
echo $reader->name, "\n";
23+
}
24+
?>
25+
--EXPECTF--
26+
books
27+
books
28+
books
29+
books
30+
--CLEAN--
31+
<?php
32+
unlink(__DIR__ . '/static.xml');
33+
?>

0 commit comments

Comments
 (0)