diff options
Diffstat (limited to 'ext/reflection')
90 files changed, 1408 insertions, 1515 deletions
diff --git a/ext/reflection/CREDITS b/ext/reflection/CREDITS index 84be988802..84be988802 100755..100644 --- a/ext/reflection/CREDITS +++ b/ext/reflection/CREDITS diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4 index daab409c32..2f295de915 100755..100644 --- a/ext/reflection/config.m4 +++ b/ext/reflection/config.m4 @@ -1,4 +1 @@ -dnl config.m4 for extension reflection - -AC_DEFINE(HAVE_REFLECTION, 1, [Whether Reflection is enabled]) PHP_NEW_EXTENSION(reflection, php_reflection.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32 index 508696d033..7f000b02ab 100755..100644 --- a/ext/reflection/config.w32 +++ b/ext/reflection/config.w32 @@ -1,5 +1,4 @@ // vim:ft=javascript EXTENSION("reflection", "php_reflection.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); -AC_DEFINE('HAVE_REFLECTION', 1, 'Reflection support enabled'); PHP_REFLECTION="yes"; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index c38160297d..61f09ca643 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2018 The PHP Group | + | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -28,6 +28,8 @@ #include "php_ini.h" #include "php_reflection.h" #include "ext/standard/info.h" +#include "ext/standard/sha1.h" +#include "ext/standard/php_random.h" #include "zend.h" #include "zend_API.h" @@ -42,19 +44,27 @@ #include "zend_builtin_functions.h" #include "zend_smart_str.h" -#define reflection_update_property(object, name, value) do { \ - zval member; \ - ZVAL_STR(&member, name); \ - zend_std_write_property(object, &member, value, NULL); \ - Z_TRY_DELREF_P(value); \ - zval_ptr_dtor(&member); \ - } while (0) +/* Key used to avoid leaking addresses in ReflectionProperty::getId() */ +#define REFLECTION_KEY_LEN 16 +ZEND_BEGIN_MODULE_GLOBALS(reflection) + zend_bool key_initialized; + unsigned char key[REFLECTION_KEY_LEN]; +ZEND_END_MODULE_GLOBALS(reflection) +ZEND_DECLARE_MODULE_GLOBALS(reflection) -#define reflection_update_property_name(object, value) \ - reflection_update_property(object, ZSTR_KNOWN(ZEND_STR_NAME), value) +#define REFLECTION_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(reflection, v) -#define reflection_update_property_class(object, value) \ - reflection_update_property(object, ZSTR_KNOWN(ZEND_STR_CLASS), value) +static zend_always_inline zval *reflection_prop_name(zval *object) { + /* $name is always in the first property slot. */ + ZEND_ASSERT(Z_OBJCE_P(object)->default_properties_count >= 1); + return &Z_OBJ_P(object)->properties_table[0]; +} + +static zend_always_inline zval *reflection_prop_class(zval *object) { + /* $class is always in the second property slot. */ + ZEND_ASSERT(Z_OBJCE_P(object)->default_properties_count >= 2); + return &Z_OBJ_P(object)->properties_table[1]; +} /* Class entry pointers */ PHPAPI zend_class_entry *reflector_ptr; @@ -73,40 +83,39 @@ PHPAPI zend_class_entry *reflection_property_ptr; PHPAPI zend_class_entry *reflection_class_constant_ptr; PHPAPI zend_class_entry *reflection_extension_ptr; PHPAPI zend_class_entry *reflection_zend_extension_ptr; +PHPAPI zend_class_entry *reflection_reference_ptr; /* Exception throwing macro */ -#define _DO_THROW(msg) \ - zend_throw_exception(reflection_exception_ptr, msg, 0); \ - return; \ - -#define RETURN_ON_EXCEPTION \ - if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) { \ - return; \ - } - -#define GET_REFLECTION_OBJECT() \ - intern = Z_REFLECTION_P(getThis()); \ - if (intern->ptr == NULL) { \ - RETURN_ON_EXCEPTION \ - zend_throw_error(NULL, "Internal error: Failed to retrieve the reflection object"); \ - return; \ - } \ +#define _DO_THROW(msg) \ + zend_throw_exception(reflection_exception_ptr, msg, 0); + +#define GET_REFLECTION_OBJECT() do { \ + intern = Z_REFLECTION_P(ZEND_THIS); \ + if (intern->ptr == NULL) { \ + if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) { \ + return; \ + } \ + zend_throw_error(NULL, "Internal error: Failed to retrieve the reflection object"); \ + return; \ + } \ +} while (0) -#define GET_REFLECTION_OBJECT_PTR(target) \ - GET_REFLECTION_OBJECT() \ - target = intern->ptr; \ +#define GET_REFLECTION_OBJECT_PTR(target) do { \ + GET_REFLECTION_OBJECT(); \ + target = intern->ptr; \ +} while (0) /* Class constants */ -#define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \ +#define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \ zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (zend_long)value); /* {{{ Object structure */ /* Struct for properties */ typedef struct _property_reference { - zend_class_entry *ce; zend_property_info prop; zend_string *unmangled_name; + zend_bool dynamic; } property_reference; /* Struct for parameters */ @@ -119,8 +128,7 @@ typedef struct _parameter_reference { /* Struct for type hints */ typedef struct _type_reference { - struct _zend_arg_info *arg_info; - zend_function *fptr; + zend_type type; } type_reference; typedef enum { @@ -135,7 +143,6 @@ typedef enum { /* Struct for reflection objects */ typedef struct { - zval dummy; /* holder for the second property */ zval obj; void *ptr; zend_class_entry *ce; @@ -153,6 +160,11 @@ static inline reflection_object *reflection_object_from_obj(zend_object *obj) { static zend_object_handlers reflection_object_handlers; +static inline zend_bool is_closure_invoke(zend_class_entry *ce, zend_string *lcname) { + return ce == zend_ce_closure + && zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME); +} + static zval *_default_load_name(zval *object) /* {{{ */ { return zend_hash_find_ex_ind(Z_OBJPROP_P(object), ZSTR_KNOWN(ZEND_STR_NAME), 1); @@ -203,7 +215,6 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ reflection_object *intern = reflection_object_from_obj(object); parameter_reference *reference; property_reference *prop_reference; - type_reference *typ_reference; if (intern->ptr) { switch (intern->ref_type) { @@ -213,8 +224,6 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ efree(intern->ptr); break; case REF_TYPE_TYPE: - typ_reference = (type_reference*)intern->ptr; - _free_function(typ_reference->fptr); efree(intern->ptr); break; case REF_TYPE_FUNCTION: @@ -266,7 +275,7 @@ static zval *reflection_instantiate(zend_class_entry *pce, zval *object) /* {{{ static void _const_string(smart_str *str, char *name, zval *value, char *indent); static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent); -static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent); +static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent, zend_bool dynamic); static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char* indent); static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent); static void _extension_string(smart_str *str, zend_module_entry *module, char *indent); @@ -324,6 +333,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char if (ce->num_interfaces) { uint32_t i; + ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); if (ce->ce_flags & ZEND_ACC_INTERFACE) { smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name)); } else { @@ -365,7 +375,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char zend_property_info *prop; ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - if(prop->flags & ZEND_ACC_SHADOW) { + if ((prop->flags & ZEND_ACC_PRIVATE) && prop->ce != ce) { count_shadow_props++; } else if (prop->flags & ZEND_ACC_STATIC) { count_static_props++; @@ -379,8 +389,8 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char zend_property_info *prop; ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) { - _property_string(str, prop, NULL, ZSTR_VAL(sub_indent)); + if ((prop->flags & ZEND_ACC_STATIC) && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) { + _property_string(str, prop, NULL, ZSTR_VAL(sub_indent), 0); } } ZEND_HASH_FOREACH_END(); } @@ -426,14 +436,15 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char zend_property_info *prop; ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) { - _property_string(str, prop, NULL, ZSTR_VAL(sub_indent)); + if (!(prop->flags & ZEND_ACC_STATIC) + && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) { + _property_string(str, prop, NULL, ZSTR_VAL(sub_indent), 0); } } ZEND_HASH_FOREACH_END(); } smart_str_append_printf(str, "%s }\n", indent); - if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_properties) { + if (obj && Z_TYPE_P(obj) == IS_OBJECT) { HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj); zend_string *prop_name; smart_str prop_str = {0}; @@ -444,7 +455,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char if (prop_name && ZSTR_LEN(prop_name) && ZSTR_VAL(prop_name)[0]) { /* skip all private and protected properties */ if (!zend_hash_exists(&ce->properties_info, prop_name)) { count++; - _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent)); + _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent), 0); } } } ZEND_HASH_FOREACH_END(); @@ -460,37 +471,26 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char count = zend_hash_num_elements(&ce->function_table) - count_static_funcs; if (count > 0) { zend_function *mptr; - zend_string *key; smart_str method_str = {0}; count = 0; - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) { + ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) { if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) { - size_t len = ZSTR_LEN(mptr->common.function_name); - - /* Do not display old-style inherited constructors */ - if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 - || mptr->common.scope == ce - || !key - || zend_binary_strcasecmp(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(mptr->common.function_name), len) == 0) + zend_function *closure; + /* see if this is a closure */ + if (obj && is_closure_invoke(ce, mptr->common.function_name) + && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL) { - zend_function *closure; - /* see if this is a closure */ - if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) - && memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 - && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL) - { - mptr = closure; - } else { - closure = NULL; - } - smart_str_appendc(&method_str, '\n'); - _function_string(&method_str, mptr, ce, ZSTR_VAL(sub_indent)); - count++; - _free_function(closure); + mptr = closure; + } else { + closure = NULL; } + smart_str_appendc(&method_str, '\n'); + _function_string(&method_str, mptr, ce, ZSTR_VAL(sub_indent)); + count++; + _free_function(closure); } } ZEND_HASH_FOREACH_END(); smart_str_append_printf(str, "\n%s - Methods [%d] {", indent, count); @@ -685,7 +685,7 @@ static void _function_closure_string(smart_str *str, zend_function *fptr, char* return; } - static_variables = fptr->op_array.static_variables; + static_variables = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr); count = zend_hash_num_elements(static_variables); if (!count) { @@ -821,14 +821,14 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent /* }}} */ /* {{{ _property_string */ -static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent) +static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent, zend_bool dynamic) { smart_str_append_printf(str, "%sProperty [ ", indent); if (!prop) { smart_str_append_printf(str, "<dynamic> public $%s", prop_name); } else { if (!(prop->flags & ZEND_ACC_STATIC)) { - if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) { + if (dynamic) { smart_str_appends(str, "<implicit> "); } else { smart_str_appends(str, "<default> "); @@ -861,12 +861,8 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha } /* }}} */ -static int _extension_ini_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +static void _extension_ini_string(zend_ini_entry *ini_entry, smart_str *str, char *indent, int number) /* {{{ */ { - zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el); - smart_str *str = va_arg(args, smart_str *); - char *indent = va_arg(args, char *); - int number = va_arg(args, int); char *comma = ""; if (number == ini_entry->module_number) { @@ -894,43 +890,19 @@ static int _extension_ini_string(zval *el, int num_args, va_list args, zend_hash } smart_str_append_printf(str, " %s}\n", indent); } - return ZEND_HASH_APPLY_KEEP; } /* }}} */ -static int _extension_class_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +static void _extension_class_string(zend_class_entry *ce, zend_string *key, smart_str *str, char *indent, zend_module_entry *module, int *num_classes) /* {{{ */ { - zend_class_entry *ce = (zend_class_entry*)Z_PTR_P(el); - smart_str *str = va_arg(args, smart_str *); - char *indent = va_arg(args, char *); - struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*); - int *num_classes = va_arg(args, int*); - - if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { + if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { /* dump class if it is not an alias */ - if (!zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) { + if (zend_string_equals_ci(ce->name, key)) { smart_str_append_printf(str, "\n"); _class_string(str, ce, NULL, indent); (*num_classes)++; } } - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - -static int _extension_const_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ -{ - zend_constant *constant = (zend_constant*)Z_PTR_P(el); - smart_str *str = va_arg(args, smart_str *); - char *indent = va_arg(args, char *); - struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*); - int *num_classes = va_arg(args, int*); - - if (ZEND_CONSTANT_MODULE_NUMBER(constant) == module->module_number) { - _const_string(str, ZSTR_VAL(constant->name), &constant->value, indent); - (*num_classes)++; - } - return ZEND_HASH_APPLY_KEEP; } /* }}} */ @@ -984,7 +956,10 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i { smart_str str_ini = {0}; - zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number); + zend_ini_entry *ini_entry; + ZEND_HASH_FOREACH_PTR(EG(ini_directives), ini_entry) { + _extension_ini_string(ini_entry, &str_ini, indent, module->module_number); + } ZEND_HASH_FOREACH_END(); if (smart_str_get_len(&str_ini) > 0) { smart_str_append_printf(str, "\n - INI {\n"); smart_str_append_smart_str(str, &str_ini); @@ -995,9 +970,16 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i { smart_str str_constants = {0}; + zend_constant *constant; int num_constants = 0; - zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants); + ZEND_HASH_FOREACH_PTR(EG(zend_constants), constant) { + if (ZEND_CONSTANT_MODULE_NUMBER(constant) == module->module_number) { + _const_string(&str_constants, ZSTR_VAL(constant->name), &constant->value, indent); + num_constants++; + } + } ZEND_HASH_FOREACH_END(); + if (num_constants) { smart_str_append_printf(str, "\n - Constants [%d] {\n", num_constants); smart_str_append_smart_str(str, &str_constants); @@ -1028,9 +1010,13 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i { zend_string *sub_indent = strpprintf(0, "%s ", indent); smart_str str_classes = {0}; + zend_string *key; + zend_class_entry *ce; int num_classes = 0; - zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) _extension_class_string, 4, &str_classes, ZSTR_VAL(sub_indent), module, &num_classes); + ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { + _extension_class_string(ce, key, &str_classes, ZSTR_VAL(sub_indent), module, &num_classes); + } ZEND_HASH_FOREACH_END(); if (num_classes) { smart_str_append_printf(str, "\n - Classes [%d] {", num_classes); smart_str_append_smart_str(str, &str_classes); @@ -1083,15 +1069,13 @@ static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object) { reflection_object *intern; - zval name; - ZVAL_STR_COPY(&name, ce->name); reflection_instantiate(reflection_class_ptr, object); intern = Z_REFLECTION_P(object); intern->ptr = ce; intern->ref_type = REF_TYPE_OTHER; intern->ce = ce; - reflection_update_property_name(object, &name); + ZVAL_STR_COPY(reflection_prop_name(object), ce->name); } /* }}} */ @@ -1099,7 +1083,6 @@ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object) static void reflection_extension_factory(zval *object, const char *name_str) { reflection_object *intern; - zval name; size_t name_len = strlen(name_str); zend_string *lcname; struct _zend_module_entry *module; @@ -1114,11 +1097,10 @@ static void reflection_extension_factory(zval *object, const char *name_str) reflection_instantiate(reflection_extension_ptr, object); intern = Z_REFLECTION_P(object); - ZVAL_STRINGL(&name, module->name, name_len); intern->ptr = module; intern->ref_type = REF_TYPE_OTHER; intern->ce = NULL; - reflection_update_property_name(object, &name); + ZVAL_STRINGL(reflection_prop_name(object), module->name, name_len); } /* }}} */ @@ -1127,18 +1109,8 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje { reflection_object *intern; parameter_reference *reference; - zval name; + zval *prop_name; - if (arg_info->name) { - if (fptr->type == ZEND_INTERNAL_FUNCTION && - !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { - ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)->name); - } else { - ZVAL_STR_COPY(&name, arg_info->name); - } - } else { - ZVAL_NULL(&name); - } reflection_instantiate(reflection_parameter_ptr, object); intern = Z_REFLECTION_P(object); reference = (parameter_reference*) emalloc(sizeof(parameter_reference)); @@ -1151,14 +1123,25 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje intern->ce = fptr->common.scope; if (closure_object) { Z_ADDREF_P(closure_object); - ZVAL_COPY_VALUE(&intern->obj, closure_object); + ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure_object)); + } + + prop_name = reflection_prop_name(object); + if (arg_info->name) { + if (fptr->type == ZEND_INTERNAL_FUNCTION && + !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { + ZVAL_STRING(prop_name, ((zend_internal_arg_info*)arg_info)->name); + } else { + ZVAL_STR_COPY(prop_name, arg_info->name); + } + } else { + ZVAL_NULL(prop_name); } - reflection_update_property_name(object, &name); } /* }}} */ /* {{{ reflection_type_factory */ -static void reflection_type_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zval *object) +static void reflection_type_factory(zend_type type, zval *object) { reflection_object *intern; type_reference *reference; @@ -1166,15 +1149,9 @@ static void reflection_type_factory(zend_function *fptr, zval *closure_object, s reflection_instantiate(reflection_named_type_ptr, object); intern = Z_REFLECTION_P(object); reference = (type_reference*) emalloc(sizeof(type_reference)); - reference->arg_info = arg_info; - reference->fptr = fptr; + reference->type = type; intern->ptr = reference; intern->ref_type = REF_TYPE_TYPE; - intern->ce = fptr->common.scope; - if (closure_object) { - Z_ADDREF_P(closure_object); - ZVAL_COPY_VALUE(&intern->obj, closure_object); - } } /* }}} */ @@ -1182,10 +1159,6 @@ static void reflection_type_factory(zend_function *fptr, zval *closure_object, s static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object) { reflection_object *intern; - zval name; - - ZVAL_STR_COPY(&name, function->common.function_name); - reflection_instantiate(reflection_function_ptr, object); intern = Z_REFLECTION_P(object); intern->ptr = function; @@ -1193,9 +1166,9 @@ static void reflection_function_factory(zend_function *function, zval *closure_o intern->ce = NULL; if (closure_object) { Z_ADDREF_P(closure_object); - ZVAL_COPY_VALUE(&intern->obj, closure_object); + ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure_object)); } - reflection_update_property_name(object, &name); + ZVAL_STR_COPY(reflection_prop_name(object), function->common.function_name); } /* }}} */ @@ -1203,12 +1176,7 @@ static void reflection_function_factory(zend_function *function, zval *closure_o static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object) { reflection_object *intern; - zval name; - zval classname; - ZVAL_STR_COPY(&name, (method->common.scope && method->common.scope->trait_aliases)? - zend_resolve_method_name(ce, method) : method->common.function_name); - ZVAL_STR_COPY(&classname, method->common.scope->name); reflection_instantiate(reflection_method_ptr, object); intern = Z_REFLECTION_P(object); intern->ptr = method; @@ -1216,19 +1184,20 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho intern->ce = ce; if (closure_object) { Z_ADDREF_P(closure_object); - ZVAL_COPY_VALUE(&intern->obj, closure_object); + ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure_object)); } - reflection_update_property_name(object, &name); - reflection_update_property_class(object, &classname); + + ZVAL_STR_COPY(reflection_prop_name(object), + (method->common.scope && method->common.scope->trait_aliases) + ? zend_resolve_method_name(ce, method) : method->common.function_name); + ZVAL_STR_COPY(reflection_prop_class(object), method->common.scope->name); } /* }}} */ /* {{{ reflection_property_factory */ -static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object) +static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object, zend_bool dynamic) { reflection_object *intern; - zval propname; - zval classname; property_reference *reference; if (!(prop->flags & ZEND_ACC_PRIVATE)) { @@ -1241,35 +1210,32 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name, tmp_ce = tmp_ce->parent; } - if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */ + if (tmp_info && (!(tmp_info->flags & ZEND_ACC_PRIVATE) || tmp_info->ce == tmp_ce)) { /* found something and it's not a parent's private */ prop = tmp_info; } else { /* not found, use initial value */ ce = store_ce; } } - ZVAL_STR_COPY(&propname, name); - ZVAL_STR_COPY(&classname, prop->ce->name); - reflection_instantiate(reflection_property_ptr, object); intern = Z_REFLECTION_P(object); reference = (property_reference*) emalloc(sizeof(property_reference)); - reference->ce = ce; reference->prop = *prop; reference->unmangled_name = zend_string_copy(name); + reference->dynamic = dynamic; intern->ptr = reference; intern->ref_type = REF_TYPE_PROPERTY; intern->ce = ce; intern->ignore_visibility = 0; - reflection_update_property_name(object, &propname); - reflection_update_property_class(object, &classname); + ZVAL_STR_COPY(reflection_prop_name(object), name); + ZVAL_STR_COPY(reflection_prop_class(object), prop->ce->name); } /* }}} */ static void reflection_property_factory_str(zend_class_entry *ce, const char *name_str, size_t name_len, zend_property_info *prop, zval *object) { zend_string *name = zend_string_init(name_str, name_len, 0); - reflection_property_factory(ce, name, prop, object); + reflection_property_factory(ce, name, prop, object, 0); zend_string_release(name); } @@ -1277,11 +1243,6 @@ static void reflection_property_factory_str(zend_class_entry *ce, const char *na static void reflection_class_constant_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object) { reflection_object *intern; - zval name; - zval classname; - - ZVAL_STR_COPY(&name, name_str); - ZVAL_STR_COPY(&classname, ce->name); reflection_instantiate(reflection_class_constant_ptr, object); intern = Z_REFLECTION_P(object); @@ -1289,11 +1250,41 @@ static void reflection_class_constant_factory(zend_class_entry *ce, zend_string intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; intern->ignore_visibility = 0; - reflection_update_property_name(object, &name); - reflection_update_property_class(object, &classname); + + ZVAL_STR_COPY(reflection_prop_name(object), name_str); + ZVAL_STR_COPY(reflection_prop_class(object), ce->name); } /* }}} */ +static void reflection_export_impl(zval *return_value, zval *object, zend_bool return_output) { + zval fname, retval; + int result; + + /* Invoke the __toString() method */ + ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1); + result = call_user_function(NULL, object, &fname, &retval, 0, NULL); + zval_ptr_dtor_str(&fname); + + if (result == FAILURE) { + _DO_THROW("Invocation of method __toString() failed"); + return; + } + + if (Z_TYPE(retval) == IS_UNDEF) { + php_error_docref(NULL, E_WARNING, "%s::__toString() did not return anything", ZSTR_VAL(Z_OBJCE_P(object)->name)); + RETURN_FALSE; + } + + if (return_output) { + ZVAL_COPY_VALUE(return_value, &retval); + } else { + /* No need for _r variant, return of __toString should always be a string */ + zend_print_zval(&retval, 0); + zend_printf("\n"); + zval_ptr_dtor(&retval); + } +} + /* {{{ _reflection_export */ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc) { @@ -1320,8 +1311,9 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c } /* Create object */ - if (object_and_properties_init(&reflector, ce_ptr, NULL) == FAILURE) { + if (object_init_ex(&reflector, ce_ptr) == FAILURE) { _DO_THROW("Could not create reflector"); + return; } /* Call __construct() */ @@ -1349,34 +1341,10 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c if (result == FAILURE) { zval_ptr_dtor(&reflector); _DO_THROW("Could not create reflector"); + return; } - /* Call static reflection::export */ - ZVAL_COPY_VALUE(¶ms[0], &reflector); - ZVAL_BOOL(¶ms[1], return_output); - - ZVAL_STRINGL(&fci.function_name, "reflection::export", sizeof("reflection::export") - 1); - fci.object = NULL; - fci.retval = &retval; - fci.param_count = 2; - fci.params = params; - fci.no_separation = 1; - - result = zend_call_function(&fci, NULL); - - zval_ptr_dtor(&fci.function_name); - - if (result == FAILURE && EG(exception) == NULL) { - zval_ptr_dtor(&reflector); - zval_ptr_dtor(&retval); - _DO_THROW("Could not execute reflection::export()"); - } - - if (return_output) { - ZVAL_COPY_VALUE(return_value, &retval); - } else { - zval_ptr_dtor(&retval); - } + reflection_export_impl(return_value, &reflector, return_output); /* Destruct reflector which is no longer needed */ zval_ptr_dtor(&reflector); @@ -1389,7 +1357,7 @@ static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTIO reflection_object *intern; parameter_reference *param; - intern = Z_REFLECTION_P(getThis()); + intern = Z_REFLECTION_P(ZEND_THIS); if (intern->ptr == NULL) { if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) { return NULL; @@ -1439,8 +1407,7 @@ ZEND_METHOD(reflection, __clone) Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ ZEND_METHOD(reflection, export) { - zval *object, fname, retval; - int result; + zval *object; zend_bool return_output = 0; ZEND_PARSE_PARAMETERS_START(1, 2) @@ -1449,29 +1416,7 @@ ZEND_METHOD(reflection, export) Z_PARAM_BOOL(return_output) ZEND_PARSE_PARAMETERS_END(); - /* Invoke the __toString() method */ - ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1); - result= call_user_function(NULL, object, &fname, &retval, 0, NULL); - zval_ptr_dtor_str(&fname); - - if (result == FAILURE) { - _DO_THROW("Invocation of method __toString() failed"); - /* Returns from this function */ - } - - if (Z_TYPE(retval) == IS_UNDEF) { - php_error_docref(NULL, E_WARNING, "%s::__toString() did not return anything", ZSTR_VAL(Z_OBJCE_P(object)->name)); - RETURN_FALSE; - } - - if (return_output) { - ZVAL_COPY_VALUE(return_value, &retval); - } else { - /* No need for _r variant, return of __toString should always be a string */ - zend_print_zval(&retval, 0); - zend_printf("\n"); - zval_ptr_dtor(&retval); - } + reflection_export_impl(return_value, object, return_output); } /* }}} */ @@ -1493,9 +1438,6 @@ ZEND_METHOD(reflection, getModifierNames) if (modifiers & ZEND_ACC_FINAL) { add_next_index_stringl(return_value, "final", sizeof("final")-1); } - if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) { - add_next_index_stringl(return_value, "public", sizeof("public")-1); - } /* These are mutually exclusive */ switch (modifiers & ZEND_ACC_PPP_MASK) { @@ -1528,14 +1470,13 @@ ZEND_METHOD(reflection_function, export) Constructor. Throws an Exception in case the given function does not exist */ ZEND_METHOD(reflection_function, __construct) { - zval name; zval *object; zval *closure = NULL; reflection_object *intern; zend_function *fptr; zend_string *fname, *lcname; - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &closure, zend_ce_closure) == SUCCESS) { @@ -1567,12 +1508,11 @@ ZEND_METHOD(reflection_function, __construct) } } - ZVAL_STR_COPY(&name, fptr->common.function_name); - reflection_update_property_name(object, &name); + ZVAL_STR_COPY(reflection_prop_name(object), fptr->common.function_name); intern->ptr = fptr; intern->ref_type = REF_TYPE_FUNCTION; if (closure) { - ZVAL_COPY_VALUE(&intern->obj, closure); + ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure)); } else { ZVAL_UNDEF(&intern->obj); } @@ -1604,7 +1544,7 @@ ZEND_METHOD(reflection_function, getName) if (zend_parse_parameters_none() == FAILURE) { return; } - _default_get_name(getThis(), return_value); + _default_get_name(ZEND_THIS, return_value); } /* }}} */ @@ -1637,7 +1577,8 @@ ZEND_METHOD(reflection_function, getClosureThis) if (!Z_ISUNDEF(intern->obj)) { closure_this = zend_get_closure_this_ptr(&intern->obj); if (!Z_ISUNDEF_P(closure_this)) { - ZVAL_COPY(return_value, closure_this); + Z_ADDREF_P(closure_this); + ZVAL_OBJ(return_value, Z_OBJ_P(closure_this)); } } } @@ -1677,7 +1618,8 @@ ZEND_METHOD(reflection_function, getClosure) if (!Z_ISUNDEF(intern->obj)) { /* Closures are immutable objects */ - ZVAL_COPY(return_value, &intern->obj); + Z_ADDREF(intern->obj); + ZVAL_OBJ(return_value, Z_OBJ(intern->obj)); } else { zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL); } @@ -1813,21 +1755,23 @@ ZEND_METHOD(reflection_function, getStaticVariables) /* Return an empty array in case no static variables exist */ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) { + HashTable *ht; + array_init(return_value); - if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) { - if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { - GC_DELREF(fptr->op_array.static_variables); - } - fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables); + ht = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr); + if (!ht) { + ZEND_ASSERT(fptr->op_array.fn_flags & ZEND_ACC_IMMUTABLE); + ht = zend_array_dup(fptr->op_array.static_variables); + ZEND_MAP_PTR_SET(fptr->op_array.static_variables_ptr, ht); } - ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) { + ZEND_HASH_FOREACH_VAL(ht, val) { if (UNEXPECTED(zval_update_constant_ex(val, fptr->common.scope) != SUCCESS)) { return; } } ZEND_HASH_FOREACH_END(); - zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref); + zend_hash_copy(Z_ARRVAL_P(return_value), ht, zval_add_ref); } else { - ZVAL_EMPTY_ARRAY(return_value); + RETURN_EMPTY_ARRAY(); } } /* }}} */ @@ -2015,8 +1959,7 @@ ZEND_METHOD(reflection_function, getParameters) } if (!num_args) { - ZVAL_EMPTY_ARRAY(return_value); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); @@ -2091,7 +2034,7 @@ ZEND_METHOD(reflection_generator, __construct) reflection_object *intern; zend_execute_data *ex; - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &generator, zend_ce_generator) == FAILURE) { @@ -2105,7 +2048,8 @@ ZEND_METHOD(reflection_generator, __construct) } intern->ref_type = REF_TYPE_GENERATOR; - ZVAL_COPY(&intern->obj, generator); + Z_ADDREF_P(generator); + ZVAL_OBJ(&intern->obj, Z_OBJ_P(generator)); intern->ce = zend_ce_generator; } /* }}} */ @@ -2120,7 +2064,7 @@ ZEND_METHOD(reflection_generator, __construct) ZEND_METHOD(reflection_generator, getTrace) { zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT; - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj); + zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_generator *root_generator; zend_execute_data *ex_backup = EG(current_execute_data); zend_execute_data *ex = generator->execute_data; @@ -2155,7 +2099,7 @@ ZEND_METHOD(reflection_generator, getTrace) /* {{{ proto public int ReflectionGenerator::getExecutingLine() */ ZEND_METHOD(reflection_generator, getExecutingLine) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj); + zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; if (zend_parse_parameters_none() == FAILURE) { @@ -2171,7 +2115,7 @@ ZEND_METHOD(reflection_generator, getExecutingLine) /* {{{ proto public string ReflectionGenerator::getExecutingFile() */ ZEND_METHOD(reflection_generator, getExecutingFile) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj); + zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; if (zend_parse_parameters_none() == FAILURE) { @@ -2187,7 +2131,7 @@ ZEND_METHOD(reflection_generator, getExecutingFile) /* {{{ proto public ReflectionFunctionAbstract ReflectionGenerator::getFunction() */ ZEND_METHOD(reflection_generator, getFunction) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj); + zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; if (zend_parse_parameters_none() == FAILURE) { @@ -2211,7 +2155,7 @@ ZEND_METHOD(reflection_generator, getFunction) /* {{{ proto public object ReflectionGenerator::getThis() */ ZEND_METHOD(reflection_generator, getThis) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj); + zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; if (zend_parse_parameters_none() == FAILURE) { @@ -2221,7 +2165,8 @@ ZEND_METHOD(reflection_generator, getThis) REFLECTION_CHECK_VALID_GENERATOR(ex) if (Z_TYPE(ex->This) == IS_OBJECT) { - ZVAL_COPY(return_value, &ex->This); + Z_ADDREF(ex->This); + ZVAL_OBJ(return_value, Z_OBJ(ex->This)); } else { ZVAL_NULL(return_value); } @@ -2231,7 +2176,7 @@ ZEND_METHOD(reflection_generator, getThis) /* {{{ proto public Generator ReflectionGenerator::getExecutingGenerator() */ ZEND_METHOD(reflection_generator, getExecutingGenerator) { - zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj); + zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); zend_execute_data *ex = generator->execute_data; zend_generator *current; @@ -2263,7 +2208,7 @@ ZEND_METHOD(reflection_parameter, __construct) parameter_reference *ref; zval *reference, *parameter; zval *object; - zval name; + zval *prop_name; reflection_object *intern; zend_function *fptr; struct _zend_arg_info *arg_info; @@ -2276,69 +2221,73 @@ ZEND_METHOD(reflection_parameter, __construct) return; } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); /* First, find the function */ switch (Z_TYPE_P(reference)) { - case IS_STRING: { - size_t lcname_len; - char *lcname; - - lcname_len = Z_STRLEN_P(reference); - lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len); - if ((fptr = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len)) == NULL) { - efree(lcname); + case IS_STRING: + { + zend_string *lcname = zend_string_tolower(Z_STR_P(reference)); + fptr = zend_hash_find_ptr(EG(function_table), lcname); + zend_string_release(lcname); + if (!fptr) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Function %s() does not exist", Z_STRVAL_P(reference)); return; } - efree(lcname); + ce = fptr->common.scope; } - ce = fptr->common.scope; break; case IS_ARRAY: { zval *classref; zval *method; - size_t lcname_len; - char *lcname; + zend_string *name, *lcname; - if (((classref =zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL) + if (((classref = zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL) || ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL)) { _DO_THROW("Expected array($object, $method) or array($classname, $method)"); - /* returns out of this function */ + return; } if (Z_TYPE_P(classref) == IS_OBJECT) { ce = Z_OBJCE_P(classref); } else { - convert_to_string_ex(classref); - if ((ce = zend_lookup_class(Z_STR_P(classref))) == NULL) { + name = zval_try_get_string(classref); + if (UNEXPECTED(!name)) { + return; + } + if ((ce = zend_lookup_class(name)) == NULL) { zend_throw_exception_ex(reflection_exception_ptr, 0, - "Class %s does not exist", Z_STRVAL_P(classref)); + "Class %s does not exist", ZSTR_VAL(name)); + zend_string_release(name); return; } + zend_string_release(name); + } + + name = zval_try_get_string(method); + if (UNEXPECTED(!name)) { + return; } - convert_to_string_ex(method); - lcname_len = Z_STRLEN_P(method); - lcname = zend_str_tolower_dup(Z_STRVAL_P(method), lcname_len); - if (ce == zend_ce_closure && Z_TYPE_P(classref) == IS_OBJECT - && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) - && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + lcname = zend_string_tolower(name); + if (Z_TYPE_P(classref) == IS_OBJECT && is_closure_invoke(ce, lcname) && (fptr = zend_get_closure_invoke_method(Z_OBJ_P(classref))) != NULL) { /* nothing to do. don't set is_closure since is the invoke handler, not the closure itself */ - } else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) { - efree(lcname); + } else if ((fptr = zend_hash_find_ptr(&ce->function_table, lcname)) == NULL) { + zend_string_release(name); + zend_string_release(lcname); zend_throw_exception_ex(reflection_exception_ptr, 0, "Method %s::%s() does not exist", ZSTR_VAL(ce->name), Z_STRVAL_P(method)); return; } - efree(lcname); + zend_string_release(name); + zend_string_release(lcname); } break; @@ -2349,7 +2298,7 @@ ZEND_METHOD(reflection_parameter, __construct) fptr = (zend_function *)zend_get_closure_method_def(reference); Z_ADDREF_P(reference); is_closure = 1; - } else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME))) == NULL) { + } else if ((fptr = zend_hash_find_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE))) == NULL) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZEND_INVOKE_FUNC_NAME); return; @@ -2359,7 +2308,7 @@ ZEND_METHOD(reflection_parameter, __construct) default: _DO_THROW("The parameter class is expected to be either a string, an array(class, method) or a callable object"); - /* returns out of this function */ + return; } /* Now, search for the parameter */ @@ -2371,29 +2320,23 @@ ZEND_METHOD(reflection_parameter, __construct) if (Z_TYPE_P(parameter) == IS_LONG) { position= (int)Z_LVAL_P(parameter); if (position < 0 || (uint32_t)position >= num_args) { - if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - if (fptr->type != ZEND_OVERLOADED_FUNCTION) { - zend_string_release_ex(fptr->common.function_name, 0); - } - zend_free_trampoline(fptr); - } - if (is_closure) { - zval_ptr_dtor(reference); - } _DO_THROW("The parameter specified by its offset could not be found"); - /* returns out of this function */ + goto failure; } } else { uint32_t i; - position= -1; - convert_to_string_ex(parameter); + position = -1; + if (!try_convert_to_string(parameter)) { + goto failure; + } + if (fptr->type == ZEND_INTERNAL_FUNCTION && !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { for (i = 0; i < num_args; i++) { if (arg_info[i].name) { if (strcmp(((zend_internal_arg_info*)arg_info)[i].name, Z_STRVAL_P(parameter)) == 0) { - position= i; + position = i; break; } @@ -2403,43 +2346,22 @@ ZEND_METHOD(reflection_parameter, __construct) for (i = 0; i < num_args; i++) { if (arg_info[i].name) { if (strcmp(ZSTR_VAL(arg_info[i].name), Z_STRVAL_P(parameter)) == 0) { - position= i; + position = i; break; } } } } if (position == -1) { - if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - if (fptr->type != ZEND_OVERLOADED_FUNCTION) { - zend_string_release_ex(fptr->common.function_name, 0); - } - zend_free_trampoline(fptr); - } - if (is_closure) { - zval_ptr_dtor(reference); - } _DO_THROW("The parameter specified by its name could not be found"); - /* returns out of this function */ + goto failure; } } - if (arg_info[position].name) { - if (fptr->type == ZEND_INTERNAL_FUNCTION && - !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { - ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)[position].name); - } else { - ZVAL_STR_COPY(&name, arg_info[position].name); - } - } else { - ZVAL_NULL(&name); - } - reflection_update_property_name(object, &name); - ref = (parameter_reference*) emalloc(sizeof(parameter_reference)); ref->arg_info = &arg_info[position]; ref->offset = (uint32_t)position; - ref->required = position < fptr->common.required_num_args; + ref->required = (uint32_t)position < fptr->common.required_num_args; ref->fptr = fptr; /* TODO: copy fptr */ intern->ptr = ref; @@ -2448,6 +2370,30 @@ ZEND_METHOD(reflection_parameter, __construct) if (reference && is_closure) { ZVAL_COPY_VALUE(&intern->obj, reference); } + + prop_name = reflection_prop_name(object); + if (arg_info[position].name) { + if (fptr->type == ZEND_INTERNAL_FUNCTION && + !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { + ZVAL_STRING(prop_name, ((zend_internal_arg_info*)arg_info)[position].name); + } else { + ZVAL_STR_COPY(prop_name, arg_info[position].name); + } + } else { + ZVAL_NULL(prop_name); + } + return; + +failure: + if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + if (fptr->type != ZEND_OVERLOADED_FUNCTION) { + zend_string_release_ex(fptr->common.function_name, 0); + } + zend_free_trampoline(fptr); + } + if (is_closure) { + zval_ptr_dtor(reference); + } } /* }}} */ @@ -2476,7 +2422,7 @@ ZEND_METHOD(reflection_parameter, getName) if (zend_parse_parameters_none() == FAILURE) { return; } - _default_get_name(getThis(), return_value); + _default_get_name(ZEND_THIS, return_value); } /* }}} */ @@ -2611,7 +2557,7 @@ ZEND_METHOD(reflection_parameter, getType) if (!ZEND_TYPE_IS_SET(param->arg_info->type)) { RETURN_NULL(); } - reflection_type_factory(_copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, param->arg_info, return_value); + reflection_type_factory(param->arg_info->type, return_value); } /* }}} */ @@ -2869,7 +2815,7 @@ ZEND_METHOD(reflection_type, allowsNull) } GET_REFLECTION_OBJECT_PTR(param); - RETVAL_BOOL(ZEND_TYPE_ALLOW_NULL(param->arg_info->type)); + RETVAL_BOOL(ZEND_TYPE_ALLOW_NULL(param->type)); } /* }}} */ @@ -2885,16 +2831,18 @@ ZEND_METHOD(reflection_type, isBuiltin) } GET_REFLECTION_OBJECT_PTR(param); - RETVAL_BOOL(ZEND_TYPE_IS_CODE(param->arg_info->type)); + RETVAL_BOOL(ZEND_TYPE_IS_CODE(param->type)); } /* }}} */ /* {{{ reflection_type_name */ static zend_string *reflection_type_name(type_reference *param) { - if (ZEND_TYPE_IS_CLASS(param->arg_info->type)) { - return zend_string_copy(ZEND_TYPE_NAME(param->arg_info->type)); + if (ZEND_TYPE_IS_NAME(param->type)) { + return zend_string_copy(ZEND_TYPE_NAME(param->type)); + } else if (ZEND_TYPE_IS_CE(param->type)) { + return zend_string_copy(ZEND_TYPE_CE(param->type)->name); } else { - char *name = zend_get_type_by_const(ZEND_TYPE_CODE(param->arg_info->type)); + char *name = zend_get_type_by_const(ZEND_TYPE_CODE(param->type)); return zend_string_init(name, strlen(name), 0); } } @@ -2944,7 +2892,7 @@ ZEND_METHOD(reflection_method, export) Constructor. Throws an Exception in case the given method does not exist */ ZEND_METHOD(reflection_method, __construct) { - zval name, *classname; + zval *classname; zval *object, *orig_obj; reflection_object *intern; char *lcname; @@ -2976,7 +2924,7 @@ ZEND_METHOD(reflection_method, __construct) orig_obj = NULL; } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); /* Find the class entry */ @@ -3003,7 +2951,7 @@ ZEND_METHOD(reflection_method, __construct) zval_ptr_dtor_str(&ztmp); } _DO_THROW("The parameter class is expected to be either a string or an object"); - /* returns out of this function */ + return; } if (classname == &ztmp) { @@ -3025,10 +2973,8 @@ ZEND_METHOD(reflection_method, __construct) } efree(lcname); - ZVAL_STR_COPY(&name, mptr->common.scope->name); - reflection_update_property_class(object, &name); - ZVAL_STR_COPY(&name, mptr->common.function_name); - reflection_update_property_name(object, &name); + ZVAL_STR_COPY(reflection_prop_name(object), mptr->common.function_name); + ZVAL_STR_COPY(reflection_prop_class(object), mptr->common.scope->name); intern->ptr = mptr; intern->ref_type = REF_TYPE_FUNCTION; intern->ce = ce; @@ -3071,14 +3017,15 @@ ZEND_METHOD(reflection_method, getClosure) if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope)) { _DO_THROW("Given object is not an instance of the class this method was declared in"); - /* Returns from this function */ + return; } /* This is an original closure object and __invoke is to be called. */ if (Z_OBJCE_P(obj) == zend_ce_closure && (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - ZVAL_COPY(return_value, obj); + Z_ADDREF_P(obj); + ZVAL_OBJ(return_value, Z_OBJ_P(obj)); } else { zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj); } @@ -3113,7 +3060,7 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) "Trying to invoke %s method %s::%s() from scope %s", mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private", ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name), - ZSTR_VAL(Z_OBJCE_P(getThis())->name)); + ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); return; } @@ -3136,7 +3083,7 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) } ZEND_HASH_FOREACH_END(); } - /* In case this is a static method, we should'nt pass an object_ptr + /* In case this is a static method, we shouldn't pass an object_ptr * (which is used as calling context aka $this). We can thus ignore the * first parameter. * @@ -3160,7 +3107,7 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) efree(params); } _DO_THROW("Given object is not an instance of the class this method was declared in"); - /* Returns from this function */ + return; } } @@ -3305,7 +3252,7 @@ ZEND_METHOD(reflection_function, inNamespace) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = _default_load_name(getThis())) == NULL) { + if ((name = _default_load_name(ZEND_THIS)) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -3328,7 +3275,7 @@ ZEND_METHOD(reflection_function, getNamespaceName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = _default_load_name(getThis())) == NULL) { + if ((name = _default_load_name(ZEND_THIS)) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -3351,7 +3298,7 @@ ZEND_METHOD(reflection_function, getShortName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = _default_load_name(getThis())) == NULL) { + if ((name = _default_load_name(ZEND_THIS)) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -3398,7 +3345,7 @@ ZEND_METHOD(reflection_function, getReturnType) RETURN_NULL(); } - reflection_type_factory(_copy_function(fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, &fptr->common.arg_info[-1], return_value); + reflection_type_factory(fptr->common.arg_info[-1].type, return_value); } /* }}} */ @@ -3441,7 +3388,7 @@ ZEND_METHOD(reflection_method, getModifiers) { reflection_object *intern; zend_function *mptr; - uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_IMPLICIT_PUBLIC + uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL; if (zend_parse_parameters_none() == FAILURE) { @@ -3504,7 +3451,7 @@ ZEND_METHOD(reflection_method, setAccessible) return; } - intern = Z_REFLECTION_P(getThis()); + intern = Z_REFLECTION_P(ZEND_THIS); intern->ignore_visibility = visible; } @@ -3514,7 +3461,7 @@ ZEND_METHOD(reflection_method, setAccessible) Constructor. Throws an Exception in case the given class constant does not exist */ ZEND_METHOD(reflection_class_constant, __construct) { - zval *classname, *object, name, cname; + zval *classname, *object; zend_string *constname; reflection_object *intern; zend_class_entry *ce; @@ -3524,7 +3471,7 @@ ZEND_METHOD(reflection_class_constant, __construct) return; } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); /* Find the class entry */ @@ -3543,7 +3490,7 @@ ZEND_METHOD(reflection_class_constant, __construct) default: _DO_THROW("The parameter class is expected to be either a string or an object"); - /* returns out of this function */ + return; } if ((constant = zend_hash_find_ptr(&ce->constants_table, constname)) == NULL) { @@ -3551,15 +3498,12 @@ ZEND_METHOD(reflection_class_constant, __construct) return; } - ZVAL_STR_COPY(&name, constname); - ZVAL_STR_COPY(&cname, ce->name); - intern->ptr = constant; intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; intern->ignore_visibility = 0; - reflection_update_property_name(object, &name); - reflection_update_property_class(object, &cname); + ZVAL_STR_COPY(reflection_prop_name(object), constname); + ZVAL_STR_COPY(reflection_prop_class(object), ce->name); } /* }}} */ @@ -3576,7 +3520,7 @@ ZEND_METHOD(reflection_class_constant, __toString) return; } GET_REFLECTION_OBJECT_PTR(ref); - _default_get_name(getThis(), &name); + _default_get_name(ZEND_THIS, &name); _class_const_string(&str, Z_STRVAL(name), ref, ""); zval_ptr_dtor(&name); RETURN_STR(smart_str_extract(&str)); @@ -3590,7 +3534,7 @@ ZEND_METHOD(reflection_class_constant, getName) if (zend_parse_parameters_none() == FAILURE) { return; } - _default_get_name(getThis(), return_value); + _default_get_name(ZEND_THIS, return_value); } /* }}} */ @@ -3611,7 +3555,7 @@ static void _class_constant_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) / Returns whether this constant is public */ ZEND_METHOD(reflection_class_constant, isPublic) { - _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC); + _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC); } /* }}} */ @@ -3713,32 +3657,33 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob { zval *argument; zval *object; - zval classname; reflection_object *intern; zend_class_entry *ce; if (is_object) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &argument) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT(argument) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &argument) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(argument) + ZEND_PARSE_PARAMETERS_END(); } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); if (Z_TYPE_P(argument) == IS_OBJECT) { - ZVAL_STR_COPY(&classname, Z_OBJCE_P(argument)->name); - reflection_update_property_name(object, &classname); + ZVAL_STR_COPY(reflection_prop_name(object), Z_OBJCE_P(argument)->name); intern->ptr = Z_OBJCE_P(argument); if (is_object) { ZVAL_COPY(&intern->obj, argument); } } else { - convert_to_string_ex(argument); + if (!try_convert_to_string(argument)) { + return; + } + if ((ce = zend_lookup_class(Z_STR_P(argument))) == NULL) { if (!EG(exception)) { zend_throw_exception_ex(reflection_exception_ptr, -1, "Class %s does not exist", Z_STRVAL_P(argument)); @@ -3746,9 +3691,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob return; } - ZVAL_STR_COPY(&classname, ce->name); - reflection_update_property_name(object, &classname); - + ZVAL_STR_COPY(reflection_prop_name(object), ce->name); intern->ptr = ce; } intern->ref_type = REF_TYPE_OTHER; @@ -3771,9 +3714,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value zend_string *key; ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) { - if (((prop_info->flags & ZEND_ACC_SHADOW) && - prop_info->ce != ce) || - ((prop_info->flags & ZEND_ACC_PROTECTED) && + if (((prop_info->flags & ZEND_ACC_PROTECTED) && !zend_check_protected(prop_info->ce, ce)) || ((prop_info->flags & ZEND_ACC_PRIVATE) && prop_info->ce != ce)) { @@ -3786,7 +3727,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; } - if (!prop) { + if (!prop || (prop_info->type && Z_ISUNDEF_P(prop))) { continue; } @@ -3797,7 +3738,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ if (Z_TYPE(prop_copy) == IS_CONSTANT_AST) { - if (UNEXPECTED(zval_update_constant_ex(&prop_copy, NULL) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(&prop_copy, ce) != SUCCESS)) { return; } } @@ -3847,7 +3788,7 @@ ZEND_METHOD(reflection_class, getStaticPropertyValue) if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { return; } - prop = zend_std_get_static_property(ce, name, 1); + prop = zend_std_get_static_property(ce, name, BP_VAR_IS); if (!prop) { if (def_value) { ZVAL_COPY(return_value, def_value); @@ -3868,6 +3809,7 @@ ZEND_METHOD(reflection_class, setStaticPropertyValue) { reflection_object *intern; zend_class_entry *ce; + zend_property_info *prop_info; zend_string *name; zval *variable_ptr, *value; @@ -3880,15 +3822,30 @@ ZEND_METHOD(reflection_class, setStaticPropertyValue) if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { return; } - variable_ptr = zend_std_get_static_property(ce, name, 1); + variable_ptr = zend_std_get_static_property_with_info(ce, name, BP_VAR_W, &prop_info); if (!variable_ptr) { + zend_clear_exception(); zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); return; } - ZVAL_DEREF(variable_ptr); + + if (Z_ISREF_P(variable_ptr)) { + zend_reference *ref = Z_REF_P(variable_ptr); + variable_ptr = Z_REFVAL_P(variable_ptr); + + if (!zend_verify_ref_assignable_zval(ref, value, 0)) { + return; + } + } + + if (prop_info->type && !zend_verify_property_type(prop_info, value, 0)) { + return; + } + zval_ptr_dtor(variable_ptr); ZVAL_COPY(variable_ptr, value); + } /* }}} */ @@ -3936,7 +3893,7 @@ ZEND_METHOD(reflection_class, getName) if (zend_parse_parameters_none() == FAILURE) { return; } - _default_get_name(getThis(), return_value); + _default_get_name(ZEND_THIS, return_value); } /* }}} */ @@ -4083,24 +4040,16 @@ ZEND_METHOD(reflection_class, hasMethod) { reflection_object *intern; zend_class_entry *ce; - char *name, *lc_name; - size_t name_len; + zend_string *name, *lc_name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ce); - lc_name = zend_str_tolower_dup(name, name_len); - if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) - && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) - || zend_hash_str_exists(&ce->function_table, lc_name, name_len)) { - efree(lc_name); - RETURN_TRUE; - } else { - efree(lc_name); - RETURN_FALSE; - } + lc_name = zend_string_tolower(name); + RETVAL_BOOL(zend_hash_exists(&ce->function_table, lc_name) || is_closure_invoke(ce, lc_name)); + zend_string_release(lc_name); } /* }}} */ @@ -4112,40 +4061,33 @@ ZEND_METHOD(reflection_class, getMethod) zend_class_entry *ce; zend_function *mptr; zval obj_tmp; - char *name, *lc_name; - size_t name_len; + zend_string *name, *lc_name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ce); - lc_name = zend_str_tolower_dup(name, name_len); - if (ce == zend_ce_closure && !Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) - && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + lc_name = zend_string_tolower(name); + if (!Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name) && (mptr = zend_get_closure_invoke_method(Z_OBJ(intern->obj))) != NULL) { /* don't assign closure_object since we only reflect the invoke handler method and not the closure definition itself */ reflection_method_factory(ce, mptr, NULL, return_value); - efree(lc_name); - } else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) - && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + } else if (Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name) && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) { /* don't assign closure_object since we only reflect the invoke handler method and not the closure definition itself */ reflection_method_factory(ce, mptr, NULL, return_value); zval_ptr_dtor(&obj_tmp); - efree(lc_name); - } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lc_name, name_len)) != NULL) { + } else if ((mptr = zend_hash_find_ptr(&ce->function_table, lc_name)) != NULL) { reflection_method_factory(ce, mptr, NULL, return_value); - efree(lc_name); } else { - efree(lc_name); zend_throw_exception_ex(reflection_exception_ptr, 0, - "Method %s does not exist", name); - return; + "Method %s does not exist", ZSTR_VAL(name)); } + zend_string_release(lc_name); } /* }}} */ @@ -4160,25 +4102,13 @@ static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, } /* }}} */ -/* {{{ _addmethod */ -static int _addmethod_va(zval *el, int num_args, va_list args, zend_hash_key *hash_key) -{ - zend_function *mptr = (zend_function*)Z_PTR_P(el); - zend_class_entry *ce = *va_arg(args, zend_class_entry**); - zval *retval = va_arg(args, zval*); - long filter = va_arg(args, long); - - _addmethod(mptr, ce, retval, filter); - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - /* {{{ proto public ReflectionMethod[] ReflectionClass::getMethods([long $filter]) Returns an array of this class' methods */ ZEND_METHOD(reflection_class, getMethods) { reflection_object *intern; zend_class_entry *ce; + zend_function *mptr; zend_long filter = 0; zend_bool filter_is_null = 1; @@ -4193,7 +4123,9 @@ ZEND_METHOD(reflection_class, getMethods) GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - zend_hash_apply_with_arguments(&ce->function_table, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter); + ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) { + _addmethod(mptr, ce, return_value, filter); + } ZEND_HASH_FOREACH_END(); if (instanceof_function(ce, zend_ce_closure)) { zend_bool has_obj = Z_TYPE(intern->obj) != IS_UNDEF; @@ -4232,12 +4164,12 @@ ZEND_METHOD(reflection_class, hasProperty) GET_REFLECTION_OBJECT_PTR(ce); if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) { - if (property_info->flags & ZEND_ACC_SHADOW) { + if ((property_info->flags & ZEND_ACC_PRIVATE) && property_info->ce != ce) { RETURN_FALSE; } RETURN_TRUE; } else { - if (Z_TYPE(intern->obj) != IS_UNDEF && Z_OBJ_HANDLER(intern->obj, has_property)) { + if (Z_TYPE(intern->obj) != IS_UNDEF) { ZVAL_STR_COPY(&property, name); if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, NULL)) { zval_ptr_dtor(&property); @@ -4267,20 +4199,20 @@ ZEND_METHOD(reflection_class, getProperty) GET_REFLECTION_OBJECT_PTR(ce); if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) { - if ((property_info->flags & ZEND_ACC_SHADOW) == 0) { - reflection_property_factory(ce, name, property_info, return_value); + if (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce) { + reflection_property_factory(ce, name, property_info, return_value, 0); return; } } else if (Z_TYPE(intern->obj) != IS_UNDEF) { /* Check for dynamic properties */ if (zend_hash_exists(Z_OBJ_HT(intern->obj)->get_properties(&intern->obj), name)) { zend_property_info property_info_tmp; - property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC; + property_info_tmp.flags = ZEND_ACC_PUBLIC; property_info_tmp.name = name; property_info_tmp.doc_comment = NULL; property_info_tmp.ce = ce; - reflection_property_factory(ce, name, &property_info_tmp, return_value); + reflection_property_factory(ce, name, &property_info_tmp, return_value, 1); return; } } @@ -4309,7 +4241,10 @@ ZEND_METHOD(reflection_class, getProperty) } ce = ce2; - if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len)) != NULL && (property_info->flags & ZEND_ACC_SHADOW) == 0) { + property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len); + if (property_info != NULL + && (!(property_info->flags & ZEND_ACC_PRIVATE) + || property_info->ce == ce)) { reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value); return; } @@ -4320,59 +4255,45 @@ ZEND_METHOD(reflection_class, getProperty) /* }}} */ /* {{{ _addproperty */ -static int _addproperty(zval *el, int num_args, va_list args, zend_hash_key *hash_key) +static void _addproperty(zend_property_info *pptr, zend_string *key, zend_class_entry *ce, zval *retval, long filter) { - zval property; - zend_property_info *pptr = (zend_property_info*)Z_PTR_P(el); - zend_class_entry *ce = *va_arg(args, zend_class_entry**); - zval *retval = va_arg(args, zval*); - long filter = va_arg(args, long); - - if (pptr->flags & ZEND_ACC_SHADOW) { - return 0; + if ((pptr->flags & ZEND_ACC_PRIVATE) && pptr->ce != ce) { + return; } if (pptr->flags & filter) { - const char *class_name, *prop_name; - size_t prop_name_len; - zend_unmangle_property_name_ex(pptr->name, &class_name, &prop_name, &prop_name_len); - reflection_property_factory_str(ce, prop_name, prop_name_len, pptr, &property); + zval property; + reflection_property_factory(ce, key, pptr, &property, 0); add_next_index_zval(retval, &property); } - return 0; } /* }}} */ /* {{{ _adddynproperty */ -static int _adddynproperty(zval *ptr, int num_args, va_list args, zend_hash_key *hash_key) +static void _adddynproperty(zval *ptr, zend_string *key, zend_class_entry *ce, zval *retval) { + zend_property_info property_info; zval property; - zend_class_entry *ce = *va_arg(args, zend_class_entry**); - zval *retval = va_arg(args, zval*); /* under some circumstances, the properties hash table may contain numeric - * properties (e.g. when casting from array). This is a WONT FIX bug, at + * properties (e.g. when casting from array). This is a WON'T FIX bug, at * least for the moment. Ignore these */ - if (hash_key->key == NULL) { - return 0; + if (key == NULL) { + return; } - if (ZSTR_VAL(hash_key->key)[0] == '\0') { - return 0; /* non public cannot be dynamic */ + /* Not a dynamic property */ + if (Z_TYPE_P(ptr) == IS_INDIRECT) { + return; } - if (zend_get_property_info(ce, hash_key->key, 1) == NULL) { - zend_property_info property_info; - - property_info.doc_comment = NULL; - property_info.flags = ZEND_ACC_IMPLICIT_PUBLIC; - property_info.name = hash_key->key; - property_info.ce = ce; - property_info.offset = -1; - reflection_property_factory(ce, hash_key->key, &property_info, &property); - add_next_index_zval(retval, &property); - } - return 0; + property_info.doc_comment = NULL; + property_info.flags = ZEND_ACC_PUBLIC; + property_info.name = key; + property_info.ce = ce; + property_info.offset = -1; + reflection_property_factory(ce, key, &property_info, &property, 1); + add_next_index_zval(retval, &property); } /* }}} */ @@ -4382,6 +4303,8 @@ ZEND_METHOD(reflection_class, getProperties) { reflection_object *intern; zend_class_entry *ce; + zend_string *key; + zend_property_info *prop_info; zend_long filter = 0; zend_bool filter_is_null = 1; @@ -4396,11 +4319,16 @@ ZEND_METHOD(reflection_class, getProperties) GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - zend_hash_apply_with_arguments(&ce->properties_info, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter); + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) { + _addproperty(prop_info, key, ce, return_value, filter); + } ZEND_HASH_FOREACH_END(); - if (Z_TYPE(intern->obj) != IS_UNDEF && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT(intern->obj)->get_properties) { + if (Z_TYPE(intern->obj) != IS_UNDEF && (filter & ZEND_ACC_PUBLIC) != 0) { HashTable *properties = Z_OBJ_HT(intern->obj)->get_properties(&intern->obj); - zend_hash_apply_with_arguments(properties, (apply_func_args_t) _adddynproperty, 2, &ce, return_value); + zval *prop; + ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, prop) { + _adddynproperty(prop, key, ce, return_value); + } ZEND_HASH_FOREACH_END(); } } /* }}} */ @@ -4661,7 +4589,7 @@ ZEND_METHOD(reflection_class, isInstance) } /* }}} */ -/* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...) +/* {{{ proto public object ReflectionClass::newInstance(mixed* args, ...) Returns an instance of this class */ ZEND_METHOD(reflection_class, newInstance) { @@ -4735,7 +4663,7 @@ ZEND_METHOD(reflection_class, newInstance) } /* }}} */ -/* {{{ proto public stdclass ReflectionClass::newInstanceWithoutConstructor() +/* {{{ proto public object ReflectionClass::newInstanceWithoutConstructor() Returns an instance of this class without invoking its constructor */ ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) { @@ -4744,7 +4672,8 @@ ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) GET_REFLECTION_OBJECT_PTR(ce); - if (ce->create_object != NULL && ce->ce_flags & ZEND_ACC_FINAL) { + if (ce->type == ZEND_INTERNAL_CLASS + && ce->create_object != NULL && (ce->ce_flags & ZEND_ACC_FINAL)) { zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s is an internal class marked as final that cannot be instantiated without invoking its constructor", ZSTR_VAL(ce->name)); return; } @@ -4753,7 +4682,7 @@ ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) } /* }}} */ -/* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args]) +/* {{{ proto public object ReflectionClass::newInstanceArgs([array args]) Returns an instance of this class */ ZEND_METHOD(reflection_class, newInstanceArgs) { @@ -4855,6 +4784,7 @@ ZEND_METHOD(reflection_class, getInterfaces) if (ce->num_interfaces) { uint32_t i; + ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); array_init(return_value); for (i=0; i < ce->num_interfaces; i++) { zval interface; @@ -4862,7 +4792,7 @@ ZEND_METHOD(reflection_class, getInterfaces) zend_hash_update(Z_ARRVAL_P(return_value), ce->interfaces[i]->name, &interface); } } else { - ZVAL_EMPTY_ARRAY(return_value); + RETURN_EMPTY_ARRAY(); } } /* }}} */ @@ -4882,10 +4812,10 @@ ZEND_METHOD(reflection_class, getInterfaceNames) if (!ce->num_interfaces) { /* Return an empty array if this class implements no interfaces */ - ZVAL_EMPTY_ARRAY(return_value); - return; + RETURN_EMPTY_ARRAY(); } + ZEND_ASSERT(ce->ce_flags & ZEND_ACC_LINKED); array_init(return_value); for (i=0; i < ce->num_interfaces; i++) { @@ -4908,16 +4838,20 @@ ZEND_METHOD(reflection_class, getTraits) GET_REFLECTION_OBJECT_PTR(ce); if (!ce->num_traits) { - ZVAL_EMPTY_ARRAY(return_value); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); for (i=0; i < ce->num_traits; i++) { zval trait; - zend_reflection_class_factory(ce->traits[i], &trait); - zend_hash_update(Z_ARRVAL_P(return_value), ce->traits[i]->name, &trait); + zend_class_entry *trait_ce; + + trait_ce = zend_fetch_class_by_name(ce->trait_names[i].name, + ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT); + ZEND_ASSERT(trait_ce); + zend_reflection_class_factory(trait_ce, &trait); + zend_hash_update(Z_ARRVAL_P(return_value), ce->trait_names[i].name, &trait); } } /* }}} */ @@ -4936,14 +4870,13 @@ ZEND_METHOD(reflection_class, getTraitNames) GET_REFLECTION_OBJECT_PTR(ce); if (!ce->num_traits) { - ZVAL_EMPTY_ARRAY(return_value); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); for (i=0; i < ce->num_traits; i++) { - add_next_index_str(return_value, zend_string_copy(ce->traits[i]->name)); + add_next_index_str(return_value, zend_string_copy(ce->trait_names[i].name)); } } /* }}} */ @@ -4978,7 +4911,7 @@ ZEND_METHOD(reflection_class, getTraitAliases) i++; } } else { - ZVAL_EMPTY_ARRAY(return_value); + RETURN_EMPTY_ARRAY(); } } /* }}} */ @@ -5166,7 +5099,7 @@ ZEND_METHOD(reflection_class, inNamespace) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = _default_load_name(getThis())) == NULL) { + if ((name = _default_load_name(ZEND_THIS)) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -5189,7 +5122,7 @@ ZEND_METHOD(reflection_class, getNamespaceName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = _default_load_name(getThis())) == NULL) { + if ((name = _default_load_name(ZEND_THIS)) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -5212,7 +5145,7 @@ ZEND_METHOD(reflection_class, getShortName) if (zend_parse_parameters_none() == FAILURE) { return; } - if ((name = _default_load_name(getThis())) == NULL) { + if ((name = _default_load_name(ZEND_THIS)) == NULL) { RETURN_FALSE; } if (Z_TYPE_P(name) == IS_STRING @@ -5261,7 +5194,7 @@ ZEND_METHOD(reflection_class_constant, export) Constructor. Throws an Exception in case the given property does not exist */ ZEND_METHOD(reflection_property, __construct) { - zval propname, cname, *classname; + zval *classname; zend_string *name; int dynam_prop = 0; zval *object; @@ -5274,7 +5207,7 @@ ZEND_METHOD(reflection_property, __construct) return; } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); /* Find the class entry */ @@ -5293,12 +5226,15 @@ ZEND_METHOD(reflection_property, __construct) default: _DO_THROW("The parameter class is expected to be either a string or an object"); - /* returns out of this function */ + return; } - if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) == NULL || (property_info->flags & ZEND_ACC_SHADOW)) { + property_info = zend_hash_find_ptr(&ce->properties_info, name); + if (property_info == NULL + || ((property_info->flags & ZEND_ACC_PRIVATE) + && property_info->ce != ce)) { /* Check for dynamic properties */ - if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) { + if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT) { if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname), name)) { dynam_prop = 1; } @@ -5321,26 +5257,24 @@ ZEND_METHOD(reflection_property, __construct) } } + ZVAL_STR_COPY(reflection_prop_name(object), name); if (dynam_prop == 0) { - ZVAL_STR_COPY(&cname, property_info->ce->name); + ZVAL_STR_COPY(reflection_prop_class(object), property_info->ce->name); } else { - ZVAL_STR_COPY(&cname, ce->name); + ZVAL_STR_COPY(reflection_prop_class(object), ce->name); } - reflection_update_property_class(object, &cname); - - ZVAL_STR_COPY(&propname, name); - reflection_update_property_name(object, &propname); reference = (property_reference*) emalloc(sizeof(property_reference)); if (dynam_prop) { - reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC; + reference->prop.flags = ZEND_ACC_PUBLIC; reference->prop.name = name; reference->prop.doc_comment = NULL; reference->prop.ce = ce; + reference->dynamic = 1; } else { reference->prop = *property_info; + reference->dynamic = 0; } - reference->ce = ce; reference->unmangled_name = zend_string_copy(name); intern->ptr = reference; intern->ref_type = REF_TYPE_PROPERTY; @@ -5361,7 +5295,7 @@ ZEND_METHOD(reflection_property, __toString) return; } GET_REFLECTION_OBJECT_PTR(ref); - _property_string(&str, &ref->prop, ZSTR_VAL(ref->unmangled_name), ""); + _property_string(&str, &ref->prop, ZSTR_VAL(ref->unmangled_name), "", ref->dynamic); RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -5373,7 +5307,7 @@ ZEND_METHOD(reflection_property, getName) if (zend_parse_parameters_none() == FAILURE) { return; } - _default_get_name(getThis(), return_value); + _default_get_name(ZEND_THIS, return_value); } /* }}} */ @@ -5394,7 +5328,7 @@ static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ Returns whether this property is public */ ZEND_METHOD(reflection_property, isPublic) { - _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC); + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC); } /* }}} */ @@ -5426,7 +5360,14 @@ ZEND_METHOD(reflection_property, isStatic) Returns whether this property is default (declared at compilation time). */ ZEND_METHOD(reflection_property, isDefault) { - _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC); + reflection_object *intern; + property_reference *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + RETURN_BOOL(!ref->dynamic); } /* }}} */ @@ -5436,7 +5377,7 @@ ZEND_METHOD(reflection_property, getModifiers) { reflection_object *intern; property_reference *ref; - uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_IMPLICIT_PUBLIC | ZEND_ACC_STATIC; + uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5458,15 +5399,15 @@ ZEND_METHOD(reflection_property, getValue) GET_REFLECTION_OBJECT_PTR(ref); - if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) { - name = _default_load_name(getThis()); + if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { + name = _default_load_name(ZEND_THIS); zend_throw_exception_ex(reflection_exception_ptr, 0, "Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name)); return; } if (ref->prop.flags & ZEND_ACC_STATIC) { - member_p = zend_read_static_property_ex(ref->ce, ref->unmangled_name, 0); + member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 0); if (member_p) { ZVAL_COPY_DEREF(return_value, member_p); } @@ -5479,10 +5420,10 @@ ZEND_METHOD(reflection_property, getValue) if (!instanceof_function(Z_OBJCE_P(object), ref->prop.ce)) { _DO_THROW("Given object is not an instance of the class this property was declared in"); - /* Returns from this function */ + return; } - member_p = zend_read_property_ex(ref->ce, object, ref->unmangled_name, 0, &rv); + member_p = zend_read_property_ex(intern->ce, object, ref->unmangled_name, 0, &rv); if (member_p != &rv) { ZVAL_COPY_DEREF(return_value, member_p); } else { @@ -5508,7 +5449,7 @@ ZEND_METHOD(reflection_property, setValue) GET_REFLECTION_OBJECT_PTR(ref); if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { - name = _default_load_name(getThis()); + name = _default_load_name(ZEND_THIS); zend_throw_exception_ex(reflection_exception_ptr, 0, "Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name)); return; @@ -5521,13 +5462,62 @@ ZEND_METHOD(reflection_property, setValue) } } - zend_update_static_property_ex(ref->ce, ref->unmangled_name, value); + zend_update_static_property_ex(intern->ce, ref->unmangled_name, value); } else { if (zend_parse_parameters(ZEND_NUM_ARGS(), "oz", &object, &value) == FAILURE) { return; } - zend_update_property_ex(ref->ce, object, ref->unmangled_name, value); + zend_update_property_ex(intern->ce, object, ref->unmangled_name, value); + } +} +/* }}} */ + +/* {{{ proto public mixed ReflectionProperty::isInitialized([stdclass object]) + Returns this property's value */ +ZEND_METHOD(reflection_property, isInitialized) +{ + reflection_object *intern; + property_reference *ref; + zval *object, *name; + zval *member_p = NULL; + + GET_REFLECTION_OBJECT_PTR(ref); + + if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { + name = _default_load_name(getThis()); + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name)); + return; + } + + if (ref->prop.flags & ZEND_ACC_STATIC) { + member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 1); + if (member_p) { + RETURN_BOOL(!Z_ISUNDEF_P(member_p)) + } + RETURN_FALSE; + } else { + zval name_zv; + zend_class_entry *old_scope; + int retval; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) { + return; + } + + if (!instanceof_function(Z_OBJCE_P(object), ref->prop.ce)) { + _DO_THROW("Given object is not an instance of the class this property was declared in"); + return; + } + + old_scope = EG(fake_scope); + EG(fake_scope) = intern->ce; + ZVAL_STR(&name_zv, ref->unmangled_name); + retval = Z_OBJ_HT_P(object)->has_property(object, &name_zv, ZEND_PROPERTY_EXISTS, NULL); + EG(fake_scope) = old_scope; + + RETVAL_BOOL(retval); } } /* }}} */ @@ -5546,9 +5536,9 @@ ZEND_METHOD(reflection_property, getDeclaringClass) } GET_REFLECTION_OBJECT_PTR(ref); - ce = tmp_ce = ref->ce; + ce = tmp_ce = intern->ce; while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) { - if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) { + if (tmp_info->flags & ZEND_ACC_PRIVATE) { /* it's a private property, so it can't be inherited */ break; } @@ -5593,12 +5583,50 @@ ZEND_METHOD(reflection_property, setAccessible) return; } - intern = Z_REFLECTION_P(getThis()); + intern = Z_REFLECTION_P(ZEND_THIS); intern->ignore_visibility = visible; } /* }}} */ +/* {{{ proto public ReflectionType ReflectionProperty::getType() + Returns the type associated with the property */ +ZEND_METHOD(reflection_property, getType) +{ + reflection_object *intern; + property_reference *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ZEND_TYPE_IS_SET(ref->prop.type)) { + RETURN_NULL(); + } + + reflection_type_factory(ref->prop.type, return_value); +} +/* }}} */ + +/* {{{ proto public bool ReflectionProperty::hasType() + Returns whether property has a type */ +ZEND_METHOD(reflection_property, hasType) +{ + reflection_object *intern; + property_reference *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ref); + + RETVAL_BOOL(ZEND_TYPE_IS_SET(ref->prop.type)); +} +/* }}} */ + /* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ ZEND_METHOD(reflection_extension, export) @@ -5611,7 +5639,6 @@ ZEND_METHOD(reflection_extension, export) Constructor. Throws an Exception in case the given extension does not exist */ ZEND_METHOD(reflection_extension, __construct) { - zval name; zval *object; char *lcname; reflection_object *intern; @@ -5624,7 +5651,7 @@ ZEND_METHOD(reflection_extension, __construct) return; } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); lcname = do_alloca(name_len + 1, use_heap); zend_str_tolower_copy(lcname, name_str, name_len); @@ -5635,8 +5662,7 @@ ZEND_METHOD(reflection_extension, __construct) return; } free_alloca(lcname, use_heap); - ZVAL_STRING(&name, module->name); - reflection_update_property_name(object, &name); + ZVAL_STRING(reflection_prop_name(object), module->name); intern->ptr = module; intern->ref_type = REF_TYPE_OTHER; intern->ce = NULL; @@ -5667,7 +5693,7 @@ ZEND_METHOD(reflection_extension, getName) if (zend_parse_parameters_none() == FAILURE) { return; } - _default_get_name(getThis(), return_value); + _default_get_name(ZEND_THIS, return_value); } /* }}} */ @@ -5717,27 +5743,13 @@ ZEND_METHOD(reflection_extension, getFunctions) } /* }}} */ -static int _addconstant(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ -{ - zval const_val; - zend_constant *constant = (zend_constant*)Z_PTR_P(el); - zval *retval = va_arg(args, zval*); - int number = va_arg(args, int); - - if (number == ZEND_CONSTANT_MODULE_NUMBER(constant)) { - ZVAL_COPY_OR_DUP(&const_val, &constant->value); - zend_hash_update(Z_ARRVAL_P(retval), constant->name, &const_val); - } - return 0; -} -/* }}} */ - /* {{{ proto public array ReflectionExtension::getConstants() Returns an associative array containing this extension's constants and their values */ ZEND_METHOD(reflection_extension, getConstants) { reflection_object *intern; zend_module_entry *module; + zend_constant *constant; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5745,28 +5757,28 @@ ZEND_METHOD(reflection_extension, getConstants) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _addconstant, 2, return_value, module->module_number); + ZEND_HASH_FOREACH_PTR(EG(zend_constants), constant) { + if (module->module_number == ZEND_CONSTANT_MODULE_NUMBER(constant)) { + zval const_val; + ZVAL_COPY_OR_DUP(&const_val, &constant->value); + zend_hash_update(Z_ARRVAL_P(return_value), constant->name, &const_val); + } + } ZEND_HASH_FOREACH_END(); } /* }}} */ /* {{{ _addinientry */ -static int _addinientry(zval *el, int num_args, va_list args, zend_hash_key *hash_key) +static void _addinientry(zend_ini_entry *ini_entry, zval *retval, int number) { - zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el); - zval *retval = va_arg(args, zval*); - int number = va_arg(args, int); - if (number == ini_entry->module_number) { + zval zv; if (ini_entry->value) { - zval zv; - ZVAL_STR_COPY(&zv, ini_entry->value); - zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &zv); } else { - zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &EG(uninitialized_zval)); + ZVAL_NULL(&zv); } + zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &zv); } - return ZEND_HASH_APPLY_KEEP; } /* }}} */ @@ -5776,6 +5788,7 @@ ZEND_METHOD(reflection_extension, getINIEntries) { reflection_object *intern; zend_module_entry *module; + zend_ini_entry *ini_entry; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5783,36 +5796,33 @@ ZEND_METHOD(reflection_extension, getINIEntries) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _addinientry, 2, return_value, module->module_number); + ZEND_HASH_FOREACH_PTR(EG(ini_directives), ini_entry) { + _addinientry(ini_entry, return_value, module->module_number); + } ZEND_HASH_FOREACH_END(); } /* }}} */ /* {{{ add_extension_class */ -static int add_extension_class(zval *zv, int num_args, va_list args, zend_hash_key *hash_key) +static void add_extension_class(zend_class_entry *ce, zend_string *key, zval *class_array, zend_module_entry *module, zend_bool add_reflection_class) { - zend_class_entry *ce = Z_PTR_P(zv); - zval *class_array = va_arg(args, zval*), zclass; - struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*); - int add_reflection_class = va_arg(args, int); - - if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { + if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { zend_string *name; - if (zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) { - /* This is an class alias, use alias name */ - name = hash_key->key; + if (!zend_string_equals_ci(ce->name, key)) { + /* This is a class alias, use alias name */ + name = key; } else { /* Use class name */ name = ce->name; } if (add_reflection_class) { + zval zclass; zend_reflection_class_factory(ce, &zclass); zend_hash_update(Z_ARRVAL_P(class_array), name, &zclass); } else { add_next_index_str(class_array, zend_string_copy(name)); } } - return ZEND_HASH_APPLY_KEEP; } /* }}} */ @@ -5822,6 +5832,8 @@ ZEND_METHOD(reflection_extension, getClasses) { reflection_object *intern; zend_module_entry *module; + zend_string *key; + zend_class_entry *ce; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5829,7 +5841,9 @@ ZEND_METHOD(reflection_extension, getClasses) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 1); + ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { + add_extension_class(ce, key, return_value, module, 1); + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -5839,6 +5853,8 @@ ZEND_METHOD(reflection_extension, getClassNames) { reflection_object *intern; zend_module_entry *module; + zend_string *key; + zend_class_entry *ce; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5846,7 +5862,9 @@ ZEND_METHOD(reflection_extension, getClassNames) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 0); + ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { + add_extension_class(ce, key, return_value, module, 0); + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -5867,8 +5885,7 @@ ZEND_METHOD(reflection_extension, getDependencies) if (!dep) { - ZVAL_EMPTY_ARRAY(return_value); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); @@ -5977,7 +5994,6 @@ ZEND_METHOD(reflection_zend_extension, export) Constructor. Throws an Exception in case the given Zend extension does not exist */ ZEND_METHOD(reflection_zend_extension, __construct) { - zval name; zval *object; reflection_object *intern; zend_extension *extension; @@ -5988,7 +6004,7 @@ ZEND_METHOD(reflection_zend_extension, __construct) return; } - object = getThis(); + object = ZEND_THIS; intern = Z_REFLECTION_P(object); extension = zend_get_extension(name_str); @@ -5997,8 +6013,7 @@ ZEND_METHOD(reflection_zend_extension, __construct) "Zend Extension %s does not exist", name_str); return; } - ZVAL_STRING(&name, extension->name); - reflection_update_property_name(object, &name); + ZVAL_STRING(reflection_prop_name(object), extension->name); intern->ptr = extension; intern->ref_type = REF_TYPE_OTHER; intern->ce = NULL; @@ -6118,6 +6133,101 @@ ZEND_METHOD(reflection_zend_extension, getCopyright) } /* }}} */ +/* {{{ proto public ReflectionReference::__construct() + * Dummy constructor -- always throws ReflectionExceptions. */ +ZEND_METHOD(reflection_reference, __construct) +{ + _DO_THROW( + "Cannot directly instantiate ReflectionReference. " + "Use ReflectionReference::fromArrayElement() instead" + ); +} +/* }}} */ + +static zend_bool is_ignorable_reference(HashTable *ht, zval *ref) { + if (Z_REFCOUNT_P(ref) != 1) { + return 0; + } + + /* Directly self-referential arrays are treated as proper references + * in zend_array_dup() despite rc=1. */ + return Z_TYPE_P(Z_REFVAL_P(ref)) != IS_ARRAY || Z_ARRVAL_P(Z_REFVAL_P(ref)) != ht; +} + +/* {{{ proto public ReflectionReference|null ReflectionReference::fromArrayElement(array array, mixed key) + * Create ReflectionReference for array item. Returns null if not a reference. */ +ZEND_METHOD(reflection_reference, fromArrayElement) +{ + HashTable *ht; + zval *key, *item; + reflection_object *intern; + + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "hz", &ht, &key) == FAILURE) { + return; + } + + if (Z_TYPE_P(key) == IS_LONG) { + item = zend_hash_index_find(ht, Z_LVAL_P(key)); + } else if (Z_TYPE_P(key) == IS_STRING) { + item = zend_symtable_find(ht, Z_STR_P(key)); + } else { + zend_type_error("Key must be array or string"); + return; + } + + if (!item) { + _DO_THROW("Array key not found"); + return; + } + + if (Z_TYPE_P(item) != IS_REFERENCE || is_ignorable_reference(ht, item)) { + RETURN_NULL(); + } + + object_init_ex(return_value, reflection_reference_ptr); + intern = Z_REFLECTION_P(return_value); + ZVAL_COPY(&intern->obj, item); + intern->ref_type = REF_TYPE_OTHER; +} +/* }}} */ + +/* {{{ proto public int|string ReflectionReference::getId() + * Returns a unique identifier for the reference. + * The format of the return value is unspecified and may change. */ +ZEND_METHOD(reflection_reference, getId) +{ + reflection_object *intern; + unsigned char digest[20]; + PHP_SHA1_CTX context; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + intern = Z_REFLECTION_P(getThis()); + if (Z_TYPE(intern->obj) != IS_REFERENCE) { + _DO_THROW("Corrupted ReflectionReference object"); + return; + } + + if (!REFLECTION_G(key_initialized)) { + if (php_random_bytes_throw(&REFLECTION_G(key_initialized), 16) == FAILURE) { + return; + } + + REFLECTION_G(key_initialized) = 1; + } + + /* SHA1(ref || key) to avoid directly exposing memory addresses. */ + PHP_SHA1Init(&context); + PHP_SHA1Update(&context, (unsigned char *) &Z_REF(intern->obj), sizeof(zend_reference *)); + PHP_SHA1Update(&context, REFLECTION_G(key), REFLECTION_KEY_LEN); + PHP_SHA1Final(digest, &context); + + RETURN_STRINGL((char *) digest, sizeof(digest)); +} +/* }}} */ + /* {{{ method tables */ static const zend_function_entry reflection_exception_functions[] = { PHP_FE_END @@ -6138,12 +6248,11 @@ ZEND_END_ARG_INFO() static const zend_function_entry reflection_functions[] = { ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_DEP_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_FE_END }; static const zend_function_entry reflector_functions[] = { - ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC) ZEND_ABSTRACT_ME(reflector, __toString, arginfo_reflection__void) PHP_FE_END }; @@ -6198,7 +6307,7 @@ static const zend_function_entry reflection_function_abstract_functions[] = { static const zend_function_entry reflection_function_functions[] = { ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0) ZEND_ME(reflection_function, __toString, arginfo_reflection__void, 0) - ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_function, isDisabled, arginfo_reflection__void, 0) ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0) ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0) @@ -6255,7 +6364,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_getClosure, 0) ZEND_END_ARG_INFO() static const zend_function_entry reflection_method_functions[] = { - ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0) ZEND_ME(reflection_method, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_method, isPublic, arginfo_reflection__void, 0) @@ -6353,7 +6462,7 @@ ZEND_END_ARG_INFO() static const zend_function_entry reflection_class_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) - ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0) ZEND_ME(reflection_class, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_class, getName, arginfo_reflection__void, 0) @@ -6420,7 +6529,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0) ZEND_END_ARG_INFO() static const zend_function_entry reflection_object_functions[] = { - ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0) PHP_FE_END }; @@ -6446,18 +6555,23 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_isInitialized, 0, 0, 0) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setAccessible, 0) ZEND_ARG_INFO(0, visible) ZEND_END_ARG_INFO() static const zend_function_entry reflection_property_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) - ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0) ZEND_ME(reflection_property, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_property, getName, arginfo_reflection__void, 0) ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0) ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0) + ZEND_ME(reflection_property, isInitialized, arginfo_reflection_property_isInitialized, 0) ZEND_ME(reflection_property, isPublic, arginfo_reflection__void, 0) ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0) ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0) @@ -6467,6 +6581,8 @@ static const zend_function_entry reflection_property_functions[] = { ZEND_ME(reflection_property, getDeclaringClass, arginfo_reflection__void, 0) ZEND_ME(reflection_property, getDocComment, arginfo_reflection__void, 0) ZEND_ME(reflection_property, setAccessible, arginfo_reflection_property_setAccessible, 0) + ZEND_ME(reflection_property, getType, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, hasType, arginfo_reflection__void, 0) PHP_FE_END }; @@ -6483,7 +6599,7 @@ ZEND_END_ARG_INFO() static const zend_function_entry reflection_class_constant_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) - ZEND_ME(reflection_class_constant, export, arginfo_reflection_class_constant_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_class_constant, export, arginfo_reflection_class_constant_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_class_constant, __construct, arginfo_reflection_class_constant___construct, 0) ZEND_ME(reflection_class_constant, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_class_constant, getName, arginfo_reflection__void, 0) @@ -6510,7 +6626,7 @@ ZEND_END_ARG_INFO() static const zend_function_entry reflection_parameter_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) - ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0) ZEND_ME(reflection_parameter, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_parameter, getName, arginfo_reflection__void, 0) @@ -6538,10 +6654,7 @@ static const zend_function_entry reflection_type_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_ME(reflection_type, allowsNull, arginfo_reflection__void, 0) ZEND_ME(reflection_type, isBuiltin, arginfo_reflection__void, 0) - /* ReflectionType::__toString() is deprecated, but we currently do not mark it as such - * due to bad interaction with the PHPUnit error handler and exceptions in __toString(). - * See PR2137. */ - ZEND_ME(reflection_type, __toString, arginfo_reflection__void, 0) + ZEND_ME(reflection_type, __toString, arginfo_reflection__void, ZEND_ACC_DEPRECATED) PHP_FE_END }; @@ -6561,7 +6674,7 @@ ZEND_END_ARG_INFO() static const zend_function_entry reflection_extension_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) - ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0) ZEND_ME(reflection_extension, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_extension, getName, arginfo_reflection__void, 0) @@ -6584,7 +6697,7 @@ ZEND_END_ARG_INFO() static const zend_function_entry reflection_zend_extension_functions[] = { ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) - ZEND_ME(reflection_zend_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) + ZEND_DEP_ME(reflection_zend_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_zend_extension, __construct, arginfo_reflection_zend_extension___construct, 0) ZEND_ME(reflection_zend_extension, __toString, arginfo_reflection__void, 0) ZEND_ME(reflection_zend_extension, getName, arginfo_reflection__void, 0) @@ -6594,6 +6707,21 @@ static const zend_function_entry reflection_zend_extension_functions[] = { ZEND_ME(reflection_zend_extension, getCopyright, arginfo_reflection__void, 0) PHP_FE_END }; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_reference_fromArrayElement, 0, 0, 2) + ZEND_ARG_INFO(0, array) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + +static const zend_function_entry reflection_reference_functions[] = { + ZEND_ME(reflection_reference, fromArrayElement, arginfo_reflection_reference_fromArrayElement, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(reflection_reference, getId, arginfo_reflection__void, ZEND_ACC_PUBLIC) + + /* Always throwing dummy methods */ + ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE) + ZEND_ME(reflection_reference, __construct, arginfo_reflection__void, ZEND_ACC_PRIVATE) + PHP_FE_END +}; /* }}} */ static const zend_function_entry reflection_ext_functions[] = { /* {{{ */ @@ -6601,7 +6729,7 @@ static const zend_function_entry reflection_ext_functions[] = { /* {{{ */ }; /* }}} */ /* {{{ _reflection_write_property */ -static void _reflection_write_property(zval *object, zval *member, zval *value, void **cache_slot) +static zval *_reflection_write_property(zval *object, zval *member, zval *value, void **cache_slot) { if ((Z_TYPE_P(member) == IS_STRING) && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STR_P(member)) @@ -6610,14 +6738,21 @@ static void _reflection_write_property(zval *object, zval *member, zval *value, { zend_throw_exception_ex(reflection_exception_ptr, 0, "Cannot set read-only property %s::$%s", ZSTR_VAL(Z_OBJCE_P(object)->name), Z_STRVAL_P(member)); + return &EG(uninitialized_zval); } else { - zend_std_write_property(object, member, value, cache_slot); + return zend_std_write_property(object, member, value, cache_slot); } } /* }}} */ +static void reflection_init_class_handlers(zend_class_entry *ce) { + ce->create_object = reflection_objects_new; + ce->serialize = zend_class_serialize_deny; + ce->unserialize = zend_class_unserialize_deny; +} + PHP_MINIT_FUNCTION(reflection) /* {{{ */ { zend_class_entry _reflection_entry; @@ -6639,38 +6774,38 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ reflector_ptr = zend_register_internal_interface(&_reflection_entry); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_function_abstract_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr); zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionGenerator", reflection_generator_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_generator_ptr = zend_register_internal_class(&_reflection_entry); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_parameter_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionType", reflection_type_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_type_ptr = zend_register_internal_class(&_reflection_entry); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionNamedType", reflection_named_type_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_named_type_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_type_ptr); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr); zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); @@ -6683,7 +6818,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_class_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_class_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); @@ -6693,18 +6828,18 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_property_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_property_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClassConstant", reflection_class_constant_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_class_constant_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_class_constant_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_class_constant_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); @@ -6716,17 +6851,24 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_extension_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_extension_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions); - _reflection_entry.create_object = reflection_objects_new; + reflection_init_class_handlers(&_reflection_entry); reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry); zend_class_implements(reflection_zend_extension_ptr, 1, reflector_ptr); zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionReference", reflection_reference_functions); + reflection_init_class_handlers(&_reflection_entry); + _reflection_entry.ce_flags |= ZEND_ACC_FINAL; + reflection_reference_ptr = zend_register_internal_class(&_reflection_entry); + + REFLECTION_G(key_initialized) = 0; + return SUCCESS; } /* }}} */ @@ -6747,14 +6889,9 @@ zend_module_entry reflection_module_entry = { /* {{{ */ NULL, PHP_MINFO(reflection), PHP_REFLECTION_VERSION, - STANDARD_MODULE_PROPERTIES + ZEND_MODULE_GLOBALS(reflection), + NULL, + NULL, + NULL, + STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * indent-tabs-mode: t - * End: - * vim600: noet sw=4 ts=4 fdm=marker - */ diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h index 3a35639e7b..b1d5717e3f 100644 --- a/ext/reflection/php_reflection.h +++ b/ext/reflection/php_reflection.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2018 The PHP Group | + | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -43,17 +43,10 @@ extern PHPAPI zend_class_entry *reflection_method_ptr; extern PHPAPI zend_class_entry *reflection_property_ptr; extern PHPAPI zend_class_entry *reflection_extension_ptr; extern PHPAPI zend_class_entry *reflection_zend_extension_ptr; +extern PHPAPI zend_class_entry *reflection_reference_ptr; PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object); END_EXTERN_C() #endif /* PHP_REFLECTION_H */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * indent-tabs-mode: t - * End: - */ diff --git a/ext/reflection/tests/009.phpt b/ext/reflection/tests/009.phpt index 09df90c8c3..d582623cbd 100644 --- a/ext/reflection/tests/009.phpt +++ b/ext/reflection/tests/009.phpt @@ -14,7 +14,7 @@ function test ($a, $b = 1, $c = "") { $func = new ReflectionFunction("test"); -var_dump($func->export("test")); +echo $func; echo "--getName--\n"; var_dump($func->getName()); echo "--isInternal--\n"; @@ -60,8 +60,6 @@ Function [ <user> function test ] { Parameter #2 [ <optional> $c = '' ] } } - -NULL --getName-- string(4) "test" --isInternal-- diff --git a/ext/reflection/tests/025.phpt b/ext/reflection/tests/025.phpt index f1e13d9240..c18a0f5b8e 100644 --- a/ext/reflection/tests/025.phpt +++ b/ext/reflection/tests/025.phpt @@ -14,7 +14,7 @@ function test ($a, $b = 1, $c = "") { $func = new ReflectionFunction("test"); -var_dump($func->export("test")); +echo $func; echo "--getName--\n"; var_dump($func->getName()); echo "--isInternal--\n"; @@ -60,8 +60,6 @@ Function [ <user> function test ] { Parameter #2 [ <optional> $c = '' ] } } - -NULL --getName-- string(4) "test" --isInternal-- diff --git a/ext/reflection/tests/ReflectionClassConstant_basic1.phpt b/ext/reflection/tests/ReflectionClassConstant_basic1.phpt index 548d64e1bf..181360d733 100644 --- a/ext/reflection/tests/ReflectionClassConstant_basic1.phpt +++ b/ext/reflection/tests/ReflectionClassConstant_basic1.phpt @@ -56,9 +56,13 @@ __toString(): string(35) "Constant [ public bool PUB ] { 1 } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d string(35) "Constant [ public bool PUB ] { 1 } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d Constant [ public bool PUB ] { 1 } NULL @@ -73,7 +77,7 @@ bool(false) isProtected(): bool(false) getModifiers(): -int(256) +int(1) getDeclaringClass(): object(ReflectionClass)#3 (1) { ["name"]=> @@ -90,9 +94,13 @@ __toString(): string(38) "Constant [ protected int PROT ] { 4 } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d string(38) "Constant [ protected int PROT ] { 4 } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d Constant [ protected int PROT ] { 4 } NULL @@ -107,7 +115,7 @@ bool(false) isProtected(): bool(true) getModifiers(): -int(512) +int(2) getDeclaringClass(): object(ReflectionClass)#3 (1) { ["name"]=> @@ -124,9 +132,13 @@ __toString(): string(45) "Constant [ private string PRIV ] { keepOut } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d string(45) "Constant [ private string PRIV ] { keepOut } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d Constant [ private string PRIV ] { keepOut } NULL @@ -141,7 +153,7 @@ bool(true) isProtected(): bool(false) getModifiers(): -int(1024) +int(4) getDeclaringClass(): object(ReflectionClass)#3 (1) { ["name"]=> @@ -158,9 +170,13 @@ __toString(): string(45) "Constant [ private string PRIV ] { keepOut } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d string(45) "Constant [ private string PRIV ] { keepOut } " export(): + +Deprecated: Function ReflectionClassConstant::export() is deprecated in %s on line %d Constant [ private string PRIV ] { keepOut } NULL @@ -175,7 +191,7 @@ bool(true) isProtected(): bool(false) getModifiers(): -int(1024) +int(4) getDeclaringClass(): object(ReflectionClass)#3 (1) { ["name"]=> diff --git a/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt b/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt deleted file mode 100644 index a4e5f95564..0000000000 --- a/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -ReflectionClass::getFileName(), ReflectionClass::getStartLine(), ReflectionClass::getEndLine() - bad params ---FILE-- -<?php -Class C { } - -$rc = new ReflectionClass("C"); -$methods = array("getFileName", "getStartLine", "getEndLine"); - -foreach ($methods as $method) { - var_dump($rc->$method()); - var_dump($rc->$method(null)); - var_dump($rc->$method('X', 0)); -} -?> ---EXPECTF-- -string(%d) "%s" - -Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 2 given in %s on line %d -NULL -int(2) - -Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 2 given in %s on line %d -NULL -int(2) - -Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_export_array_bug72222.phpt b/ext/reflection/tests/ReflectionClass_export_array_bug72222.phpt index 30694bf536..80d2be2585 100644 --- a/ext/reflection/tests/ReflectionClass_export_array_bug72222.phpt +++ b/ext/reflection/tests/ReflectionClass_export_array_bug72222.phpt @@ -1,12 +1,12 @@ --TEST-- -ReflectionClass::export() - array constants +ReflectionClass::__toString() - array constants --FILE-- <?php Class A { const A = 8; const B = ["a", "b"]; } -ReflectionClass::export("A"); +echo new ReflectionClass("A"), "\n"; ?> --EXPECTF-- Class [ <user> class A ] { diff --git a/ext/reflection/tests/ReflectionClass_export_basic1.phpt b/ext/reflection/tests/ReflectionClass_export_basic1.phpt index abfa41f3d7..d9183442c4 100644 --- a/ext/reflection/tests/ReflectionClass_export_basic1.phpt +++ b/ext/reflection/tests/ReflectionClass_export_basic1.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionClass::export() - various parameters +ReflectionClass::__toString() - various parameters --FILE-- <?php Class A { @@ -17,7 +17,7 @@ Class A { Class C extends A { } define('K', "16 chars long --"); -ReflectionClass::export("C"); +echo new ReflectionClass("C"), "\n"; ?> --EXPECTF-- Class [ <user> class C extends A ] { diff --git a/ext/reflection/tests/ReflectionClass_export_basic2.phpt b/ext/reflection/tests/ReflectionClass_export_basic2.phpt index 5699529b3d..12cee4e6e3 100644 --- a/ext/reflection/tests/ReflectionClass_export_basic2.phpt +++ b/ext/reflection/tests/ReflectionClass_export_basic2.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionClass::export() - ensure inherited private props are hidden. +ReflectionClass::__toString() - ensure inherited private props are hidden. --FILE-- <?php Class c { @@ -9,8 +9,8 @@ Class c { class d extends c {} -ReflectionClass::export("c"); -ReflectionClass::export("d"); +echo new ReflectionClass("c"), "\n"; +echo new ReflectionClass("d"), "\n"; ?> --EXPECTF-- Class [ <user> class c ] { diff --git a/ext/reflection/tests/ReflectionClass_getConstants_error.phpt b/ext/reflection/tests/ReflectionClass_getConstants_error.phpt deleted file mode 100644 index 1784d712a4..0000000000 --- a/ext/reflection/tests/ReflectionClass_getConstants_error.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -ReflectionClass::getConstants() ---FILE-- -<?php -class X { -} - -$rc = new reflectionClass('X'); - -//Test invalid arguments -$rc->getConstants('X'); -$rc->getConstants(true); -$rc->getConstants(null); -$rc->getConstants('A', 'B'); - -?> ---EXPECTF-- -Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 2 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt b/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt deleted file mode 100644 index 7e8932a5ed..0000000000 --- a/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -ReflectionClass::getConstructor() - bad params ---FILE-- -<?php -class C {} -$rc = new ReflectionClass('C'); -var_dump($rc->getConstructor(null)); -var_dump($rc->getConstructor('X')); -var_dump($rc->getConstructor(true)); -var_dump($rc->getConstructor(array(1,2,3))); -?> ---EXPECTF-- -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt b/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt deleted file mode 100644 index 7c178ac8ea..0000000000 --- a/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -ReflectionClass::getDefaultProperties(), ReflectionClass::getStaticProperties() - wrong param count ---CREDITS-- -Robin Fernandes <robinf@php.net> -Steve Seear <stevseea@php.net> ---FILE-- -<?php -interface I {} -class C implements I {} -$rc = new ReflectionClass('C'); -var_dump($rc->getDefaultProperties(null)); -var_dump($rc->getDefaultProperties('X')); -var_dump($rc->getDefaultProperties(true)); -var_dump($rc->getDefaultProperties(array(1,2,3))); -var_dump($rc->getStaticProperties(null)); -var_dump($rc->getStaticProperties('X')); -var_dump($rc->getStaticProperties(true)); -var_dump($rc->getStaticProperties(array(1,2,3))); - -?> ---EXPECTF-- -Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getDefaultProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getStaticProperties() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt deleted file mode 100644 index 5bbd596488..0000000000 --- a/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -ReflectionClass::getDocComment() - bad params ---CREDITS-- -Robin Fernandes <robinf@php.net> -Steve Seear <stevseea@php.net> ---FILE-- -<?php -class C {} -$rc = new ReflectionClass('C'); -var_dump($rc->getDocComment(null)); -var_dump($rc->getDocComment('X')); -var_dump($rc->getDocComment(true)); -var_dump($rc->getDocComment(array(1,2,3))); -?> ---EXPECTF-- -Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt index d99cd2561c..998bd4bea6 100644 --- a/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt +++ b/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt @@ -25,24 +25,24 @@ Array [name] => I6 ) - [I2] => ReflectionClass Object + [I4] => ReflectionClass Object ( - [name] => I2 + [name] => I4 ) - [I1] => ReflectionClass Object + [I3] => ReflectionClass Object ( - [name] => I1 + [name] => I3 ) - [I4] => ReflectionClass Object + [I2] => ReflectionClass Object ( - [name] => I4 + [name] => I2 ) - [I3] => ReflectionClass Object + [I1] => ReflectionClass Object ( - [name] => I3 + [name] => I1 ) [I5] => ReflectionClass Object diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt deleted file mode 100644 index f62d58cd72..0000000000 --- a/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -ReflectionClass::getInterfaces() - wrong param count ---CREDITS-- -Robin Fernandes <robinf@php.net> -Steve Seear <stevseea@php.net> ---FILE-- -<?php -interface I {} -class C implements I {} -$rc = new ReflectionClass('C'); -var_dump($rc->getInterfaces(null)); -var_dump($rc->getInterfaces('X')); -var_dump($rc->getInterfaces(true)); -var_dump($rc->getInterfaces(array(1,2,3))); -?> ---EXPECTF-- -Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getInterfaces() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_getMethods_002.phpt b/ext/reflection/tests/ReflectionClass_getMethods_002.phpt deleted file mode 100644 index b6a78aa318..0000000000 --- a/ext/reflection/tests/ReflectionClass_getMethods_002.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -ReflectionClass::getMethods() - invalid arguments ---CREDITS-- -Robin Fernandes <robinf@php.net> -Steve Seear <stevseea@php.net> ---FILE-- -<?php -$rc = new ReflectionClass("ReflectionClass"); -echo "\nTest invalid arguments:"; -$rc->getMethods('X'); -$rc->getMethods('X', true); - -?> ---EXPECTF-- -Test invalid arguments: -Warning: ReflectionClass::getMethods() expects parameter 1 to be int, string given in %s on line 4 - -Warning: ReflectionClass::getMethods() expects at most 1 parameter, 2 given in %s on line 5 diff --git a/ext/reflection/tests/ReflectionClass_getMethods_003.phpt b/ext/reflection/tests/ReflectionClass_getMethods_003.phpt index 885bd908f1..b08fcaa4d4 100644 --- a/ext/reflection/tests/ReflectionClass_getMethods_003.phpt +++ b/ext/reflection/tests/ReflectionClass_getMethods_003.phpt @@ -17,9 +17,9 @@ class C { } $rc = new ReflectionClass("C"); -$StaticFlag = 0x01; -$pubFlag = 0x100; -$privFlag = 0x400; +$StaticFlag = ReflectionMethod::IS_STATIC; +$pubFlag = ReflectionMethod::IS_PUBLIC; +$privFlag = ReflectionMethod::IS_PRIVATE; echo "No methods:"; var_dump($rc->getMethods(0)); diff --git a/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt index f77bbacda7..ffe8876133 100644 --- a/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt +++ b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt @@ -29,8 +29,8 @@ dump_modifiers('g'); ?> --EXPECT-- int(0) +int(64) int(32) -int(4) int(0) int(0) int(0) diff --git a/ext/reflection/tests/ReflectionClass_getName_error.phpt b/ext/reflection/tests/ReflectionClass_getName_error.phpt deleted file mode 100644 index 145704e7bc..0000000000 --- a/ext/reflection/tests/ReflectionClass_getName_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -ReflectionClass::getName() - invalid params ---FILE-- -<?php - -$r1 = new ReflectionClass("stdClass"); - -var_dump($r1->getName('X')); -var_dump($r1->getName('X', true)); -?> ---EXPECTF-- -Warning: ReflectionClass::getName() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getName() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_getProperties_002.phpt b/ext/reflection/tests/ReflectionClass_getProperties_002.phpt deleted file mode 100644 index 1f7dc24d74..0000000000 --- a/ext/reflection/tests/ReflectionClass_getProperties_002.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -ReflectionClass::getProperties() - invalid arguments ---CREDITS-- -Robin Fernandes <robinf@php.net> -Steve Seear <stevseea@php.net> ---FILE-- -<?php -$rc = new ReflectionClass("ReflectionClass"); -echo "\nTest invalid arguments:"; -$rc->getProperties('X'); -$rc->getProperties('X', true); -?> ---EXPECTF-- -Test invalid arguments: -Warning: ReflectionClass::getProperties() expects parameter 1 to be int, string given in %s on line 4 - -Warning: ReflectionClass::getProperties() expects at most 1 parameter, 2 given in %s on line 5 diff --git a/ext/reflection/tests/ReflectionClass_getProperties_003.phpt b/ext/reflection/tests/ReflectionClass_getProperties_003.phpt index d4a00f05fe..fe3792a30f 100644 --- a/ext/reflection/tests/ReflectionClass_getProperties_003.phpt +++ b/ext/reflection/tests/ReflectionClass_getProperties_003.phpt @@ -17,9 +17,9 @@ class C { } $rc = new ReflectionClass("C"); -$StaticFlag = 0x01; -$pubFlag = 0x100; -$privFlag = 0x400; +$StaticFlag = ReflectionProperty::IS_STATIC; +$pubFlag = ReflectionProperty::IS_PUBLIC; +$privFlag = ReflectionProperty::IS_PRIVATE; echo "No properties:"; var_dump($rc->getProperties(0)); diff --git a/ext/reflection/tests/ReflectionClass_isInstance_error.phpt b/ext/reflection/tests/ReflectionClass_isInstance_error.phpt deleted file mode 100644 index f4c553dec6..0000000000 --- a/ext/reflection/tests/ReflectionClass_isInstance_error.phpt +++ /dev/null @@ -1,39 +0,0 @@ ---TEST-- -ReflectionClass::isInstance() - invalid params ---FILE-- -<?php -class X {} - -$rc = new ReflectionClass("X"); -$instance = new X; - -var_dump($rc->isInstance()); -var_dump($rc->isInstance($instance, $instance)); -var_dump($rc->isInstance(1)); -var_dump($rc->isInstance(1.5)); -var_dump($rc->isInstance(true)); -var_dump($rc->isInstance('X')); -var_dump($rc->isInstance(null)); - -?> ---EXPECTF-- -Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 0 given in %s on line 7 -NULL - -Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 2 given in %s on line 8 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, %s given in %s on line 9 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, float given in %s on line 10 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, bool given in %s on line 11 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, string given in %s on line 12 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, null given in %s on line 13 -NULL diff --git a/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt deleted file mode 100644 index 5263643023..0000000000 --- a/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -ReflectionClass::IsInstantiable() ---FILE-- -<?php -class privateCtorOld { - private function privateCtorOld() {} -} -$reflectionClass = new ReflectionClass("privateCtorOld"); - -var_dump($reflectionClass->IsInstantiable('X')); -var_dump($reflectionClass->IsInstantiable(0, null)); - -?> ---EXPECTF-- -Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; privateCtorOld has a deprecated constructor in %s on line %d - -Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_isInternal_error.phpt b/ext/reflection/tests/ReflectionClass_isInternal_error.phpt deleted file mode 100644 index ef69a4c393..0000000000 --- a/ext/reflection/tests/ReflectionClass_isInternal_error.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -ReflectionClass::isInternal() - invalid params ---FILE-- -<?php -$r1 = new ReflectionClass("stdClass"); -var_dump($r1->isInternal('X')); -var_dump($r1->isInternal('X', true)); -?> ---EXPECTF-- -Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt deleted file mode 100644 index 7d929fafd7..0000000000 --- a/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -ReflectionClass::isSubclassOf() - invalid number of parameters ---FILE-- -<?php -class A {} -$rc = new ReflectionClass('A'); - -var_dump($rc->isSubclassOf()); -var_dump($rc->isSubclassOf('A',5)); - -?> ---EXPECTF-- -Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 5 -NULL - -Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 6 -NULL diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt new file mode 100644 index 0000000000..8671c2500b --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_error2.phpt @@ -0,0 +1,35 @@ +--TEST-- +ReflectionClass::isSubclassOf() - fixed crash for unbound anonymous class +--FILE-- +<?php +class X { + public static function main() { + return new class() extends Base {}; + } +} +class Base {} +$check = function () { + $base = Base::class; + foreach (get_declared_classes() as $class) { + if (strpos($class, 'class@anonymous') === false) { + continue; + } + echo "Checking for $class\n"; + flush(); + $rc = new ReflectionClass($class); + var_export($rc->isSubclassOf($base)); + echo "\n"; + } +}; +// Should not show up in get_declared_classes until the anonymous class is bound. +$check(); +echo "After first check\n"; +X::main(); +$check(); +echo "Done\n"; +?> +--EXPECTF-- +After first check +Checking for class@%s +true +Done diff --git a/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt b/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt deleted file mode 100644 index ac88884179..0000000000 --- a/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -ReflectionClass::isUserDefined() - invalid params. ---FILE-- -<?php -$r1 = new ReflectionClass("stdClass"); -var_dump($r1->isUserDefined('X')); -var_dump($r1->isUserDefined('X', true)); -?> ---EXPECTF-- -Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_modifiers_001.phpt b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt index d82519e4f4..1370228f04 100644 --- a/ext/reflection/tests/ReflectionClass_modifiers_001.phpt +++ b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt @@ -25,7 +25,7 @@ foreach ($classes as $class) { bool(false) bool(false) bool(true) -int(32) +int(64) bool(false) bool(false) bool(false) @@ -37,7 +37,7 @@ int(0) bool(true) bool(false) bool(false) -int(4) +int(32) bool(false) bool(true) bool(false) diff --git a/ext/reflection/tests/ReflectionClass_modifiers_002.phpt b/ext/reflection/tests/ReflectionClass_modifiers_002.phpt deleted file mode 100644 index a3a567ccbb..0000000000 --- a/ext/reflection/tests/ReflectionClass_modifiers_002.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Modifiers - wrong param count ---CREDITS-- -Robin Fernandes <robinf@php.net> -Steve Seear <stevseea@php.net> ---FILE-- -<?php -class C {} -$rc = new ReflectionClass("C"); -var_dump($rc->isFinal('X')); -var_dump($rc->isInterface(null)); -var_dump($rc->isAbstract(true)); -var_dump($rc->getModifiers(array(1,2,3))); - -?> ---EXPECTF-- -Warning: ReflectionClass::isFinal() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isInterface() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isAbstract() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt index 334efc3a50..59337f09e8 100644 --- a/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt +++ b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt @@ -22,7 +22,19 @@ $class = new ReflectionClass('DateTime'); var_dump($class->newInstanceWithoutConstructor()); $class = new ReflectionClass('Generator'); +try { + var_dump($class->newInstanceWithoutConstructor()); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} + +final class Bar extends ArrayObject { +} + +$class = new ReflectionClass('Bar'); var_dump($class->newInstanceWithoutConstructor()); + +?> --EXPECTF-- object(Foo)#%d (0) { } @@ -30,9 +42,9 @@ object(stdClass)#%d (0) { } object(DateTime)#%d (0) { } - -Fatal error: Uncaught ReflectionException: Class Generator is an internal class marked as final that cannot be instantiated without invoking its constructor in %sReflectionClass_newInstanceWithoutConstructor.php:%d -Stack trace: -#0 %sReflectionClass_newInstanceWithoutConstructor.php(%d): ReflectionClass->newInstanceWithoutConstructor() -#1 {main} - thrown in %sReflectionClass_newInstanceWithoutConstructor.php on line %d +Class Generator is an internal class marked as final that cannot be instantiated without invoking its constructor +object(Bar)#%d (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +} diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt index 14e8382e41..fb472681ca 100644 --- a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionClass::getStaticPropertyValue() - bad params +ReflectionClass::setStaticPropertyValue() - bad params --CREDITS-- Robin Fernandes <robinf@php.net> Steve Seear <stevseea@php.net> diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_003.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_003.phpt new file mode 100644 index 0000000000..a83900a123 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_003.phpt @@ -0,0 +1,39 @@ +--TEST-- +ReflectionClass::setStaticPropertyValue() - type constraints must be enforced +--FILE-- +<?php + +class Test { + public static $x; + public static int $y = 2; +} + +$rc = new ReflectionClass('Test'); + +try { + $rc->setStaticPropertyValue("y", "foo"); +} catch (TypeError $e) { echo $e->getMessage(), "\n"; } +var_dump(Test::$y); + +$rc->setStaticPropertyValue("y", "21"); +var_dump(Test::$y); + + +Test::$x =& Test::$y; + +try { + $rc->setStaticPropertyValue("x", "foo"); +} catch (TypeError $e) { echo $e->getMessage(), "\n"; } +var_dump(Test::$y); + +$rc->setStaticPropertyValue("x", "42"); +var_dump(Test::$y); + +?> +--EXPECT-- +Typed property Test::$y must be int, string used +int(2) +int(21) +Cannot assign string to reference held by property Test::$y of type int +int(21) +int(42) diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index cafdd2e37c..2cfd808cb8 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -13,15 +13,15 @@ Class [ <internal:Reflection> class ReflectionClass implements Reflector ] { - Constants [3] { Constant [ public int IS_IMPLICIT_ABSTRACT ] { 16 } - Constant [ public int IS_EXPLICIT_ABSTRACT ] { 32 } - Constant [ public int IS_FINAL ] { 4 } + Constant [ public int IS_EXPLICIT_ABSTRACT ] { 64 } + Constant [ public int IS_FINAL ] { 32 } } - Static properties [0] { } - Static methods [1] { - Method [ <internal:Reflection, prototype Reflector> static public method export ] { + Method [ <internal, deprecated:Reflection> static public method export ] { - Parameters [2] { Parameter #0 [ <required> $argument ] diff --git a/ext/reflection/tests/ReflectionExtension_export_basic.phpt b/ext/reflection/tests/ReflectionExtension_export_basic.phpt index 3fa7a66afd..4652a409a1 100644 --- a/ext/reflection/tests/ReflectionExtension_export_basic.phpt +++ b/ext/reflection/tests/ReflectionExtension_export_basic.phpt @@ -5,18 +5,14 @@ Gerrit "Remi" te Sligte <remi@wolerized.com> Leon Luijkx <leon@phpgg.nl> --FILE-- <?php -ob_start(); ReflectionExtension::export("reflection", true); -$test = ob_get_clean(); -var_dump(empty($test)); -unset($test); ob_start(); ReflectionExtension::export("reflection", false); $test = ob_get_clean(); var_dump(empty($test)); ?> ==DONE== ---EXPECT-- -bool(true) +--EXPECTF-- +Deprecated: Function ReflectionExtension::export() is deprecated in %s on line %d bool(false) ==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt index 9b2122d1b9..5877f88e27 100644 --- a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt +++ b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt @@ -9,7 +9,7 @@ var_dump($ext->getClasses()); ?> ==DONE== --EXPECT-- -array(16) { +array(17) { ["ReflectionException"]=> object(ReflectionClass)#2 (1) { ["name"]=> @@ -90,5 +90,10 @@ array(16) { ["name"]=> string(23) "ReflectionZendExtension" } + ["ReflectionReference"]=> + object(ReflectionClass)#18 (1) { + ["name"]=> + string(19) "ReflectionReference" + } } ==DONE== diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt deleted file mode 100644 index 9a963e41ca..0000000000 --- a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Test ReflectionFunction::getClosure() function : error functionality ---FILE-- -<?php -/* Prototype : public mixed ReflectionFunction::getClosure() - * Description: Returns a dynamically created closure for the function - * Source code: ext/reflection/php_reflection.c - * Alias to functions: - */ - -echo "*** Testing ReflectionFunction::getClosure() : error conditions ***\n"; - -function foo() -{ - var_dump( "Inside foo function" ); -} - -$func = new ReflectionFunction( 'foo' ); -$closure = $func->getClosure('bar'); - -?> -===DONE=== ---EXPECTF-- -*** Testing ReflectionFunction::getClosure() : error conditions *** - -Warning: ReflectionFunction::getClosure() expects exactly 0 parameters, 1 given in %s on line %d -===DONE=== diff --git a/ext/reflection/tests/ReflectionMethod_basic2.phpt b/ext/reflection/tests/ReflectionMethod_basic2.phpt index c91af67701..71ef9e95d9 100644 --- a/ext/reflection/tests/ReflectionMethod_basic2.phpt +++ b/ext/reflection/tests/ReflectionMethod_basic2.phpt @@ -60,6 +60,8 @@ string(%d) "Method [ <user, inherits TestClass> public method foo ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user, inherits TestClass> public method foo ] { @@ %s 16 - 18 } @@ -76,6 +78,8 @@ string(%d) "Method [ <user> static public method stat ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user> static public method stat ] { @@ %s 20 - 22 } @@ -92,6 +96,8 @@ string(%d) "Method [ <user> private method priv ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user> private method priv ] { @@ %s 24 - 26 } @@ -108,6 +114,8 @@ string(%d) "Method [ <user> protected method prot ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user> protected method prot ] { @@ %s 28 - 28 } @@ -124,6 +132,8 @@ string(%d) "Method [ <user, inherits TestClass> protected method prot ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user, inherits TestClass> protected method prot ] { @@ %s 28 - 28 } @@ -140,6 +150,8 @@ string(%d) "Method [ <user> abstract public method int ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user> abstract public method int ] { @@ %s 36 - 36 } @@ -160,6 +172,8 @@ string(%d) "Method [ <internal:Reflection, ctor> public method __construct ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <internal:Reflection, ctor> public method __construct ] { - Parameters [2] { @@ -180,6 +194,8 @@ string(%d) "Method [ <user, dtor> public method __destruct ] { " export(): + +Deprecated: Function ReflectionMethod::export() is deprecated in %s on line %d string(%d) "Method [ <user, dtor> public method __destruct ] { @@ %s 30 - 30 } diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt deleted file mode 100644 index 02de25bab0..0000000000 --- a/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -ReflectionMethod::getDocComment() errors ---FILE-- -<?php -class C { function f() {} } -$rc = new ReflectionMethod('C::f'); -var_dump($rc->getDocComment(null)); -var_dump($rc->getDocComment('X')); -?> ---EXPECTF-- -Warning: ReflectionFunctionAbstract::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionFunctionAbstract::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt index 55aea10763..d1a19c7116 100644 --- a/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt +++ b/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt @@ -87,151 +87,151 @@ printf("0x%08x\n", $a->getModifiers()); ?> --EXPECTF-- Modifiers for method TestClass::foo(): -0x00000100 +0x00000001 Modifiers for method TestClass::stat(): -0x00000101 +0x00000011 Modifiers for method TestClass::priv(): -0x00000400 +0x00000004 Modifiers for method TestClass::prot(): -0x00000200 +0x00000002 Modifiers for method TestClass::fin(): -0x00000104 +0x00000021 Modifiers for method TestClass::__destruct(): -0x00000100 +0x00000001 Modifiers for method TestClass::__call(): -0x00000100 +0x00000001 Modifiers for method TestClass::__clone(): -0x00000100 +0x00000001 Modifiers for method TestClass::__get(): -0x00000100 +0x00000001 Modifiers for method TestClass::__set(): -0x00000100 +0x00000001 Modifiers for method TestClass::__unset(): -0x00000100 +0x00000001 Modifiers for method TestClass::__isset(): -0x00000100 +0x00000001 Modifiers for method TestClass::__tostring(): -0x00000100 +0x00000001 Modifiers for method TestClass::__sleep(): -0x00000100 +0x00000001 Modifiers for method TestClass::__wakeup(): -0x00000100 +0x00000001 Modifiers for method TestClass::__set_state(): -0x00000100 +0x00000001 Modifiers for method TestClass::__autoload(): -0x00000100 +0x00000001 Modifiers for method TestClass::foo(): -0x00000100 +0x00000001 Modifiers for method TestClass::stat(): -0x00000101 +0x00000011 Modifiers for method TestClass::priv(): -0x00000400 +0x00000004 Modifiers for method TestClass::prot(): -0x00000200 +0x00000002 Modifiers for method TestClass::fin(): -0x00000104 +0x00000021 Modifiers for method TestClass::__destruct(): -0x00000100 +0x00000001 Modifiers for method TestClass::__call(): -0x00000100 +0x00000001 Modifiers for method TestClass::__clone(): -0x00000100 +0x00000001 Modifiers for method TestClass::__get(): -0x00000100 +0x00000001 Modifiers for method TestClass::__set(): -0x00000100 +0x00000001 Modifiers for method TestClass::__unset(): -0x00000100 +0x00000001 Modifiers for method TestClass::__isset(): -0x00000100 +0x00000001 Modifiers for method TestClass::__tostring(): -0x00000100 +0x00000001 Modifiers for method TestClass::__sleep(): -0x00000100 +0x00000001 Modifiers for method TestClass::__wakeup(): -0x00000100 +0x00000001 Modifiers for method TestClass::__set_state(): -0x00000100 +0x00000001 Modifiers for method TestClass::__autoload(): -0x00000100 +0x00000001 Modifiers for method TestInterface::int(): -0x00000102 +0x00000041 Modifiers for method TestInterface::__clone(): -0x00000102 +0x00000041 Modifiers for method AbstractClass::foo(): -0x00000102 +0x00000041 Wrong number of params: @@ -239,4 +239,4 @@ Wrong number of params: Warning: ReflectionMethod::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d ReflectionMethod::getModifiers() modifiers: -0x00000100 +0x00000001 diff --git a/ext/reflection/tests/ReflectionNamedType.phpt b/ext/reflection/tests/ReflectionNamedType.phpt index a40d4066ec..afb592127c 100644 --- a/ext/reflection/tests/ReflectionNamedType.phpt +++ b/ext/reflection/tests/ReflectionNamedType.phpt @@ -30,12 +30,20 @@ var_dump($return->getName()); var_dump((string) $return); ?> ---EXPECT-- +--EXPECTF-- string(11) "Traversable" + +Deprecated: Function ReflectionType::__toString() is deprecated in %s on line %d string(11) "Traversable" string(6) "string" + +Deprecated: Function ReflectionType::__toString() is deprecated in %s on line %d string(6) "string" string(4) "Test" + +Deprecated: Function ReflectionType::__toString() is deprecated in %s on line %d string(4) "Test" string(4) "Test" + +Deprecated: Function ReflectionType::__toString() is deprecated in %s on line %d string(4) "Test" diff --git a/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt b/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt deleted file mode 100644 index 70ad24297d..0000000000 --- a/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -ReflectionObject::getFileName(), ReflectionObject::getStartLine(), ReflectionObject::getEndLine() -invalid aparams ---FILE-- -<?php -Class C { } - -$rc = new ReflectionObject(new C); -$methods = array("getFileName", "getStartLine", "getEndLine"); - -foreach ($methods as $method) { - var_dump($rc->$method()); - var_dump($rc->$method(null)); - var_dump($rc->$method('X', 0)); -} -?> ---EXPECTF-- -string(%d) "%s" - -Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getFileName() expects exactly 0 parameters, 2 given in %s on line %d -NULL -int(2) - -Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getStartLine() expects exactly 0 parameters, 2 given in %s on line %d -NULL -int(2) - -Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getEndLine() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionObject_constructor_error.phpt b/ext/reflection/tests/ReflectionObject_constructor_error.phpt deleted file mode 100644 index 71a1166b13..0000000000 --- a/ext/reflection/tests/ReflectionObject_constructor_error.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---TEST-- -ReflectionObject::__construct - invalid arguments ---FILE-- -<?php - -var_dump(new ReflectionObject()); -var_dump(new ReflectionObject('stdClass')); -$myInstance = new stdClass; -var_dump(new ReflectionObject($myInstance, $myInstance)); -var_dump(new ReflectionObject(0)); -var_dump(new ReflectionObject(null)); -var_dump(new ReflectionObject(array(1,2))); -?> ---EXPECTF-- -Warning: ReflectionObject::__construct() expects exactly 1 parameter, 0 given in %s on line 3 -object(ReflectionObject)#%d (1) { - ["name"]=> - string(0) "" -} - -Warning: ReflectionObject::__construct() expects parameter 1 to be object, string given in %s on line 4 -object(ReflectionObject)#%d (1) { - ["name"]=> - string(0) "" -} - -Warning: ReflectionObject::__construct() expects exactly 1 parameter, 2 given in %s on line 6 -object(ReflectionObject)#%d (1) { - ["name"]=> - string(0) "" -} - -Warning: ReflectionObject::__construct() expects parameter 1 to be object, int given in %s on line 7 -object(ReflectionObject)#%d (1) { - ["name"]=> - string(0) "" -} - -Warning: ReflectionObject::__construct() expects parameter 1 to be object, null given in %s on line 8 -object(ReflectionObject)#%d (1) { - ["name"]=> - string(0) "" -} - -Warning: ReflectionObject::__construct() expects parameter 1 to be object, array given in %s on line 9 -object(ReflectionObject)#%d (1) { - ["name"]=> - string(0) "" -} diff --git a/ext/reflection/tests/ReflectionObject_export_basic1.phpt b/ext/reflection/tests/ReflectionObject_export_basic1.phpt index 2fbe6fd779..43210ea686 100644 --- a/ext/reflection/tests/ReflectionObject_export_basic1.phpt +++ b/ext/reflection/tests/ReflectionObject_export_basic1.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionObject::export() : very basic test with no dynamic properties +ReflectionObject::__toString() : very basic test with no dynamic properties --FILE-- <?php @@ -8,7 +8,7 @@ class Foo { } $f = new foo; -ReflectionObject::export($f); +echo new ReflectionObject($f); ?> --EXPECTF-- diff --git a/ext/reflection/tests/ReflectionObject_export_basic2.phpt b/ext/reflection/tests/ReflectionObject_export_basic2.phpt index 652a5556cd..970d07b432 100644 --- a/ext/reflection/tests/ReflectionObject_export_basic2.phpt +++ b/ext/reflection/tests/ReflectionObject_export_basic2.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionObject::export() : very basic test with dynamic properties +ReflectionObject::__toString() : very basic test with dynamic properties --FILE-- <?php @@ -9,7 +9,7 @@ class Foo { $f = new foo; $f->dynProp = 'hello'; $f->dynProp2 = 'hello again'; -ReflectionObject::export($f); +echo new ReflectionObject($f); ?> --EXPECTF-- diff --git a/ext/reflection/tests/ReflectionObject_export_basic3.phpt b/ext/reflection/tests/ReflectionObject_export_basic3.phpt index c4afc22d64..a92c2d4921 100644 --- a/ext/reflection/tests/ReflectionObject_export_basic3.phpt +++ b/ext/reflection/tests/ReflectionObject_export_basic3.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionObject::export() - ensure dynamic property with same name as inherited private property is shown. +ReflectionObject::__toString() - ensure dynamic property with same name as inherited private property is shown. --FILE-- <?php class C { @@ -11,7 +11,7 @@ class D extends C{ $Obj = new D; $Obj->p = 'value'; -ReflectionObject::export($Obj) +echo new ReflectionObject($Obj); ?> --EXPECTF-- Object of class [ <user> class D extends C ] { diff --git a/ext/reflection/tests/ReflectionObject_getConstant_error.phpt b/ext/reflection/tests/ReflectionObject_getConstant_error.phpt deleted file mode 100644 index 3f12f3a1ea..0000000000 --- a/ext/reflection/tests/ReflectionObject_getConstant_error.phpt +++ /dev/null @@ -1,34 +0,0 @@ ---TEST-- -ReflectionObject::getConstant() - invalid params ---FILE-- -<?php -class C { - const myConst = 1; -} - -$rc = new ReflectionObject(new C); -var_dump($rc->getConstant()); -var_dump($rc->getConstant("myConst", "myConst")); -var_dump($rc->getConstant(null)); -var_dump($rc->getConstant(1)); -var_dump($rc->getConstant(1.5)); -var_dump($rc->getConstant(true)); -var_dump($rc->getConstant(array(1,2,3))); -var_dump($rc->getConstant(new C)); -?> ---EXPECTF-- -Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 0 given in %s on line 7 -NULL - -Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 2 given in %s on line 8 -NULL -bool(false) -bool(false) -bool(false) -bool(false) - -Warning: ReflectionClass::getConstant() expects parameter 1 to be string, array given in %s on line 13 -NULL - -Warning: ReflectionClass::getConstant() expects parameter 1 to be string, object given in %s on line 14 -NULL diff --git a/ext/reflection/tests/ReflectionObject_getConstants_error.phpt b/ext/reflection/tests/ReflectionObject_getConstants_error.phpt deleted file mode 100644 index d3b90805eb..0000000000 --- a/ext/reflection/tests/ReflectionObject_getConstants_error.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -ReflectionObject::getConstants() - invalid params ---FILE-- -<?php -class X { -} - -$rc = new ReflectionObject(new X); - -$rc->getConstants('X'); -$rc->getConstants(true); - -?> ---EXPECTF-- -Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: ReflectionClass::getConstants() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt b/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt deleted file mode 100644 index 2f52de2ed8..0000000000 --- a/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -ReflectionObject::getConstructor() - invalid params ---FILE-- -<?php -class C {} -$rc = new ReflectionObject(new C); -var_dump($rc->getConstructor(null)); -var_dump($rc->getConstructor('X')); -var_dump($rc->getConstructor(true)); -var_dump($rc->getConstructor(array(1,2,3))); -?> ---EXPECTF-- -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getConstructor() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionObject_getName_error.phpt b/ext/reflection/tests/ReflectionObject_getName_error.phpt deleted file mode 100644 index ff8e279e9b..0000000000 --- a/ext/reflection/tests/ReflectionObject_getName_error.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -ReflectionObject::getname() - invalid params ---FILE-- -<?php -class C { } -$myInstance = new C; -$r2 = new ReflectionObject($myInstance); - -$r3 = new ReflectionObject($r2); - -var_dump($r3->getName(null)); -var_dump($r3->getName('x','y')); -var_dump($r3->getName(0)); -?> ---EXPECTF-- -Warning: ReflectionClass::getName() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::getName() expects exactly 0 parameters, 2 given in %s on line %d -NULL - -Warning: ReflectionClass::getName() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionObject_isInstance_error.phpt b/ext/reflection/tests/ReflectionObject_isInstance_error.phpt deleted file mode 100644 index fa0befa504..0000000000 --- a/ext/reflection/tests/ReflectionObject_isInstance_error.phpt +++ /dev/null @@ -1,38 +0,0 @@ ---TEST-- -ReflectionObject::isInstance() - invalid params ---FILE-- -<?php -class X {} -$instance = new X; -$ro = new ReflectionObject(new X); - -var_dump($ro->isInstance()); -var_dump($ro->isInstance($instance, $instance)); -var_dump($ro->isInstance(1)); -var_dump($ro->isInstance(1.5)); -var_dump($ro->isInstance(true)); -var_dump($ro->isInstance('X')); -var_dump($ro->isInstance(null)); - -?> ---EXPECTF-- -Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 0 given in %s on line 6 -NULL - -Warning: ReflectionClass::isInstance() expects exactly 1 parameter, 2 given in %s on line 7 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, int given in %s on line 8 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, float given in %s on line 9 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, bool given in %s on line 10 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, string given in %s on line 11 -NULL - -Warning: ReflectionClass::isInstance() expects parameter 1 to be object, null given in %s on line 12 -NULL diff --git a/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt deleted file mode 100644 index f6d4c9d3d2..0000000000 --- a/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -ReflectionObject::IsInstantiable() - invalid params ---FILE-- -<?php -class privateCtorOld { - private function privateCtorOld() {} - public static function reflectionObjectFactory() { - return new ReflectionObject(new self); - } -} -$reflectionObject = privateCtorOld::reflectionObjectFactory(); - -var_dump($reflectionObject->IsInstantiable('X')); -var_dump($reflectionObject->IsInstantiable(0, null)); - -?> ---EXPECTF-- -Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; privateCtorOld has a deprecated constructor in %s on line %d - -Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isInstantiable() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionObject_isInternal_error.phpt b/ext/reflection/tests/ReflectionObject_isInternal_error.phpt deleted file mode 100644 index 996add6cd4..0000000000 --- a/ext/reflection/tests/ReflectionObject_isInternal_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -ReflectionObject::isInternal() - invalid params ---FILE-- -<?php - -$r1 = new ReflectionObject(new stdClass); -var_dump($r1->isInternal('X')); -var_dump($r1->isInternal('X', true)); -?> ---EXPECTF-- -Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isInternal() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt b/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt deleted file mode 100644 index 06be47ae67..0000000000 --- a/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -ReflectionObject::isUserDefined() - invalid params ---FILE-- -<?php -$r1 = new ReflectionObject(new stdClass); - -var_dump($r1->isUserDefined('X')); -var_dump($r1->isUserDefined('X', true)); -?> ---EXPECTF-- -Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionClass::isUserDefined() expects exactly 0 parameters, 2 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionParameter_export_basic.phpt b/ext/reflection/tests/ReflectionParameter_export_basic.phpt index 74428ccd23..6f3d16a5ff 100644 --- a/ext/reflection/tests/ReflectionParameter_export_basic.phpt +++ b/ext/reflection/tests/ReflectionParameter_export_basic.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionParameter::export() +ReflectionParameter::__toString() --CREDITS-- Stefan Koopmanschap <stefan@stefankoopmanschap.nl> --FILE-- @@ -9,11 +9,11 @@ function ReflectionParameterTest($test, $test2 = null) { } $reflect = new ReflectionFunction('ReflectionParameterTest'); foreach($reflect->getParameters() as $key => $value) { - echo ReflectionParameter::export('ReflectionParameterTest', $key); + echo new ReflectionParameter('ReflectionParameterTest', $key), "\n"; } ?> ==DONE== ---EXPECT-- +--EXPECTF-- Parameter #0 [ <required> $test ] Parameter #1 [ <optional> $test2 = NULL ] ==DONE== diff --git a/ext/reflection/tests/ReflectionParameter_export_error.phpt b/ext/reflection/tests/ReflectionParameter_export_error.phpt deleted file mode 100644 index e3d2bac0fc..0000000000 --- a/ext/reflection/tests/ReflectionParameter_export_error.phpt +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -ReflectionParameter::export() without parameters ---CREDITS-- -Stefan Koopmanschap <stefan@stefankoopmanschap.nl> ---FILE-- -<?php -function ReflectionParameterTest($test, $test2 = null) { - echo $test; -} -$reflect = new ReflectionFunction('ReflectionParameterTest'); -foreach($reflect->getParameters() as $key => $value) { - ReflectionParameter::export(); -} -?> -==DONE== ---EXPECTF-- -Warning: ReflectionParameter::export() expects at least 2 parameters, 0 given in %s.php on line %d - -Warning: ReflectionParameter::export() expects at least 2 parameters, 0 given in %s.php on line %d -==DONE== diff --git a/ext/reflection/tests/ReflectionParameter_export_error2.phpt b/ext/reflection/tests/ReflectionParameter_export_error2.phpt index aa0bc0aa7c..38cd99171b 100644 --- a/ext/reflection/tests/ReflectionParameter_export_error2.phpt +++ b/ext/reflection/tests/ReflectionParameter_export_error2.phpt @@ -26,6 +26,9 @@ catch (ReflectionException $e) { echo $e->getMessage() . "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function ReflectionParameter::export() is deprecated in %s on line %d Method ReflectionFunction::__invoke() does not exist + +Deprecated: Function ReflectionParameter::export() is deprecated in %s on line %d The parameter class is expected to be either a string, an array(class, method) or a callable object diff --git a/ext/reflection/tests/ReflectionParameter_export_error3.phpt b/ext/reflection/tests/ReflectionParameter_export_error3.phpt index f5223c35fe..b098a9251d 100644 --- a/ext/reflection/tests/ReflectionParameter_export_error3.phpt +++ b/ext/reflection/tests/ReflectionParameter_export_error3.phpt @@ -13,9 +13,11 @@ foreach($params as $key => $value) { ReflectionParameter::export('ReflectionParameterTest', 'incorrect_parameter'); } --EXPECTF-- -Fatal error: Uncaught ReflectionException: The parameter specified by its name could not be found in %s.php:%d +Deprecated: Function ReflectionParameter::export() is deprecated in %s on line %d + +Fatal error: Uncaught ReflectionException: The parameter specified by its name could not be found in %s:%d Stack trace: #0 [internal function]: ReflectionParameter->__construct('ReflectionParam...', 'incorrect_param...') -#1 %s.php(%d): ReflectionParameter::export('ReflectionParam...', 'incorrect_param...') +#1 %s(%d): ReflectionParameter::export('ReflectionParam...', 'incorrect_param...') #2 {main} - thrown in %s.php on line %d + thrown in %s on line %d diff --git a/ext/reflection/tests/ReflectionProperty_basic1.phpt b/ext/reflection/tests/ReflectionProperty_basic1.phpt index 18eb71fa10..1748ebfca9 100644 --- a/ext/reflection/tests/ReflectionProperty_basic1.phpt +++ b/ext/reflection/tests/ReflectionProperty_basic1.phpt @@ -47,7 +47,7 @@ reflectProperty("TestClass", "prot"); reflectProperty("TestClass", "priv"); ?> ---EXPECT-- +--EXPECTF-- ********************************** Reflecting on property TestClass::pub @@ -55,9 +55,13 @@ __toString(): string(35) "Property [ <default> public $pub ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d string(35) "Property [ <default> public $pub ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d Property [ <default> public $pub ] NULL @@ -84,9 +88,13 @@ __toString(): string(33) "Property [ public static $stat ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d string(33) "Property [ public static $stat ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d Property [ public static $stat ] NULL @@ -113,9 +121,13 @@ __toString(): string(39) "Property [ <default> protected $prot ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d string(39) "Property [ <default> protected $prot ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d Property [ <default> protected $prot ] NULL @@ -138,9 +150,13 @@ __toString(): string(37) "Property [ <default> private $priv ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d string(37) "Property [ <default> private $priv ] " export(): + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d Property [ <default> private $priv ] NULL diff --git a/ext/reflection/tests/ReflectionProperty_basic2.phpt b/ext/reflection/tests/ReflectionProperty_basic2.phpt index 0491073ace..09495f744b 100644 --- a/ext/reflection/tests/ReflectionProperty_basic2.phpt +++ b/ext/reflection/tests/ReflectionProperty_basic2.phpt @@ -43,7 +43,7 @@ Reflecting on property TestClass::pub isDefault(): bool(true) getModifiers(): -int(256) +int(1) getDeclaringClass(): object(ReflectionClass)#%d (1) { ["name"]=> @@ -59,7 +59,7 @@ Reflecting on property TestClass::stat isDefault(): bool(true) getModifiers(): -int(257) +int(17) getDeclaringClass(): object(ReflectionClass)#%d (1) { ["name"]=> @@ -75,7 +75,7 @@ Reflecting on property TestClass::prot isDefault(): bool(true) getModifiers(): -int(512) +int(2) getDeclaringClass(): object(ReflectionClass)#%d (1) { ["name"]=> @@ -93,7 +93,7 @@ Reflecting on property TestClass::priv isDefault(): bool(true) getModifiers(): -int(1024) +int(4) getDeclaringClass(): object(ReflectionClass)#%d (1) { ["name"]=> diff --git a/ext/reflection/tests/ReflectionProperty_export_basic.phpt b/ext/reflection/tests/ReflectionProperty_export_basic.phpt index e77a3b714a..28f1f6b988 100644 --- a/ext/reflection/tests/ReflectionProperty_export_basic.phpt +++ b/ext/reflection/tests/ReflectionProperty_export_basic.phpt @@ -1,5 +1,5 @@ --TEST-- -Test ReflectionProperty::export() usage. +Test ReflectionProperty::__toString() usage. --FILE-- <?php @@ -7,10 +7,8 @@ class TestClass { public $proper = 5; } -var_dump(ReflectionProperty::export('TestClass', 'proper')); +echo new ReflectionProperty('TestClass', 'proper'); ?> --EXPECT-- Property [ <default> public $proper ] - -NULL diff --git a/ext/reflection/tests/ReflectionProperty_export_error.phpt b/ext/reflection/tests/ReflectionProperty_export_error.phpt index ab09ed01f0..114b4c0ac8 100644 --- a/ext/reflection/tests/ReflectionProperty_export_error.phpt +++ b/ext/reflection/tests/ReflectionProperty_export_error.phpt @@ -39,16 +39,26 @@ ReflectionProperty::export('TestClass', "nonExistentProperty", true, false); ?> --EXPECTF-- Non-existent class: + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d Class NonExistentClass does not exist Wrong property parameter type: + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d The parameter class is expected to be either a string or an object Non-existent property: + +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d Property TestClass::$nonExistentProperty does not exist Incorrect number of args: +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d + Warning: ReflectionProperty::export() expects at least 2 parameters, 0 given in %s on line %d +Deprecated: Function ReflectionProperty::export() is deprecated in %s on line %d + Warning: ReflectionProperty::export() expects at most 3 parameters, 4 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt b/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt deleted file mode 100644 index dae7be2fb9..0000000000 --- a/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -Test ReflectionProperty::getDocComment() errors. ---FILE-- -<?php - -class C { - public $a; -} - -$rc = new ReflectionProperty('C', 'a'); -var_dump($rc->getDocComment(null)); -var_dump($rc->getDocComment('X')); -var_dump($rc->getDocComment(true)); -var_dump($rc->getDocComment(array(1, 2, 3))); - -?> ---EXPECTF-- -Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL - -Warning: ReflectionProperty::getDocComment() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt b/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt index 6d7ddbe834..a297a10436 100644 --- a/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt +++ b/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt @@ -40,27 +40,27 @@ reflectProperty("TestClass", "priv"); Reflecting on property TestClass::pub getModifiers(): -int(256) +int(1) ********************************** ********************************** Reflecting on property TestClass::stat getModifiers(): -int(257) +int(17) ********************************** ********************************** Reflecting on property TestClass::prot getModifiers(): -int(512) +int(2) ********************************** ********************************** Reflecting on property TestClass::priv getModifiers(): -int(1024) +int(4) ********************************** diff --git a/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt index 4c99444e30..6856569d3e 100644 --- a/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt +++ b/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt @@ -32,15 +32,15 @@ for ($i = 1;$i <= 6;$i++) { ?> --EXPECT-- -C::a1: int(256) -D::a1: int(256) -C::a2: int(512) -D::a2: int(512) -C::a3: int(1024) -D::a3: int(1024) -C::a4: int(257) -D::a4: int(257) -C::a5: int(513) -D::a5: int(513) -C::a6: int(1025) -D::a6: int(1025) +C::a1: int(1) +D::a1: int(1) +C::a2: int(2) +D::a2: int(2) +C::a3: int(4) +D::a3: int(4) +C::a4: int(17) +D::a4: int(17) +C::a5: int(18) +D::a5: int(18) +C::a6: int(20) +D::a6: int(20) diff --git a/ext/reflection/tests/ReflectionProperty_isInitialized.phpt b/ext/reflection/tests/ReflectionProperty_isInitialized.phpt new file mode 100644 index 0000000000..f1f6e53ebd --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isInitialized.phpt @@ -0,0 +1,113 @@ +--TEST-- +Test ReflectionProperty::isInitialized() +--FILE-- +<?php + +class A { + public static ?string $ssv = null; + public static ?string $ss; + public static $s; + public ?int $iv = null; + public ?int $i; + public $n; + + private int $p; +} + +class B extends A { } + +echo "Static properties:\n"; +var_dump((new ReflectionProperty(A::class, 'ssv'))->isInitialized()); +var_dump((new ReflectionProperty(A::class, 'ss'))->isInitialized()); +var_dump((new ReflectionProperty(A::class, 's'))->isInitialized()); + +echo "Declared properties:\n"; +$a = new A; +var_dump((new ReflectionProperty($a, 'iv'))->isInitialized($a)); +var_dump((new ReflectionProperty($a, 'i'))->isInitialized($a)); +var_dump((new ReflectionProperty($a, 'n'))->isInitialized($a)); + +echo "Declared properties after unset:\n"; +unset($a->iv); +unset($a->i); +unset($a->n); +var_dump((new ReflectionProperty($a, 'i'))->isInitialized($a)); +var_dump((new ReflectionProperty($a, 'iv'))->isInitialized($a)); +var_dump((new ReflectionProperty($a, 'n'))->isInitialized($a)); + +echo "Dynamic properties:\n"; +$a->d = null; +$rp = new ReflectionProperty($a, 'd'); +var_dump($rp->isInitialized($a)); +unset($a->d); +var_dump($rp->isInitialized($a)); + +echo "Visibility handling:\n"; +$rp = new ReflectionProperty('A', 'p'); +try { + var_dump($rp->isInitialized($a)); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} +$rp->setAccessible(true); +var_dump($rp->isInitialized($a)); + +echo "Object type:\n"; +$rp = new ReflectionProperty('B', 'i'); +var_dump($rp->isInitialized($a)); + +try { + var_dump($rp->isInitialized(new stdClass)); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} + +class WithMagic { + public $prop; + public int $intProp; + + public function __isset($name) { + echo "__isset($name)\n"; + return true; + } + + public function __get($name) { + echo "__get($name)\n"; + return "foobar"; + } +} + +echo "Class with __isset:\n"; +$obj = new WithMagic; +unset($obj->prop); +$rp = new ReflectionProperty('WithMagic', 'prop'); +var_dump($rp->isInitialized($obj)); +$rp = new ReflectionProperty('WithMagic', 'intProp'); +var_dump($rp->isInitialized($obj)); + +?> +--EXPECT-- +Static properties: +bool(true) +bool(false) +bool(true) +Declared properties: +bool(true) +bool(false) +bool(true) +Declared properties after unset: +bool(false) +bool(false) +bool(false) +Dynamic properties: +bool(true) +bool(false) +Visibility handling: +Cannot access non-public member A::$p +bool(false) +Object type: +bool(false) +Given object is not an instance of the class this property was declared in +Class with __isset: +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_typed_static.phpt b/ext/reflection/tests/ReflectionProperty_typed_static.phpt new file mode 100644 index 0000000000..77f95d77ef --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_typed_static.phpt @@ -0,0 +1,51 @@ +--TEST-- +ReflectionProperty::getValue() on typed static property +--FILE-- +<?php + +class Test { + public static int $x = 42; + public static int $y; + public static $z; +} + +$rp = new ReflectionProperty('Test', 'x'); +var_dump($rp->getValue()); + +$rp = new ReflectionProperty('Test', 'y'); +try { + var_dump($rp->getValue()); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$rp->setValue("24"); +var_dump($rp->getValue()); + +try { + $rp->setValue("foo"); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +var_dump($rp->getValue()); + +Test::$z =& Test::$y; + +$rp = new ReflectionProperty('Test', 'z'); +try { + $rp->setValue("foo"); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +var_dump($rp->getValue()); + + +?> +--EXPECT-- +int(42) +Typed static property Test::$y must not be accessed before initialization +int(24) +Typed property Test::$y must be int, string used +int(24) +Cannot assign string to reference held by property Test::$y of type int +int(24) diff --git a/ext/reflection/tests/ReflectionReference.phpt b/ext/reflection/tests/ReflectionReference.phpt new file mode 100644 index 0000000000..2963c30232 --- /dev/null +++ b/ext/reflection/tests/ReflectionReference.phpt @@ -0,0 +1,59 @@ +--TEST-- +Basic ReflectionReference functionality +--FILE-- +<?php + +$ary = [0, 1, 2, 3]; +$ref1 =& $ary[1]; +unset($ref1); +$ref2 =& $ary[2]; +$ref3 =& $ary[3]; + +echo "fromArrayElement():\n"; +$r0 = ReflectionReference::fromArrayElement($ary, 0); +var_dump($r0 === null); +$r1 = ReflectionReference::fromArrayElement($ary, 1); +var_dump($r1 === null); +$r2 = ReflectionReference::fromArrayElement($ary, 2); +var_dump($r2 instanceof ReflectionReference); +$r3 = ReflectionReference::fromArrayElement($ary, 3); +var_dump($r2 instanceof ReflectionReference); + +echo "getId() #1:\n"; +var_dump($r2->getId() === $r2->getId()); +var_dump($r3->getId() === $r3->getId()); +var_dump($r2->getId() !== $r3->getId()); + +echo "getId() #2:\n"; +$ary2 = [&$ary[2], &$ref3]; +$r2_2 = ReflectionReference::fromArrayElement($ary2, 0); +$r3_2 = ReflectionReference::fromArrayElement($ary2, 1); +var_dump($r2->getId() === $r2_2->getId()); +var_dump($r3->getId() === $r3_2->getId()); + +echo "getId() #3:\n"; +$r2_id = $r2->getId(); +$r3_id = $r3->getId(); +unset($r0, $r1, $r2, $r3, $r2_2, $r3_2); +$r2 = ReflectionReference::fromArrayElement($ary, 2); +$r3 = ReflectionReference::fromArrayElement($ary, 3); +var_dump($r2_id === $r2->getId()); +var_dump($r3_id === $r3->getId()); + +?> +--EXPECT-- +fromArrayElement(): +bool(true) +bool(true) +bool(true) +bool(true) +getId() #1: +bool(true) +bool(true) +bool(true) +getId() #2: +bool(true) +bool(true) +getId() #3: +bool(true) +bool(true) diff --git a/ext/reflection/tests/ReflectionReference_bug78263.phpt b/ext/reflection/tests/ReflectionReference_bug78263.phpt new file mode 100644 index 0000000000..868edc0812 --- /dev/null +++ b/ext/reflection/tests/ReflectionReference_bug78263.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78263: Handling of self-referential array special case +--FILE-- +<?php + +// The case of a directly self-referential array is special and will +// be treated as a proper reference despite rc=1 during array copying. +$a = [&$a]; +$b = [$a]; +unset($a); + +var_dump(ReflectionReference::fromArrayElement($b[0], 0)); + +?> +--EXPECT-- +object(ReflectionReference)#1 (0) { +} diff --git a/ext/reflection/tests/ReflectionReference_errors.phpt b/ext/reflection/tests/ReflectionReference_errors.phpt new file mode 100644 index 0000000000..8e52a1d223 --- /dev/null +++ b/ext/reflection/tests/ReflectionReference_errors.phpt @@ -0,0 +1,52 @@ +--TEST-- +Various error conditions for ReflectionReference +--FILE-- +<?php + +try { + new ReflectionReference(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +try { + ReflectionReference::fromArrayElement(new stdClass, "test"); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +try { + ReflectionReference::fromArrayElement([], 1.5); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +try { + $ary = [0, 1, 2]; + ReflectionReference::fromArrayElement($ary, 3); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} + +try { + $ary = [&$ary]; + $ref = ReflectionReference::fromArrayElement($ary, 0); + var_dump(serialize($ref)); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(unserialize('O:19:"ReflectionReference":0:{}')); + +?> +--EXPECTF-- +Call to private ReflectionReference::__construct() from invalid context +ReflectionReference::fromArrayElement() expects parameter 1 to be array, object given +Key must be array or string +Array key not found +Serialization of 'ReflectionReference' is not allowed + +Warning: Erroneous data format for unserializing 'ReflectionReference' in %s on line %d + +Notice: unserialize(): Error at offset 30 of 31 bytes in %s on line %d +bool(false) diff --git a/ext/reflection/tests/ReflectionType_001.phpt b/ext/reflection/tests/ReflectionType_001.phpt index d949e18107..1eb521317c 100644 --- a/ext/reflection/tests/ReflectionType_001.phpt +++ b/ext/reflection/tests/ReflectionType_001.phpt @@ -74,6 +74,32 @@ foreach ([ } } +echo "\n*** property types\n"; + +class PropTypeTest { + public int $int; + public string $string; + public array $arr; + public iterable $iterable; + public stdClass $std; + public OtherThing $other; + public $mixed; +} + +$reflector = new ReflectionClass(PropTypeTest::class); + +foreach ($reflector->getProperties() as $name => $property) { + if ($property->hasType()) { + printf("public %s $%s;\n", + $property->getType()->getName(), $property->getName()); + } else printf("public $%s;\n", $property->getName()); +} + +echo "*** resolved property types\n"; +$obj = new PropTypeTest; +$obj->std = new stdClass; +$r = (new ReflectionProperty($obj, 'std'))->getType(); +var_dump($r->getName()); ?> --EXPECT-- *** functions @@ -185,3 +211,14 @@ bool(true) bool(false) bool(false) string(4) "Test" + +*** property types +public int $int; +public string $string; +public array $arr; +public iterable $iterable; +public stdClass $std; +public OtherThing $other; +public $mixed; +*** resolved property types +string(8) "stdClass" diff --git a/ext/reflection/tests/ReflectionZendExtension.phpt b/ext/reflection/tests/ReflectionZendExtension.phpt index b4cd96e97b..bce34f5a2c 100644 --- a/ext/reflection/tests/ReflectionZendExtension.phpt +++ b/ext/reflection/tests/ReflectionZendExtension.phpt @@ -16,8 +16,10 @@ var_dump(gettype($reflection->export('Zend OPcache', true)) === 'string'); ?> --EXPECTF-- string(17) "Zend Technologies" -string(23) "Copyright (c) 1999-20%d" +string(13) "Copyright (c)" string(12) "Zend OPcache" string(20) "http://www.zend.com/" bool(true) + +Deprecated: Function ReflectionZendExtension::export() is deprecated in %s on line %d bool(true) diff --git a/ext/reflection/tests/bug29986.phpt b/ext/reflection/tests/bug29986.phpt index 3d8d6ee7c5..97aafd3820 100644 --- a/ext/reflection/tests/bug29986.phpt +++ b/ext/reflection/tests/bug29986.phpt @@ -13,7 +13,7 @@ class just_constants const FLOAT_CONSTANT = 3.14159265; } -Reflection::export(new ReflectionClass('just_constants')); +echo new ReflectionClass('just_constants'); ?> --EXPECTF-- Class [ <user> class just_constants ] { diff --git a/ext/reflection/tests/bug33389.phpt b/ext/reflection/tests/bug33389.phpt index f1997a397c..fb166c16ba 100644 --- a/ext/reflection/tests/bug33389.phpt +++ b/ext/reflection/tests/bug33389.phpt @@ -19,10 +19,7 @@ class Test { function foo() { } } -Reflection::export(new ReflectionClass('Test')); -?> -===DONE=== -<?php exit(0); ?> +echo new ReflectionClass('Test'); --EXPECTF-- Class [ <user> class Test ] { @@ %sbug33389.php 3-18 @@ -93,5 +90,3 @@ Class [ <user> class Test ] { } } } - -===DONE=== diff --git a/ext/reflection/tests/bug37964.phpt b/ext/reflection/tests/bug37964.phpt index f3c161da8d..f3ebe9f72a 100644 --- a/ext/reflection/tests/bug37964.phpt +++ b/ext/reflection/tests/bug37964.phpt @@ -19,7 +19,7 @@ class bar extends foo { } } -Reflection::export(new ReflectionClass(new bar)); +echo new ReflectionClass(new bar); ?> --EXPECTF-- diff --git a/ext/reflection/tests/bug38942.phpt b/ext/reflection/tests/bug38942.phpt index 59666607cb..6dbe396ae6 100644 --- a/ext/reflection/tests/bug38942.phpt +++ b/ext/reflection/tests/bug38942.phpt @@ -8,7 +8,7 @@ class foo { class bar extends foo { } -ReflectionClass::export("bar"); +echo new ReflectionClass("bar"); ?> --EXPECTF-- Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; foo has a deprecated constructor in %s on line %d diff --git a/ext/reflection/tests/bug41061.phpt b/ext/reflection/tests/bug41061.phpt index d907907dcf..027b872be9 100644 --- a/ext/reflection/tests/bug41061.phpt +++ b/ext/reflection/tests/bug41061.phpt @@ -1,5 +1,5 @@ --TEST-- -Reflection Bug #41061 ("visibility error" in ReflectionFunction::export()) +Reflection Bug #41061 ("visibility error" in ReflectionFunction::__toString()) --FILE-- <?php @@ -11,8 +11,8 @@ class bar { } } -Reflection::export(new ReflectionFunction('foo')); -Reflection::export(new ReflectionMethod('bar', 'foo')); +echo new ReflectionFunction('foo'), "\n"; +echo new ReflectionMethod('bar', 'foo'), "\n"; ?> ===DONE=== <?php exit(0); ?> diff --git a/ext/reflection/tests/bug45571.phpt b/ext/reflection/tests/bug45571.phpt index 2aa5698879..74245fc24c 100644 --- a/ext/reflection/tests/bug45571.phpt +++ b/ext/reflection/tests/bug45571.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #45571 (ReflectionClass::export() shows superclasses' private static methods.) +Bug #45571 (ReflectionClass::__toString() shows superclasses' private static methods.) --FILE-- <?php @@ -14,7 +14,7 @@ Class A { Class C extends A { } -ReflectionClass::export("C"); +echo new ReflectionClass("C"); ?> --EXPECTF-- diff --git a/ext/reflection/tests/bug45765.phpt b/ext/reflection/tests/bug45765.phpt index 80cb39d0ac..5c33faca2b 100644 --- a/ext/reflection/tests/bug45765.phpt +++ b/ext/reflection/tests/bug45765.phpt @@ -23,7 +23,7 @@ class foo extends foo2 { } } -ReflectionObject::export(new foo); +echo new ReflectionObject(new foo); ?> --EXPECTF-- diff --git a/ext/reflection/tests/bug46205.phpt b/ext/reflection/tests/bug46205.phpt index ef7a692cb7..5ca8ac1cd0 100644 --- a/ext/reflection/tests/bug46205.phpt +++ b/ext/reflection/tests/bug46205.phpt @@ -10,5 +10,6 @@ try { } catch (Exception $e) { } ?> ok ---EXPECT-- +--EXPECTF-- +Deprecated: Function ReflectionParameter::export() is deprecated in %s on line %d ok diff --git a/ext/reflection/tests/bug49719.phpt b/ext/reflection/tests/bug49719.phpt index f55334c951..6211b6b543 100644 --- a/ext/reflection/tests/bug49719.phpt +++ b/ext/reflection/tests/bug49719.phpt @@ -36,7 +36,7 @@ $prop->setAccessible(true); var_dump($prop->getValue(new b2)); ?> ---EXPECTF-- +--EXPECT-- bool(false) bool(false) bool(false) diff --git a/ext/reflection/tests/bug61388.phpt b/ext/reflection/tests/bug61388.phpt index 3d6dc83fa0..b9fe6bfaaa 100644 --- a/ext/reflection/tests/bug61388.phpt +++ b/ext/reflection/tests/bug61388.phpt @@ -14,12 +14,6 @@ print_r($reflObj->getProperties(ReflectionProperty::IS_PUBLIC)); --EXPECT-- Array ( - [0] => ReflectionProperty Object - ( - [name] => test - [class] => ArrayObject - ) - ) Array ( diff --git a/ext/reflection/tests/bug72661.phpt b/ext/reflection/tests/bug72661.phpt index b1cb764beb..46ba048078 100644 --- a/ext/reflection/tests/bug72661.phpt +++ b/ext/reflection/tests/bug72661.phpt @@ -6,5 +6,6 @@ function test(iterable $arg) { } var_dump((string)(new ReflectionParameter("test", 0))->getType()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function ReflectionType::__toString() is deprecated in %s on line %d string(8) "iterable" diff --git a/ext/reflection/tests/bug74454.phpt b/ext/reflection/tests/bug74454.phpt index d2d6e88649..9e0332d893 100644 --- a/ext/reflection/tests/bug74454.phpt +++ b/ext/reflection/tests/bug74454.phpt @@ -14,6 +14,6 @@ function load_file() { } ?> ===DONE=== ---EXPECTF-- +--EXPECT-- ParseError: syntax error, unexpected 'if' (T_IF), expecting function (T_FUNCTION) or const (T_CONST) ===DONE=== diff --git a/ext/reflection/tests/bug74673.phpt b/ext/reflection/tests/bug74673.phpt index 8e4e8e3a18..47f7604e8b 100644 --- a/ext/reflection/tests/bug74673.phpt +++ b/ext/reflection/tests/bug74673.phpt @@ -19,4 +19,9 @@ $class = new ReflectionClass('A'); echo $class; ?> --EXPECTF-- -Fatal error: Method ReflectionClass::__toString() must not throw an exception, caught Exception: in %sbug74673.php on line %d +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 [internal function]: {closure}(2, 'Use of undefine...', %s, %d, Array) +#1 %s(%d): ReflectionClass->__toString() +#2 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/bug76737.phpt b/ext/reflection/tests/bug76737.phpt new file mode 100644 index 0000000000..716b40e76a --- /dev/null +++ b/ext/reflection/tests/bug76737.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #76737: Unserialized reflection objects are broken, they shouldn't be serializable +--FILE-- +<?php + +try { + $r = new ReflectionClass('stdClass'); + var_dump(serialize($r)); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} +try { + $s = 'C:15:"ReflectionClass":0:{}'; + var_dump(unserialize($s)); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} +try { + $s = 'O:15:"ReflectionClass":0:{}'; + var_dump(unserialize($s)); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +Serialization of 'ReflectionClass' is not allowed +Unserialization of 'ReflectionClass' is not allowed + +Warning: Erroneous data format for unserializing 'ReflectionClass' in %s on line %d + +Notice: unserialize(): Error at offset 26 of 27 bytes in %s on line %d +bool(false) diff --git a/ext/reflection/tests/exception.inc b/ext/reflection/tests/exception.inc deleted file mode 100644 index da3fceaac7..0000000000 --- a/ext/reflection/tests/exception.inc +++ /dev/null @@ -1,16 +0,0 @@ -<?php -class ReflectionExceptionEx extends ReflectionException { - function MyException($_errno, $_errmsg) { - $this->errno = $_errno; - $this->errmsg = $_errmsg; - } - - function getErrno() { - return $this->errno; - } - - function getErrmsg() { - return $this->errmsg; - } -} -?> diff --git a/ext/reflection/tests/traits002.phpt b/ext/reflection/tests/traits002.phpt index 3a4b294961..c7a09bfb19 100644 --- a/ext/reflection/tests/traits002.phpt +++ b/ext/reflection/tests/traits002.phpt @@ -10,8 +10,8 @@ trait bar { } -reflectionclass::export('foo'); -reflectionclass::export('bar'); +echo new ReflectionClass('foo'), "\n"; +echo new ReflectionClass('bar'), "\n"; ?> --EXPECTF-- |
