diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 3f834b7155133..fb05339522760 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -123,6 +123,40 @@ zval *xmlreader_get_property_ptr_ptr(zend_object *object, zend_string *name, int } /* }}} */ +static int xmlreader_has_property(zend_object *object, zend_string *name, int type, void **cache_slot) +{ + xmlreader_object *obj = php_xmlreader_fetch_object(object); + xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name); + + if (hnd != NULL) { + if (type == ZEND_PROPERTY_EXISTS) { + return 1; + } + + zval rv; + if (xmlreader_property_reader(obj, hnd, &rv) == FAILURE) { + return 0; + } + + bool result; + + if (type == ZEND_PROPERTY_NOT_EMPTY) { + result = zend_is_true(&rv); + } else if (type == ZEND_PROPERTY_ISSET) { + result = (Z_TYPE(rv) != IS_NULL); + } else { + ZEND_UNREACHABLE(); + } + + zval_ptr_dtor(&rv); + + return result; + } + + return zend_std_has_property(object, name, type, cache_slot); +} + + /* {{{ xmlreader_read_property */ zval *xmlreader_read_property(zend_object *object, zend_string *name, int type, void **cache_slot, zval *rv) { @@ -159,6 +193,18 @@ zval *xmlreader_write_property(zend_object *object, zend_string *name, zval *val } /* }}} */ +void xmlreader_unset_property(zend_object *object, zend_string *name, void **cache_slot) +{ + xmlreader_prop_handler *hnd = zend_hash_find_ptr(&xmlreader_prop_handlers, name); + + if (hnd != NULL) { + zend_throw_error(NULL, "Cannot unset %s::$%s", ZSTR_VAL(object->ce->name), ZSTR_VAL(name)); + return; + } + + zend_std_unset_property(object, name, cache_slot); +} + /* {{{ */ static zend_function *xmlreader_get_method(zend_object **obj, zend_string *name, const zval *key) { @@ -1293,8 +1339,10 @@ PHP_MINIT_FUNCTION(xmlreader) memcpy(&xmlreader_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); xmlreader_object_handlers.offset = XtOffsetOf(xmlreader_object, std); xmlreader_object_handlers.free_obj = xmlreader_objects_free_storage; + xmlreader_object_handlers.has_property = xmlreader_has_property; xmlreader_object_handlers.read_property = xmlreader_read_property; xmlreader_object_handlers.write_property = xmlreader_write_property; + xmlreader_object_handlers.unset_property = xmlreader_unset_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; diff --git a/ext/xmlreader/tests/virtual_properties2.phpt b/ext/xmlreader/tests/virtual_properties2.phpt new file mode 100644 index 0000000000000..c748f1fc59ca0 --- /dev/null +++ b/ext/xmlreader/tests/virtual_properties2.phpt @@ -0,0 +1,46 @@ +--TEST-- +Virtual property existence tests +--EXTENSIONS-- +xmlreader +--FILE-- +attributeCount)); +var_dump(empty($reader->attributeCount)); +var_dump(property_exists($reader, "attributeCount")); + +var_dump(isset($reader->baseURI)); +var_dump(empty($reader->baseURI)); +var_dump(property_exists($reader, "baseURI")); + +var_dump(isset($reader->depth)); +var_dump(empty($reader->depth)); +var_dump(property_exists($reader, "depth")); + +var_dump(isset($reader->hasAttributes)); +var_dump(empty($reader->hasAttributes)); +var_dump(property_exists($reader, "hasAttributes")); + +var_dump(isset($reader->hasValue)); +var_dump(empty($reader->hasValue)); +var_dump(property_exists($reader, "hasValue")); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/xmlreader/tests/virtual_properties3.phpt b/ext/xmlreader/tests/virtual_properties3.phpt new file mode 100644 index 0000000000000..ad016c4db7647 --- /dev/null +++ b/ext/xmlreader/tests/virtual_properties3.phpt @@ -0,0 +1,55 @@ +--TEST-- +Virtual property unset tests +--EXTENSIONS-- +xmlreader +--FILE-- +attributeCount); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +try { + unset($reader->baseURI); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +try { + unset($reader->depth); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +try { + unset($reader->hasAttributes); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +try { + unset($reader->hasValue); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +unset($reader->x); +var_dump(isset($reader->x)); + +?> +--EXPECT-- +Cannot unset MyXMLReader::$attributeCount +Cannot unset MyXMLReader::$baseURI +Cannot unset MyXMLReader::$depth +Cannot unset MyXMLReader::$hasAttributes +Cannot unset MyXMLReader::$hasValue +bool(false)