From ca0a70ec72caa165e704401e26f5f812f0db106e Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 11 Oct 2019 16:41:07 +0200 Subject: [PATCH] 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. --- ext/xmlreader/php_xmlreader.c | 32 ++++++++++++++++++++++++++++++-- ext/xmlreader/tests/static.phpt | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 ext/xmlreader/tests/static.phpt diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index d1c683ed00d1..90f5bfc14fa1 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -37,6 +37,9 @@ static zend_object_handlers xmlreader_object_handlers; static HashTable xmlreader_prop_handlers; +static zend_internal_function xmlreader_open_fn; +static zend_internal_function xmlreader_xml_fn; + typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader); typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader); 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 } /* }}} */ +/* {{{ */ +static zend_function *xmlreader_get_method(zend_object **obj, zend_string *name, const zval *key) +{ + if (ZSTR_LEN(name) == sizeof("open") - 1 + && (ZSTR_VAL(name)[0] == 'o' || ZSTR_VAL(name)[0] == 'O') + && (ZSTR_VAL(name)[1] == 'p' || ZSTR_VAL(name)[1] == 'P') + && (ZSTR_VAL(name)[2] == 'e' || ZSTR_VAL(name)[2] == 'E') + && (ZSTR_VAL(name)[3] == 'n' || ZSTR_VAL(name)[3] == 'N')) { + return (zend_function*)&xmlreader_open_fn; + } else if (ZSTR_LEN(name) == sizeof("xml") - 1 + && (ZSTR_VAL(name)[0] == 'x' || ZSTR_VAL(name)[0] == 'X') + && (ZSTR_VAL(name)[1] == 'm' || ZSTR_VAL(name)[1] == 'M') + && (ZSTR_VAL(name)[2] == 'l' || ZSTR_VAL(name)[2] == 'L')) { + return (zend_function*)&xmlreader_xml_fn; + } + return zend_std_get_method(obj, name, key);; +} +/* }}} */ + /* {{{ _xmlreader_get_valid_file_path */ /* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a 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[] /* {{{ */ = { PHP_ME(xmlreader, moveToElement, arginfo_class_XMLReader_moveToElement, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, moveToFirstAttribute, arginfo_class_XMLReader_moveToFirstAttribute, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, moveToNextAttribute, arginfo_class_XMLReader_moveToNextAttribute, ZEND_ACC_PUBLIC) - PHP_ME(xmlreader, open, arginfo_class_XMLReader_open, ZEND_ACC_PUBLIC) + PHP_ME(xmlreader, open, arginfo_class_XMLReader_open, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(xmlreader, read, arginfo_class_XMLReader_read, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, next, arginfo_class_XMLReader_next, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, readInnerXml, arginfo_class_XMLReader_readInnerXml, ZEND_ACC_PUBLIC) @@ -1158,7 +1180,7 @@ static const zend_function_entry xmlreader_functions[] /* {{{ */ = { PHP_ME(xmlreader, setParserProperty, arginfo_class_XMLReader_setParserProperty, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, setRelaxNGSchema, arginfo_class_XMLReader_setRelaxNGSchema, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, setRelaxNGSchemaSource, arginfo_class_XMLReader_setRelaxNGSchemaSource, ZEND_ACC_PUBLIC) - PHP_ME(xmlreader, XML, arginfo_class_XMLReader_XML, ZEND_ACC_PUBLIC) + PHP_ME(xmlreader, XML, arginfo_class_XMLReader_XML, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(xmlreader, expand, arginfo_class_XMLReader_expand, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ @@ -1177,12 +1199,18 @@ PHP_MINIT_FUNCTION(xmlreader) xmlreader_object_handlers.read_property = xmlreader_read_property; xmlreader_object_handlers.write_property = xmlreader_write_property; xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr; + xmlreader_object_handlers.get_method = xmlreader_get_method; xmlreader_object_handlers.clone_obj = NULL; INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions); ce.create_object = xmlreader_objects_new; xmlreader_class_entry = zend_register_internal_class(&ce); + memcpy(&xmlreader_open_fn, zend_hash_str_find_ptr(&xmlreader_class_entry->function_table, "open", sizeof("open")-1), sizeof(zend_internal_function)); + xmlreader_open_fn.fn_flags &= ~ZEND_ACC_STATIC; + memcpy(&xmlreader_xml_fn, zend_hash_str_find_ptr(&xmlreader_class_entry->function_table, "xml", sizeof("xml")-1), sizeof(zend_internal_function)); + xmlreader_xml_fn.fn_flags &= ~ZEND_ACC_STATIC; + zend_hash_init(&xmlreader_prop_handlers, 0, NULL, php_xmlreader_free_prop_handler, 1); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING); diff --git a/ext/xmlreader/tests/static.phpt b/ext/xmlreader/tests/static.phpt new file mode 100644 index 000000000000..0218efd5fc2e --- /dev/null +++ b/ext/xmlreader/tests/static.phpt @@ -0,0 +1,33 @@ +--TEST-- +Calling XMLReader::open() and ::XML() statically +--SKIPIF-- + +--FILE-- + +'; +file_put_contents($filename, $xmlstring); + +$reader = XMLReader::open($filename); +while ($reader->read()) { + echo $reader->name, "\n"; +} + +$reader = XMLReader::XML($xmlstring); +while ($reader->read()) { + echo $reader->name, "\n"; +} +?> +--EXPECTF-- +books +books +books +books +--CLEAN-- +