diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /ext/reflection | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/reflection')
314 files changed, 22709 insertions, 0 deletions
diff --git a/ext/reflection/CREDITS b/ext/reflection/CREDITS new file mode 100755 index 0000000..84be988 --- /dev/null +++ b/ext/reflection/CREDITS @@ -0,0 +1,2 @@ +Reflection +Marcus Boerger, Timm Friebe, George Schlossnagle, Andrei Zmievski, Johannes Schlueter diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4 new file mode 100755 index 0000000..7026636 --- /dev/null +++ b/ext/reflection/config.m4 @@ -0,0 +1,5 @@ +dnl $Id$ +dnl config.m4 for extension reflection + +AC_DEFINE(HAVE_REFLECTION, 1, [Whether Reflection is enabled]) +PHP_NEW_EXTENSION(reflection, php_reflection.c, no) diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32 new file mode 100755 index 0000000..724bf7b --- /dev/null +++ b/ext/reflection/config.w32 @@ -0,0 +1,6 @@ +// $Id$ +// vim:ft=javascript + +EXTENSION("reflection", "php_reflection.c", false /* never shared */); +AC_DEFINE('HAVE_REFLECTION', 1, 'Reflection support enabled'); +PHP_REFLECTION="yes";
\ No newline at end of file diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c new file mode 100644 index 0000000..659f4be --- /dev/null +++ b/ext/reflection/php_reflection.c @@ -0,0 +1,6195 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Timm Friebe <thekid@thekid.de> | + | George Schlossnagle <george@omniti.com> | + | Andrei Zmievski <andrei@gravitonic.com> | + | Marcus Boerger <helly@php.net> | + | Johannes Schlueter <johannes@php.net> | + +----------------------------------------------------------------------+ +*/ + +/* $Id: 25ecbad68e5a4573ffee43ea24a0591ea179492a $ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "php_reflection.h" +#include "ext/standard/info.h" + +#include "zend.h" +#include "zend_API.h" +#include "zend_exceptions.h" +#include "zend_operators.h" +#include "zend_constants.h" +#include "zend_ini.h" +#include "zend_interfaces.h" +#include "zend_closures.h" +#include "zend_extensions.h" + +#define reflection_update_property(object, name, value) do { \ + zval *member; \ + MAKE_STD_ZVAL(member); \ + ZVAL_STRINGL(member, name, sizeof(name)-1, 1); \ + zend_std_write_property(object, member, value, NULL TSRMLS_CC); \ + Z_DELREF_P(value); \ + zval_ptr_dtor(&member); \ + } while (0) + +/* Class entry pointers */ +PHPAPI zend_class_entry *reflector_ptr; +PHPAPI zend_class_entry *reflection_exception_ptr; +PHPAPI zend_class_entry *reflection_ptr; +PHPAPI zend_class_entry *reflection_function_abstract_ptr; +PHPAPI zend_class_entry *reflection_function_ptr; +PHPAPI zend_class_entry *reflection_parameter_ptr; +PHPAPI zend_class_entry *reflection_class_ptr; +PHPAPI zend_class_entry *reflection_object_ptr; +PHPAPI zend_class_entry *reflection_method_ptr; +PHPAPI zend_class_entry *reflection_property_ptr; +PHPAPI zend_class_entry *reflection_extension_ptr; +PHPAPI zend_class_entry *reflection_zend_extension_ptr; + +#if MBO_0 +ZEND_BEGIN_MODULE_GLOBALS(reflection) + int dummy; +ZEND_END_MODULE_GLOBALS(reflection) + +#ifdef ZTS +# define REFLECTION_G(v) \ + TSRMG(reflection_globals_id, zend_reflection_globals*, v) +extern int reflection_globals_id; +#else +# define REFLECTION_G(v) (reflection_globals.v) +extern zend_reflection_globals reflectionglobals; +#endif + +ZEND_DECLARE_MODULE_GLOBALS(reflection) +#endif /* MBO_0 */ + +/* Method macros */ + +#define METHOD_NOTSTATIC(ce) \ + if (!this_ptr || !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) { \ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \ + return; \ + } \ + +/* Exception throwing macro */ +#define _DO_THROW(msg) \ + zend_throw_exception(reflection_exception_ptr, msg, 0 TSRMLS_CC); \ + return; \ + +#define RETURN_ON_EXCEPTION \ + if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) { \ + return; \ + } + +#define GET_REFLECTION_OBJECT_PTR(target) \ + intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); \ + if (intern == NULL || intern->ptr == NULL) { \ + RETURN_ON_EXCEPTION \ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \ + } \ + target = intern->ptr; \ + +/* Class constants */ +#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, (long)value TSRMLS_CC); + +/* {{{ Smart string functions */ +typedef struct _string { + char *string; + int len; + int alloced; +} string; + +static void string_init(string *str) +{ + str->string = (char *) emalloc(1024); + str->len = 1; + str->alloced = 1024; + *str->string = '\0'; +} + +static string *string_printf(string *str, const char *format, ...) +{ + int len; + va_list arg; + char *s_tmp; + + va_start(arg, format); + len = zend_vspprintf(&s_tmp, 0, format, arg); + if (len) { + register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1); + if (str->alloced < nlen) { + str->alloced = nlen; + str->string = erealloc(str->string, str->alloced); + } + memcpy(str->string + str->len - 1, s_tmp, len + 1); + str->len += len; + } + efree(s_tmp); + va_end(arg); + return str; +} + +static string *string_write(string *str, char *buf, int len) +{ + register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1); + if (str->alloced < nlen) { + str->alloced = nlen; + str->string = erealloc(str->string, str->alloced); + } + memcpy(str->string + str->len - 1, buf, len); + str->len += len; + str->string[str->len - 1] = '\0'; + return str; +} + +static string *string_append(string *str, string *append) +{ + if (append->len > 1) { + string_write(str, append->string, append->len - 1); + } + return str; +} + +static void string_free(string *str) +{ + efree(str->string); + str->len = 0; + str->alloced = 0; + str->string = NULL; +} +/* }}} */ + +/* {{{ Object structure */ + +/* Struct for properties */ +typedef struct _property_reference { + zend_class_entry *ce; + zend_property_info prop; +} property_reference; + +/* Struct for parameters */ +typedef struct _parameter_reference { + zend_uint offset; + zend_uint required; + struct _zend_arg_info *arg_info; + zend_function *fptr; +} parameter_reference; + +typedef enum { + REF_TYPE_OTHER, /* Must be 0 */ + REF_TYPE_FUNCTION, + REF_TYPE_PARAMETER, + REF_TYPE_PROPERTY, + REF_TYPE_DYNAMIC_PROPERTY +} reflection_type_t; + +/* Struct for reflection objects */ +typedef struct { + zend_object zo; + void *ptr; + reflection_type_t ref_type; + zval *obj; + zend_class_entry *ce; + unsigned int ignore_visibility:1; +} reflection_object; + +/* }}} */ + +static zend_object_handlers reflection_object_handlers; + +static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC) /* {{{ */ +{ + zval **value; + + if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) { + RETURN_FALSE; + } + + MAKE_COPY_ZVAL(value, return_value); +} +/* }}} */ + +#ifdef ilia_0 +static void _default_lookup_entry(zval *object, char *name, int name_len, zval **return_value TSRMLS_DC) /* {{{ */ +{ + zval **value; + + if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) { + *return_value = NULL; + } else { + *return_value = *value; + } +} +/* }}} */ +#endif + +static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC) /* {{{ */ +{ + zend_uint num_interfaces = ++class_entry->num_interfaces; + + class_entry->interfaces = (zend_class_entry **) realloc(class_entry->interfaces, sizeof(zend_class_entry *) * num_interfaces); + class_entry->interfaces[num_interfaces - 1] = interface_entry; +} +/* }}} */ + +static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */ +{ + if (fptr + && fptr->type == ZEND_INTERNAL_FUNCTION + && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) + { + zend_function *copy_fptr; + copy_fptr = emalloc(sizeof(zend_function)); + memcpy(copy_fptr, fptr, sizeof(zend_function)); + copy_fptr->internal_function.function_name = estrdup(fptr->internal_function.function_name); + return copy_fptr; + } else { + /* no copy needed */ + return fptr; + } +} +/* }}} */ + +static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */ +{ + if (fptr + && fptr->type == ZEND_INTERNAL_FUNCTION + && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) + { + efree((char*)fptr->internal_function.function_name); + efree(fptr); + } +} +/* }}} */ + +static void reflection_free_objects_storage(void *object TSRMLS_DC) /* {{{ */ +{ + reflection_object *intern = (reflection_object *) object; + parameter_reference *reference; + property_reference *prop_reference; + + if (intern->ptr) { + switch (intern->ref_type) { + case REF_TYPE_PARAMETER: + reference = (parameter_reference*)intern->ptr; + _free_function(reference->fptr TSRMLS_CC); + efree(intern->ptr); + break; + case REF_TYPE_FUNCTION: + _free_function(intern->ptr TSRMLS_CC); + break; + case REF_TYPE_PROPERTY: + efree(intern->ptr); + break; + case REF_TYPE_DYNAMIC_PROPERTY: + prop_reference = (property_reference*)intern->ptr; + efree((char*)prop_reference->prop.name); + efree(intern->ptr); + break; + case REF_TYPE_OTHER: + break; + } + } + intern->ptr = NULL; + if (intern->obj) { + zval_ptr_dtor(&intern->obj); + } + zend_objects_free_object_storage(object TSRMLS_CC); +} +/* }}} */ + +static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ +{ + zend_object_value retval; + reflection_object *intern; + + intern = ecalloc(1, sizeof(reflection_object)); + intern->zo.ce = class_type; + + zend_object_std_init(&intern->zo, class_type TSRMLS_CC); + object_properties_init(&intern->zo, class_type); + retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, NULL TSRMLS_CC); + retval.handlers = &reflection_object_handlers; + return retval; +} +/* }}} */ + +static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC) /* {{{ */ +{ + if (!object) { + ALLOC_ZVAL(object); + } + Z_TYPE_P(object) = IS_OBJECT; + object_init_ex(object, pce); + Z_SET_REFCOUNT_P(object, 1); + Z_SET_ISREF_P(object); + return object; +} +/* }}} */ + +static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC); +static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC); +static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC); +static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC); +static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC); +static void _zend_extension_string(string *str, zend_extension *extension, char *indent TSRMLS_DC); + +/* {{{ _class_string */ +static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC) +{ + int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0; + string sub_indent; + + string_init(&sub_indent); + string_printf(&sub_indent, "%s ", indent); + + /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */ + if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) { + string_printf(str, "%s%s", indent, ce->info.user.doc_comment); + string_write(str, "\n", 1); + } + + if (obj) { + string_printf(str, "%sObject of class [ ", indent); + } else { + char *kind = "Class"; + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + kind = "Interface"; + } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + kind = "Trait"; + } + string_printf(str, "%s%s [ ", indent, kind); + } + string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal"); + if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module) { + string_printf(str, ":%s", ce->info.internal.module->name); + } + string_printf(str, "> "); + if (ce->get_iterator != NULL) { + string_printf(str, "<iterateable> "); + } + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + string_printf(str, "interface "); + } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + string_printf(str, "trait "); + } else { + if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + string_printf(str, "abstract "); + } + if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) { + string_printf(str, "final "); + } + string_printf(str, "class "); + } + string_printf(str, "%s", ce->name); + if (ce->parent) { + string_printf(str, " extends %s", ce->parent->name); + } + + if (ce->num_interfaces) { + zend_uint i; + + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + string_printf(str, " extends %s", ce->interfaces[0]->name); + } else { + string_printf(str, " implements %s", ce->interfaces[0]->name); + } + for (i = 1; i < ce->num_interfaces; ++i) { + string_printf(str, ", %s", ce->interfaces[i]->name); + } + } + string_printf(str, " ] {\n"); + + /* The information where a class is declared is only available for user classes */ + if (ce->type == ZEND_USER_CLASS) { + string_printf(str, "%s @@ %s %d-%d\n", indent, ce->info.user.filename, + ce->info.user.line_start, ce->info.user.line_end); + } + + /* Constants */ + if (&ce->constants_table) { + zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC); + string_printf(str, "\n"); + count = zend_hash_num_elements(&ce->constants_table); + string_printf(str, "%s - Constants [%d] {\n", indent, count); + if (count > 0) { + HashPosition pos; + zval **value; + char *key; + uint key_len; + ulong num_index; + + zend_hash_internal_pointer_reset_ex(&ce->constants_table, &pos); + + while (zend_hash_get_current_data_ex(&ce->constants_table, (void **) &value, &pos) == SUCCESS) { + zend_hash_get_current_key_ex(&ce->constants_table, &key, &key_len, &num_index, 0, &pos); + + _const_string(str, key, *value, indent TSRMLS_CC); + zend_hash_move_forward_ex(&ce->constants_table, &pos); + } + } + string_printf(str, "%s }\n", indent); + } + + /* Static properties */ + if (&ce->properties_info) { + /* counting static properties */ + count = zend_hash_num_elements(&ce->properties_info); + if (count > 0) { + HashPosition pos; + zend_property_info *prop; + + zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + + while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) { + if(prop->flags & ZEND_ACC_SHADOW) { + count_shadow_props++; + } else if (prop->flags & ZEND_ACC_STATIC) { + count_static_props++; + } + zend_hash_move_forward_ex(&ce->properties_info, &pos); + } + } + + /* static properties */ + string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props); + if (count_static_props > 0) { + HashPosition pos; + zend_property_info *prop; + + zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + + while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) { + if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) { + _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC); + } + + zend_hash_move_forward_ex(&ce->properties_info, &pos); + } + } + string_printf(str, "%s }\n", indent); + } + + /* Static methods */ + if (&ce->function_table) { + /* counting static methods */ + count = zend_hash_num_elements(&ce->function_table); + if (count > 0) { + HashPosition pos; + zend_function *mptr; + + zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos); + + while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) { + if (mptr->common.fn_flags & ZEND_ACC_STATIC + && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) + { + count_static_funcs++; + } + zend_hash_move_forward_ex(&ce->function_table, &pos); + } + } + + /* static methods */ + string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs); + if (count_static_funcs > 0) { + HashPosition pos; + zend_function *mptr; + + zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos); + + while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) { + if (mptr->common.fn_flags & ZEND_ACC_STATIC + && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) + { + string_printf(str, "\n"); + _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC); + } + zend_hash_move_forward_ex(&ce->function_table, &pos); + } + } else { + string_printf(str, "\n"); + } + string_printf(str, "%s }\n", indent); + } + + /* Default/Implicit properties */ + if (&ce->properties_info) { + count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props; + string_printf(str, "\n%s - Properties [%d] {\n", indent, count); + if (count > 0) { + HashPosition pos; + zend_property_info *prop; + + zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + + while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) { + if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) { + _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC); + } + zend_hash_move_forward_ex(&ce->properties_info, &pos); + } + } + string_printf(str, "%s }\n", indent); + } + + if (obj && Z_OBJ_HT_P(obj)->get_properties) { + string dyn; + HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC); + HashPosition pos; + zval **prop; + + string_init(&dyn); + count = 0; + + if (properties && zend_hash_num_elements(properties)) { + zend_hash_internal_pointer_reset_ex(properties, &pos); + + while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) { + char *prop_name; + uint prop_name_size; + ulong index; + + if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) { + if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */ + if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) { + count++; + _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC); + } + } + efree(prop_name); + } + zend_hash_move_forward_ex(properties, &pos); + } + } + + string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count); + string_append(str, &dyn); + string_printf(str, "%s }\n", indent); + string_free(&dyn); + } + + /* Non static methods */ + if (&ce->function_table) { + count = zend_hash_num_elements(&ce->function_table) - count_static_funcs; + if (count > 0) { + HashPosition pos; + zend_function *mptr; + string dyn; + + count = 0; + string_init(&dyn); + zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos); + + while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) { + if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0 + && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) + { + char *key; + uint key_len; + ulong num_index; + uint len = strlen(mptr->common.function_name); + + /* Do not display old-style inherited constructors */ + if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 + || mptr->common.scope == ce + || zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING + || zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) + { + zend_function *closure; + /* see if this is a closure */ + if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL) + { + mptr = closure; + } else { + closure = NULL; + } + string_printf(&dyn, "\n"); + _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC); + count++; + _free_function(closure TSRMLS_CC); + } + } + zend_hash_move_forward_ex(&ce->function_table, &pos); + } + string_printf(str, "\n%s - Methods [%d] {", indent, count); + if (!count) { + string_printf(str, "\n"); + } + string_append(str, &dyn); + string_free(&dyn); + } else { + string_printf(str, "\n%s - Methods [0] {\n", indent); + } + string_printf(str, "%s }\n", indent); + } + + string_printf(str, "%s}\n", indent); + string_free(&sub_indent); +} +/* }}} */ + +/* {{{ _const_string */ +static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC) +{ + char *type; + zval value_copy; + int use_copy; + + type = zend_zval_type_name(value); + + zend_make_printable_zval(value, &value_copy, &use_copy); + if (use_copy) { + value = &value_copy; + } + + string_printf(str, "%s Constant [ %s %s ] { %s }\n", + indent, type, name, Z_STRVAL_P(value)); + + if (use_copy) { + zval_dtor(value); + } +} +/* }}} */ + +/* {{{ _get_recv_opcode */ +static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset) +{ + zend_op *op = op_array->opcodes; + zend_op *end = op + op_array->last; + + ++offset; + while (op < end) { + if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) + && op->op1.num == (long)offset) + { + return op; + } + ++op; + } + return NULL; +} +/* }}} */ + +/* {{{ _parameter_string */ +static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, char* indent TSRMLS_DC) +{ + string_printf(str, "Parameter #%d [ ", offset); + if (offset >= required) { + string_printf(str, "<optional> "); + } else { + string_printf(str, "<required> "); + } + if (arg_info->class_name) { + string_printf(str, "%s ", arg_info->class_name); + if (arg_info->allow_null) { + string_printf(str, "or NULL "); + } + } else if (arg_info->type_hint) { + string_printf(str, "%s ", zend_get_type_by_const(arg_info->type_hint)); + if (arg_info->allow_null) { + string_printf(str, "or NULL "); + } + } + if (arg_info->pass_by_reference) { + string_write(str, "&", sizeof("&")-1); + } + if (arg_info->name) { + string_printf(str, "$%s", arg_info->name); + } else { + string_printf(str, "$param%d", offset); + } + if (fptr->type == ZEND_USER_FUNCTION && offset >= required) { + zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset); + if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) { + zval *zv, zv_copy; + int use_copy; + string_write(str, " = ", sizeof(" = ")-1); + ALLOC_ZVAL(zv); + *zv = *precv->op2.zv; + zval_copy_ctor(zv); + INIT_PZVAL(zv); + zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); + if (Z_TYPE_P(zv) == IS_BOOL) { + if (Z_LVAL_P(zv)) { + string_write(str, "true", sizeof("true")-1); + } else { + string_write(str, "false", sizeof("false")-1); + } + } else if (Z_TYPE_P(zv) == IS_NULL) { + string_write(str, "NULL", sizeof("NULL")-1); + } else if (Z_TYPE_P(zv) == IS_STRING) { + string_write(str, "'", sizeof("'")-1); + string_write(str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 15)); + if (Z_STRLEN_P(zv) > 15) { + string_write(str, "...", sizeof("...")-1); + } + string_write(str, "'", sizeof("'")-1); + } else if (Z_TYPE_P(zv) == IS_ARRAY) { + string_write(str, "Array", sizeof("Array")-1); + } else { + zend_make_printable_zval(zv, &zv_copy, &use_copy); + string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy)); + if (use_copy) { + zval_dtor(&zv_copy); + } + } + zval_ptr_dtor(&zv); + } + } + string_write(str, " ]", sizeof(" ]")-1); +} +/* }}} */ + +/* {{{ _function_parameter_string */ +static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC) +{ + struct _zend_arg_info *arg_info = fptr->common.arg_info; + zend_uint i, required = fptr->common.required_num_args; + + if (!arg_info) { + return; + } + + string_printf(str, "\n"); + string_printf(str, "%s- Parameters [%d] {\n", indent, fptr->common.num_args); + for (i = 0; i < fptr->common.num_args; i++) { + string_printf(str, "%s ", indent); + _parameter_string(str, fptr, arg_info, i, required, indent TSRMLS_CC); + string_write(str, "\n", sizeof("\n")-1); + arg_info++; + } + string_printf(str, "%s}\n", indent); +} +/* }}} */ + +/* {{{ _function_closure_string */ +static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC) +{ + zend_uint i, count; + ulong num_index; + char *key; + uint key_len; + HashTable *static_variables; + HashPosition pos; + + if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) { + return; + } + + static_variables = fptr->op_array.static_variables; + count = zend_hash_num_elements(static_variables); + + if (!count) { + return; + } + + string_printf(str, "\n"); + string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables)); + zend_hash_internal_pointer_reset_ex(static_variables, &pos); + i = 0; + while (i < count) { + zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos); + string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, key); + zend_hash_move_forward_ex(static_variables, &pos); + } + string_printf(str, "%s}\n", indent); +} +/* }}} */ + +/* {{{ _function_string */ +static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC) +{ + string param_indent; + zend_function *overwrites; + char *lc_name; + unsigned int lc_name_len; + + /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) + * What's "wrong" is that any whitespace before the doc comment start is + * swallowed, leading to an unaligned comment. + */ + if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) { + string_printf(str, "%s%s\n", indent, fptr->op_array.doc_comment); + } + + string_write(str, indent, strlen(indent)); + string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ ")); + string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal"); + if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) { + string_printf(str, ", deprecated"); + } + if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) { + string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name); + } + + if (scope && fptr->common.scope) { + if (fptr->common.scope != scope) { + string_printf(str, ", inherits %s", fptr->common.scope->name); + } else if (fptr->common.scope->parent) { + lc_name_len = strlen(fptr->common.function_name); + lc_name = zend_str_tolower_dup(fptr->common.function_name, lc_name_len); + if (zend_hash_find(&fptr->common.scope->parent->function_table, lc_name, lc_name_len + 1, (void**) &overwrites) == SUCCESS) { + if (fptr->common.scope != overwrites->common.scope) { + string_printf(str, ", overwrites %s", overwrites->common.scope->name); + } + } + efree(lc_name); + } + } + if (fptr->common.prototype && fptr->common.prototype->common.scope) { + string_printf(str, ", prototype %s", fptr->common.prototype->common.scope->name); + } + if (fptr->common.fn_flags & ZEND_ACC_CTOR) { + string_printf(str, ", ctor"); + } + if (fptr->common.fn_flags & ZEND_ACC_DTOR) { + string_printf(str, ", dtor"); + } + string_printf(str, "> "); + + if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) { + string_printf(str, "abstract "); + } + if (fptr->common.fn_flags & ZEND_ACC_FINAL) { + string_printf(str, "final "); + } + if (fptr->common.fn_flags & ZEND_ACC_STATIC) { + string_printf(str, "static "); + } + + if (fptr->common.scope) { + /* These are mutually exclusive */ + switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) { + case ZEND_ACC_PUBLIC: + string_printf(str, "public "); + break; + case ZEND_ACC_PRIVATE: + string_printf(str, "private "); + break; + case ZEND_ACC_PROTECTED: + string_printf(str, "protected "); + break; + default: + string_printf(str, "<visibility error> "); + break; + } + string_printf(str, "method "); + } else { + string_printf(str, "function "); + } + + if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) { + string_printf(str, "&"); + } + string_printf(str, "%s ] {\n", fptr->common.function_name); + /* The information where a function is declared is only available for user classes */ + if (fptr->type == ZEND_USER_FUNCTION) { + string_printf(str, "%s @@ %s %d - %d\n", indent, + fptr->op_array.filename, + fptr->op_array.line_start, + fptr->op_array.line_end); + } + string_init(¶m_indent); + string_printf(¶m_indent, "%s ", indent); + if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) { + _function_closure_string(str, fptr, param_indent.string TSRMLS_CC); + } + _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC); + string_free(¶m_indent); + string_printf(str, "%s}\n", indent); +} +/* }}} */ + +/* {{{ _property_string */ +static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC) +{ + const char *class_name; + + string_printf(str, "%sProperty [ ", indent); + if (!prop) { + string_printf(str, "<dynamic> public $%s", prop_name); + } else { + if (!(prop->flags & ZEND_ACC_STATIC)) { + if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) { + string_write(str, "<implicit> ", sizeof("<implicit> ") - 1); + } else { + string_write(str, "<default> ", sizeof("<default> ") - 1); + } + } + + /* These are mutually exclusive */ + switch (prop->flags & ZEND_ACC_PPP_MASK) { + case ZEND_ACC_PUBLIC: + string_printf(str, "public "); + break; + case ZEND_ACC_PRIVATE: + string_printf(str, "private "); + break; + case ZEND_ACC_PROTECTED: + string_printf(str, "protected "); + break; + } + if(prop->flags & ZEND_ACC_STATIC) { + string_printf(str, "static "); + } + + zend_unmangle_property_name(prop->name, prop->name_length, &class_name, (const char**)&prop_name); + string_printf(str, "$%s", prop_name); + } + + string_printf(str, " ]\n"); +} +/* }}} */ + +static int _extension_ini_string(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + string *str = va_arg(args, string *); + char *indent = va_arg(args, char *); + int number = va_arg(args, int); + char *comma = ""; + + if (number == ini_entry->module_number) { + string_printf(str, " %sEntry [ %s <", indent, ini_entry->name); + if (ini_entry->modifiable == ZEND_INI_ALL) { + string_printf(str, "ALL"); + } else { + if (ini_entry->modifiable & ZEND_INI_USER) { + string_printf(str, "USER"); + comma = ","; + } + if (ini_entry->modifiable & ZEND_INI_PERDIR) { + string_printf(str, "%sPERDIR", comma); + comma = ","; + } + if (ini_entry->modifiable & ZEND_INI_SYSTEM) { + string_printf(str, "%sSYSTEM", comma); + } + } + + string_printf(str, "> ]\n"); + string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ini_entry->value : ""); + if (ini_entry->modified) { + string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ini_entry->orig_value : ""); + } + string_printf(str, " %s}\n", indent); + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +static int _extension_class_string(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + string *str = va_arg(args, string *); + 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 (((*pce)->type == ZEND_INTERNAL_CLASS) && (*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, module->name)) { + string_printf(str, "\n"); + _class_string(str, *pce, NULL, indent TSRMLS_CC); + (*num_classes)++; + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +static int _extension_const_string(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + string *str = va_arg(args, string *); + 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 (constant->module_number == module->module_number) { + _const_string(str, constant->name, &constant->value, indent TSRMLS_CC); + (*num_classes)++; + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +/* {{{ _extension_string */ +static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC) +{ + string_printf(str, "%sExtension [ ", indent); + if (module->type == MODULE_PERSISTENT) { + string_printf(str, "<persistent>"); + } + if (module->type == MODULE_TEMPORARY) { + string_printf(str, "<temporary>" ); + } + string_printf(str, " extension #%d %s version %s ] {\n", + module->module_number, module->name, + (module->version == NO_VERSION_YET) ? "<no_version>" : module->version); + + if (module->deps) { + const zend_module_dep* dep = module->deps; + + string_printf(str, "\n - Dependencies {\n"); + + while(dep->name) { + string_printf(str, "%s Dependency [ %s (", indent, dep->name); + + switch(dep->type) { + case MODULE_DEP_REQUIRED: + string_write(str, "Required", sizeof("Required") - 1); + break; + case MODULE_DEP_CONFLICTS: + string_write(str, "Conflicts", sizeof("Conflicts") - 1); + break; + case MODULE_DEP_OPTIONAL: + string_write(str, "Optional", sizeof("Optional") - 1); + break; + default: + string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */ + break; + } + + if (dep->rel) { + string_printf(str, " %s", dep->rel); + } + if (dep->version) { + string_printf(str, " %s", dep->version); + } + string_write(str, ") ]\n", sizeof(") ]\n") - 1); + dep++; + } + string_printf(str, "%s }\n", indent); + } + + { + string str_ini; + string_init(&str_ini); + zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number); + if (str_ini.len > 1) { + string_printf(str, "\n - INI {\n"); + string_append(str, &str_ini); + string_printf(str, "%s }\n", indent); + } + string_free(&str_ini); + } + + { + string str_constants; + int num_constants = 0; + + string_init(&str_constants); + zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants); + if (num_constants) { + string_printf(str, "\n - Constants [%d] {\n", num_constants); + string_append(str, &str_constants); + string_printf(str, "%s }\n", indent); + } + string_free(&str_constants); + } + + if (module->functions && module->functions->fname) { + zend_function *fptr; + const zend_function_entry *func = module->functions; + + string_printf(str, "\n - Functions {\n"); + + /* Is there a better way of doing this? */ + while (func->fname) { + int fname_len = strlen(func->fname); + char *lc_name = zend_str_tolower_dup(func->fname, fname_len); + + if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname); + func++; + efree(lc_name); + continue; + } + + _function_string(str, fptr, NULL, " " TSRMLS_CC); + efree(lc_name); + func++; + } + string_printf(str, "%s }\n", indent); + } + + { + string str_classes; + string sub_indent; + int num_classes = 0; + + string_init(&sub_indent); + string_printf(&sub_indent, "%s ", indent); + string_init(&str_classes); + zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) _extension_class_string, 4, &str_classes, sub_indent.string, module, &num_classes); + if (num_classes) { + string_printf(str, "\n - Classes [%d] {", num_classes); + string_append(str, &str_classes); + string_printf(str, "%s }\n", indent); + } + string_free(&str_classes); + string_free(&sub_indent); + } + + string_printf(str, "%s}\n", indent); +} +/* }}} */ + +static void _zend_extension_string(string *str, zend_extension *extension, char *indent TSRMLS_DC) /* {{{ */ +{ + string_printf(str, "%sZend Extension [ %s ", indent, extension->name); + + if (extension->version) { + string_printf(str, "%s ", extension->version); + } + if (extension->copyright) { + string_printf(str, "%s ", extension->copyright); + } + if (extension->author) { + string_printf(str, "by %s ", extension->author); + } + if (extension->URL) { + string_printf(str, "<%s> ", extension->URL); + } + + string_printf(str, "]\n"); +} +/* }}} */ + +/* {{{ _function_check_flag */ +static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) +{ + reflection_object *intern; + zend_function *mptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(mptr); + RETURN_BOOL(mptr->common.fn_flags & mask); +} +/* }}} */ + +/* {{{ zend_reflection_class_factory */ +PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC) +{ + reflection_object *intern; + zval *name; + + MAKE_STD_ZVAL(name); + ZVAL_STRINGL(name, ce->name, ce->name_length, 1); + reflection_instantiate(reflection_class_ptr, object TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + intern->ptr = ce; + intern->ref_type = REF_TYPE_OTHER; + intern->ce = ce; + reflection_update_property(object, "name", name); +} +/* }}} */ + +/* {{{ reflection_extension_factory */ +static void reflection_extension_factory(zval *object, const char *name_str TSRMLS_DC) +{ + reflection_object *intern; + zval *name; + int name_len = strlen(name_str); + char *lcname; + struct _zend_module_entry *module; + ALLOCA_FLAG(use_heap) + + lcname = do_alloca(name_len + 1, use_heap); + zend_str_tolower_copy(lcname, name_str, name_len); + if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) { + free_alloca(lcname, use_heap); + return; + } + free_alloca(lcname, use_heap); + + reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + MAKE_STD_ZVAL(name); + ZVAL_STRINGL(name, module->name, name_len, 1); + intern->ptr = module; + intern->ref_type = REF_TYPE_OTHER; + intern->ce = NULL; + reflection_update_property(object, "name", name); +} +/* }}} */ + +/* {{{ reflection_parameter_factory */ +static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC) +{ + reflection_object *intern; + parameter_reference *reference; + zval *name; + + if (closure_object) { + Z_ADDREF_P(closure_object); + } + MAKE_STD_ZVAL(name); + if (arg_info->name) { + ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1); + } else { + ZVAL_NULL(name); + } + reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + reference = (parameter_reference*) emalloc(sizeof(parameter_reference)); + reference->arg_info = arg_info; + reference->offset = offset; + reference->required = required; + reference->fptr = fptr; + intern->ptr = reference; + intern->ref_type = REF_TYPE_PARAMETER; + intern->ce = fptr->common.scope; + intern->obj = closure_object; + reflection_update_property(object, "name", name); +} +/* }}} */ + +/* {{{ reflection_function_factory */ +static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC) +{ + reflection_object *intern; + zval *name; + + if (closure_object) { + Z_ADDREF_P(closure_object); + } + MAKE_STD_ZVAL(name); + ZVAL_STRING(name, function->common.function_name, 1); + + reflection_instantiate(reflection_function_ptr, object TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + intern->ptr = function; + intern->ref_type = REF_TYPE_FUNCTION; + intern->ce = NULL; + intern->obj = closure_object; + reflection_update_property(object, "name", name); +} +/* }}} */ + +/* {{{ reflection_method_factory */ +static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC) +{ + reflection_object *intern; + zval *name; + zval *classname; + + if (closure_object) { + Z_ADDREF_P(closure_object); + } + MAKE_STD_ZVAL(name); + MAKE_STD_ZVAL(classname); + ZVAL_STRING(name, method->common.function_name, 1); + ZVAL_STRINGL(classname, method->common.scope->name, method->common.scope->name_length, 1); + reflection_instantiate(reflection_method_ptr, object TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + intern->ptr = method; + intern->ref_type = REF_TYPE_FUNCTION; + intern->ce = ce; + intern->obj = closure_object; + reflection_update_property(object, "name", name); + reflection_update_property(object, "class", classname); +} +/* }}} */ + +/* {{{ reflection_property_factory */ +static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object TSRMLS_DC) +{ + reflection_object *intern; + zval *name; + zval *classname; + property_reference *reference; + const char *class_name, *prop_name; + + zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name); + + if (!(prop->flags & ZEND_ACC_PRIVATE)) { + /* we have to search the class hierarchy for this (implicit) public or protected property */ + zend_class_entry *tmp_ce = ce, *store_ce = ce; + zend_property_info *tmp_info = NULL; + + while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) { + ce = tmp_ce; + tmp_ce = tmp_ce->parent; + } + + if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */ + prop = tmp_info; + } else { /* not found, use initial value */ + ce = store_ce; + } + } + + MAKE_STD_ZVAL(name); + MAKE_STD_ZVAL(classname); + ZVAL_STRING(name, prop_name, 1); + ZVAL_STRINGL(classname, prop->ce->name, prop->ce->name_length, 1); + + reflection_instantiate(reflection_property_ptr, object TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + reference = (property_reference*) emalloc(sizeof(property_reference)); + reference->ce = ce; + reference->prop = *prop; + intern->ptr = reference; + intern->ref_type = REF_TYPE_PROPERTY; + intern->ce = ce; + intern->ignore_visibility = 0; + reflection_update_property(object, "name", name); + reflection_update_property(object, "class", classname); +} +/* }}} */ + +/* {{{ _reflection_export */ +static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc) +{ + zval *reflector_ptr; + zval output, *output_ptr = &output; + zval *argument_ptr, *argument2_ptr; + zval *retval_ptr, **params[2]; + int result; + int return_output = 0; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval fname; + + if (ctor_argc == 1) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &argument_ptr, &return_output) == FAILURE) { + return; + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) { + return; + } + } + + INIT_PZVAL(&output); + + /* Create object */ + MAKE_STD_ZVAL(reflector_ptr); + if (object_and_properties_init(reflector_ptr, ce_ptr, NULL) == FAILURE) { + _DO_THROW("Could not create reflector"); + } + + /* Call __construct() */ + params[0] = &argument_ptr; + params[1] = &argument2_ptr; + + fci.size = sizeof(fci); + fci.function_table = NULL; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = reflector_ptr; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = ctor_argc; + fci.params = params; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = ce_ptr->constructor; + fcc.calling_scope = ce_ptr; + fcc.called_scope = Z_OBJCE_P(reflector_ptr); + fcc.object_ptr = reflector_ptr; + + result = zend_call_function(&fci, &fcc TSRMLS_CC); + + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + + if (EG(exception)) { + zval_ptr_dtor(&reflector_ptr); + return; + } + if (result == FAILURE) { + zval_ptr_dtor(&reflector_ptr); + _DO_THROW("Could not create reflector"); + } + + /* Call static reflection::export */ + ZVAL_BOOL(&output, return_output); + params[0] = &reflector_ptr; + params[1] = &output_ptr; + + ZVAL_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 0); + fci.function_table = &reflection_ptr->function_table; + fci.function_name = &fname; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = 2; + fci.params = params; + fci.no_separation = 1; + + result = zend_call_function(&fci, NULL TSRMLS_CC); + + if (result == FAILURE && EG(exception) == NULL) { + zval_ptr_dtor(&reflector_ptr); + zval_ptr_dtor(&retval_ptr); + _DO_THROW("Could not execute reflection::export()"); + } + + if (return_output) { + COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); + } else { + zval_ptr_dtor(&retval_ptr); + } + + /* Destruct reflector which is no longer needed */ + zval_ptr_dtor(&reflector_ptr); +} +/* }}} */ + +/* {{{ _reflection_param_get_default_param */ +static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAMETERS) +{ + reflection_object *intern; + parameter_reference *param; + + intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); + if (intern == NULL || intern->ptr == NULL) { + if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) { + return NULL; + } + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object"); + } + + param = intern->ptr; + if (param->fptr->type != ZEND_USER_FUNCTION) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions"); + return NULL; + } + + return param; +} +/* }}} */ + +/* {{{ _reflection_param_get_default_precv */ +static zend_op *_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAMETERS, parameter_reference *param) +{ + zend_op *precv; + + if (param == NULL) { + return NULL; + } + + precv = _get_recv_op((zend_op_array*)param->fptr, param->offset); + if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error: Failed to retrieve the default value"); + return NULL; + } + + return precv; +} +/* }}} */ + +/* {{{ Preventing __clone from being called */ +ZEND_METHOD(reflection, __clone) +{ + /* Should never be executable */ + _DO_THROW("Cannot clone object using __clone()"); +} +/* }}} */ + +/* {{{ proto public static mixed Reflection::export(Reflector r [, bool return]) + Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ +ZEND_METHOD(reflection, export) +{ + zval *object, fname, *retval_ptr; + int result; + zend_bool return_output = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &object, reflector_ptr, &return_output) == FAILURE) { + return; + } + + /* Invoke the __toString() method */ + ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1); + result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC); + zval_dtor(&fname); + + if (result == FAILURE) { + _DO_THROW("Invocation of method __toString() failed"); + /* Returns from this function */ + } + + if (!retval_ptr) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name); + RETURN_FALSE; + } + + if (return_output) { + COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); + } else { + /* No need for _r variant, return of __toString should always be a string */ + zend_print_zval(retval_ptr, 0); + zend_printf("\n"); + zval_ptr_dtor(&retval_ptr); + } +} +/* }}} */ + +/* {{{ proto public static array Reflection::getModifierNames(int modifiers) + Returns an array of modifier names */ +ZEND_METHOD(reflection, getModifierNames) +{ + long modifiers; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &modifiers) == FAILURE) { + return; + } + + array_init(return_value); + + if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1, 1); + } + if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) { + add_next_index_stringl(return_value, "final", sizeof("final")-1, 1); + } + if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) { + add_next_index_stringl(return_value, "public", sizeof("public")-1, 1); + } + + /* These are mutually exclusive */ + switch (modifiers & ZEND_ACC_PPP_MASK) { + case ZEND_ACC_PUBLIC: + add_next_index_stringl(return_value, "public", sizeof("public")-1, 1); + break; + case ZEND_ACC_PRIVATE: + add_next_index_stringl(return_value, "private", sizeof("private")-1, 1); + break; + case ZEND_ACC_PROTECTED: + add_next_index_stringl(return_value, "protected", sizeof("protected")-1, 1); + break; + } + + if (modifiers & ZEND_ACC_STATIC) { + add_next_index_stringl(return_value, "static", sizeof("static")-1, 1); + } +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return]) + Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ +ZEND_METHOD(reflection_function, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionFunction::__construct(string name) + Constructor. Throws an Exception in case the given function does not exist */ +ZEND_METHOD(reflection_function, __construct) +{ + zval *name; + zval *object; + zval *closure = NULL; + char *lcname; + reflection_object *intern; + zend_function *fptr; + char *name_str; + int name_len; + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "O", &closure, zend_ce_closure) == SUCCESS) { + fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC); + Z_ADDREF_P(closure); + } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) { + char *nsname; + + lcname = zend_str_tolower_dup(name_str, name_len); + + /* Ignore leading "\" */ + nsname = lcname; + if (lcname[0] == '\\') { + nsname = &lcname[1]; + name_len--; + } + + if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) { + efree(lcname); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Function %s() does not exist", name_str); + return; + } + efree(lcname); + } else { + return; + } + + MAKE_STD_ZVAL(name); + ZVAL_STRING(name, fptr->common.function_name, 1); + reflection_update_property(object, "name", name); + intern->ptr = fptr; + intern->ref_type = REF_TYPE_FUNCTION; + intern->obj = closure; + intern->ce = NULL; +} +/* }}} */ + +/* {{{ proto public string ReflectionFunction::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_function, __toString) +{ + reflection_object *intern; + zend_function *fptr; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + string_init(&str); + _function_string(&str, fptr, intern->ce, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public string ReflectionFunction::getName() + Returns this function's name */ +ZEND_METHOD(reflection_function, getName) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::isClosure() + Returns whether this is a closure */ +ZEND_METHOD(reflection_function, isClosure) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::getClosureThis() + Returns this pointer bound to closure */ +ZEND_METHOD(reflection_function, getClosureThis) +{ + reflection_object *intern; + zend_function *fptr; + zval* closure_this; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + if (intern->obj) { + closure_this = zend_get_closure_this_ptr(intern->obj TSRMLS_CC); + if (closure_this) { + RETURN_ZVAL(closure_this, 1, 0); + } + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass ReflectionFunction::getClosureScopeClass() + Returns the scope associated to the closure */ +ZEND_METHOD(reflection_function, getClosureScopeClass) +{ + reflection_object *intern; + zend_function *fptr; + const zend_function *closure_func; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + if (intern->obj) { + closure_func = zend_get_closure_method_def(intern->obj TSRMLS_CC); + if (closure_func && closure_func->common.scope) { + zend_reflection_class_factory(closure_func->common.scope, return_value TSRMLS_CC); + } + } +} +/* }}} */ + +/* {{{ proto public mixed ReflectionFunction::getClosure() + Returns a dynamically created closure for the function */ +ZEND_METHOD(reflection_function, getClosure) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + + zend_create_closure(return_value, fptr, NULL, NULL TSRMLS_CC); +} +/* }}} */ + + +/* {{{ proto public bool ReflectionFunction::isInternal() + Returns whether this is an internal function */ +ZEND_METHOD(reflection_function, isInternal) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::isUserDefined() + Returns whether this is an user-defined function */ +ZEND_METHOD(reflection_function, isUserDefined) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::isDisabled() + Returns whether this function has been disabled or not */ +ZEND_METHOD(reflection_function, isDisabled) +{ + reflection_object *intern; + zend_function *fptr; + + METHOD_NOTSTATIC(reflection_function_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function); +} +/* }}} */ + +/* {{{ proto public string ReflectionFunction::getFileName() + Returns the filename of the file this function was declared in */ +ZEND_METHOD(reflection_function, getFileName) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + if (fptr->type == ZEND_USER_FUNCTION) { + RETURN_STRING(fptr->op_array.filename, 1); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public int ReflectionFunction::getStartLine() + Returns the line this function's declaration starts at */ +ZEND_METHOD(reflection_function, getStartLine) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + if (fptr->type == ZEND_USER_FUNCTION) { + RETURN_LONG(fptr->op_array.line_start); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public int ReflectionFunction::getEndLine() + Returns the line this function's declaration ends at */ +ZEND_METHOD(reflection_function, getEndLine) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + if (fptr->type == ZEND_USER_FUNCTION) { + RETURN_LONG(fptr->op_array.line_end); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public string ReflectionFunction::getDocComment() + Returns the doc comment for this function */ +ZEND_METHOD(reflection_function, getDocComment) +{ + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) { + RETURN_STRINGL(fptr->op_array.doc_comment, fptr->op_array.doc_comment_len, 1); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public array ReflectionFunction::getStaticVariables() + Returns an associative array containing this function's static variables and their values */ +ZEND_METHOD(reflection_function, getStaticVariables) +{ + zval *tmp_copy; + reflection_object *intern; + zend_function *fptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(fptr); + + /* Return an empty array in case no static variables exist */ + array_init(return_value); + if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) { + zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant_inline_change, fptr->common.scope TSRMLS_CC); + zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *)); + } +} +/* }}} */ + +/* {{{ proto public mixed ReflectionFunction::invoke([mixed* args]) + Invokes the function */ +ZEND_METHOD(reflection_function, invoke) +{ + zval *retval_ptr; + zval ***params = NULL; + int result, num_args = 0; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + reflection_object *intern; + zend_function *fptr; + + METHOD_NOTSTATIC(reflection_function_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", ¶ms, &num_args) == FAILURE) { + return; + } + + fci.size = sizeof(fci); + fci.function_table = NULL; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = num_args; + fci.params = params; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = fptr; + fcc.calling_scope = EG(scope); + fcc.called_scope = NULL; + fcc.object_ptr = NULL; + + result = zend_call_function(&fci, &fcc TSRMLS_CC); + + if (num_args) { + efree(params); + } + + if (result == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Invocation of function %s() failed", fptr->common.function_name); + return; + } + + if (retval_ptr) { + COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); + } +} +/* }}} */ + +static int _zval_array_to_c_array(zval **arg, zval ****params TSRMLS_DC) /* {{{ */ +{ + *(*params)++ = arg; + return ZEND_HASH_APPLY_KEEP; +} /* }}} */ + +/* {{{ proto public mixed ReflectionFunction::invokeArgs(array args) + Invokes the function and pass its arguments as array. */ +ZEND_METHOD(reflection_function, invokeArgs) +{ + zval *retval_ptr; + zval ***params; + int result; + int argc; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + reflection_object *intern; + zend_function *fptr; + zval *param_array; + + METHOD_NOTSTATIC(reflection_function_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", ¶m_array) == FAILURE) { + return; + } + + argc = zend_hash_num_elements(Z_ARRVAL_P(param_array)); + + params = safe_emalloc(sizeof(zval **), argc, 0); + zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC); + params -= argc; + + fci.size = sizeof(fci); + fci.function_table = NULL; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = argc; + fci.params = params; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = fptr; + fcc.calling_scope = EG(scope); + fcc.called_scope = NULL; + fcc.object_ptr = NULL; + + result = zend_call_function(&fci, &fcc TSRMLS_CC); + + efree(params); + + if (result == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Invocation of function %s() failed", fptr->common.function_name); + return; + } + + if (retval_ptr) { + COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::returnsReference() + Gets whether this function returns a reference */ +ZEND_METHOD(reflection_function, returnsReference) +{ + reflection_object *intern; + zend_function *fptr; + + METHOD_NOTSTATIC(reflection_function_abstract_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::getNumberOfParameters() + Gets the number of required parameters */ +ZEND_METHOD(reflection_function, getNumberOfParameters) +{ + reflection_object *intern; + zend_function *fptr; + + METHOD_NOTSTATIC(reflection_function_abstract_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + RETURN_LONG(fptr->common.num_args); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::getNumberOfRequiredParameters() + Gets the number of required parameters */ +ZEND_METHOD(reflection_function, getNumberOfRequiredParameters) +{ + reflection_object *intern; + zend_function *fptr; + + METHOD_NOTSTATIC(reflection_function_abstract_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + RETURN_LONG(fptr->common.required_num_args); +} +/* }}} */ + +/* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters() + Returns an array of parameter objects for this function */ +ZEND_METHOD(reflection_function, getParameters) +{ + reflection_object *intern; + zend_function *fptr; + zend_uint i; + struct _zend_arg_info *arg_info; + + METHOD_NOTSTATIC(reflection_function_abstract_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + arg_info= fptr->common.arg_info; + + array_init(return_value); + for (i = 0; i < fptr->common.num_args; i++) { + zval *parameter; + + ALLOC_ZVAL(parameter); + reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), intern->obj, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC); + add_next_index_zval(return_value, parameter); + + arg_info++; + } +} +/* }}} */ + +/* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension() + Returns NULL or the extension the function belongs to */ +ZEND_METHOD(reflection_function, getExtension) +{ + reflection_object *intern; + zend_function *fptr; + zend_internal_function *internal; + + METHOD_NOTSTATIC(reflection_function_abstract_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + if (fptr->type != ZEND_INTERNAL_FUNCTION) { + RETURN_NULL(); + } + + internal = (zend_internal_function *)fptr; + if (internal->module) { + reflection_extension_factory(return_value, internal->module->name TSRMLS_CC); + } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ proto public string|false ReflectionFunction::getExtensionName() + Returns false or the name of the extension the function belongs to */ +ZEND_METHOD(reflection_function, getExtensionName) +{ + reflection_object *intern; + zend_function *fptr; + zend_internal_function *internal; + + METHOD_NOTSTATIC(reflection_function_abstract_ptr); + GET_REFLECTION_OBJECT_PTR(fptr); + + if (fptr->type != ZEND_INTERNAL_FUNCTION) { + RETURN_FALSE; + } + + internal = (zend_internal_function *)fptr; + if (internal->module) { + RETURN_STRING(internal->module->name, 1); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException + Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ +ZEND_METHOD(reflection_parameter, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2); +} +/* }}} */ + +/* {{{ proto public void ReflectionParameter::__construct(mixed function, mixed parameter) + Constructor. Throws an Exception in case the given method does not exist */ +ZEND_METHOD(reflection_parameter, __construct) +{ + parameter_reference *ref; + zval *reference, **parameter; + zval *object; + zval *name; + reflection_object *intern; + zend_function *fptr; + struct _zend_arg_info *arg_info; + int position; + zend_class_entry *ce = NULL; + zend_bool is_closure = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, ¶meter) == FAILURE) { + return; + } + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + + /* First, find the function */ + switch (Z_TYPE_P(reference)) { + case IS_STRING: { + unsigned int lcname_len; + char *lcname; + + lcname_len = Z_STRLEN_P(reference); + lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len); + if (zend_hash_find(EG(function_table), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) { + efree(lcname); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Function %s() does not exist", Z_STRVAL_P(reference)); + return; + } + efree(lcname); + } + ce = fptr->common.scope; + break; + + case IS_ARRAY: { + zval **classref; + zval **method; + zend_class_entry **pce; + unsigned int lcname_len; + char *lcname; + + if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE) + || (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE)) + { + _DO_THROW("Expected array($object, $method) or array($classname, $method)"); + /* returns out of this function */ + } + + if (Z_TYPE_PP(classref) == IS_OBJECT) { + ce = Z_OBJCE_PP(classref); + } else { + convert_to_string_ex(classref); + if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not exist", Z_STRVAL_PP(classref)); + return; + } + ce = *pce; + } + + convert_to_string_ex(method); + lcname_len = Z_STRLEN_PP(method); + lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), lcname_len); + if (ce == zend_ce_closure && Z_TYPE_PP(classref) == IS_OBJECT + && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && (fptr = zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL) + { + /* nothing to do. don't set is_closure since is the invoke handler, +- not the closure itself */ + } else if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) { + efree(lcname); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Method %s::%s() does not exist", ce->name, Z_STRVAL_PP(method)); + return; + } + efree(lcname); + } + break; + + case IS_OBJECT: { + ce = Z_OBJCE_P(reference); + + if (instanceof_function(ce, zend_ce_closure TSRMLS_CC)) { + fptr = (zend_function *)zend_get_closure_method_def(reference TSRMLS_CC); + Z_ADDREF_P(reference); + is_closure = 1; + } else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Method %s::%s() does not exist", ce->name, ZEND_INVOKE_FUNC_NAME); + return; + } + } + break; + + 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 */ + } + + /* Now, search for the parameter */ + arg_info = fptr->common.arg_info; + if (Z_TYPE_PP(parameter) == IS_LONG) { + position= Z_LVAL_PP(parameter); + if (position < 0 || (zend_uint)position >= fptr->common.num_args) { + if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) { + if (fptr->type != ZEND_OVERLOADED_FUNCTION) { + efree((char*)fptr->common.function_name); + } + efree(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 */ + } + } else { + zend_uint i; + + position= -1; + convert_to_string_ex(parameter); + for (i = 0; i < fptr->common.num_args; i++) { + if (arg_info[i].name && strcmp(arg_info[i].name, Z_STRVAL_PP(parameter)) == 0) { + position= i; + break; + } + } + if (position == -1) { + if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) { + if (fptr->type != ZEND_OVERLOADED_FUNCTION) { + efree((char*)fptr->common.function_name); + } + efree(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 */ + } + } + + MAKE_STD_ZVAL(name); + if (arg_info[position].name) { + ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1); + } else { + ZVAL_NULL(name); + } + reflection_update_property(object, "name", name); + + ref = (parameter_reference*) emalloc(sizeof(parameter_reference)); + ref->arg_info = &arg_info[position]; + ref->offset = (zend_uint)position; + ref->required = fptr->common.required_num_args; + ref->fptr = fptr; + /* TODO: copy fptr */ + intern->ptr = ref; + intern->ref_type = REF_TYPE_PARAMETER; + intern->ce = ce; + if (reference && is_closure) { + intern->obj = reference; + } +} +/* }}} */ + +/* {{{ proto public string ReflectionParameter::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_parameter, __toString) +{ + reflection_object *intern; + parameter_reference *param; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + string_init(&str); + _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public string ReflectionParameter::getName() + Returns this parameters's name */ +ZEND_METHOD(reflection_parameter, getName) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction() + Returns the ReflectionFunction for the function of this parameter */ +ZEND_METHOD(reflection_parameter, getDeclaringFunction) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + if (!param->fptr->common.scope) { + reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC); + } else { + reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass() + Returns in which class this parameter is defined (not the typehint of the parameter) */ +ZEND_METHOD(reflection_parameter, getDeclaringClass) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + if (param->fptr->common.scope) { + zend_reflection_class_factory(param->fptr->common.scope, return_value TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass() + Returns this parameters's class hint or NULL if there is none */ +ZEND_METHOD(reflection_parameter, getClass) +{ + reflection_object *intern; + parameter_reference *param; + zend_class_entry **pce, *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + if (param->arg_info->class_name) { + /* Class name is stored as a string, we might also get "self" or "parent" + * - For "self", simply use the function scope. If scope is NULL then + * the function is global and thus self does not make any sense + * + * - For "parent", use the function scope's parent. If scope is NULL then + * the function is global and thus parent does not make any sense. + * If the parent is NULL then the class does not extend anything and + * thus parent does not make any sense, either. + * + * TODO: Think about moving these checks to the compiler or some sort of + * lint-mode. + */ + if (0 == zend_binary_strcasecmp(param->arg_info->class_name, param->arg_info->class_name_len, "self", sizeof("self")- 1)) { + ce = param->fptr->common.scope; + if (!ce) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter uses 'self' as type hint but function is not a class member!"); + return; + } + pce= &ce; + } else if (0 == zend_binary_strcasecmp(param->arg_info->class_name, param->arg_info->class_name_len, "parent", sizeof("parent")- 1)) { + ce = param->fptr->common.scope; + if (!ce) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter uses 'parent' as type hint but function is not a class member!"); + return; + } + if (!ce->parent) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter uses 'parent' as type hint although class does not have a parent!"); + return; + } + pce= &ce->parent; + } else if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not exist", param->arg_info->class_name); + return; + } + zend_reflection_class_factory(*pce, return_value TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::isArray() + Returns whether parameter MUST be an array */ +ZEND_METHOD(reflection_parameter, isArray) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->arg_info->type_hint == IS_ARRAY); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::isCallable() + Returns whether parameter MUST be callable */ +ZEND_METHOD(reflection_parameter, isCallable) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->arg_info->type_hint == IS_CALLABLE); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::allowsNull() + Returns whether NULL is allowed as this parameters's value */ +ZEND_METHOD(reflection_parameter, allowsNull) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->arg_info->allow_null); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::isPassedByReference() + Returns whether this parameters is passed to by reference */ +ZEND_METHOD(reflection_parameter, isPassedByReference) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->arg_info->pass_by_reference); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::canBePassedByValue() + Returns whether this parameter can be passed by value */ +ZEND_METHOD(reflection_parameter, canBePassedByValue) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + /* true if it's ZEND_SEND_BY_VAL or ZEND_SEND_PREFER_REF */ + RETVAL_BOOL(param->arg_info->pass_by_reference != ZEND_SEND_BY_REF); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::getPosition() + Returns whether this parameter is an optional parameter */ +ZEND_METHOD(reflection_parameter, getPosition) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_LONG(param->offset); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::isOptional() + Returns whether this parameter is an optional parameter */ +ZEND_METHOD(reflection_parameter, isOptional) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->offset >= param->required); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::isDefaultValueAvailable() + Returns whether the default value of this parameter is available */ +ZEND_METHOD(reflection_parameter, isDefaultValueAvailable) +{ + reflection_object *intern; + parameter_reference *param; + zend_op *precv; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + if (param->fptr->type != ZEND_USER_FUNCTION) + { + RETURN_FALSE; + } + + precv = _get_recv_op((zend_op_array*)param->fptr, param->offset); + if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::getDefaultValue() + Returns the default value of this parameter or throws an exception */ +ZEND_METHOD(reflection_parameter, getDefaultValue) +{ + parameter_reference *param; + zend_op *precv; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (!param) { + return; + } + + precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param); + if (!precv) { + return; + } + + *return_value = *precv->op2.zv; + INIT_PZVAL(return_value); + if ((Z_TYPE_P(return_value) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT + && (Z_TYPE_P(return_value) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT_ARRAY) { + zval_copy_ctor(return_value); + } + zval_update_constant_ex(&return_value, (void*)0, param->fptr->common.scope TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionParameter::isDefaultValueConstant() + Returns whether the default value of this parameter is constant */ +ZEND_METHOD(reflection_parameter, isDefaultValueConstant) +{ + zend_op *precv; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (!param) { + RETURN_FALSE; + } + + precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param); + if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + RETURN_TRUE; + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public mixed ReflectionParameter::getDefaultValueConstantName() + Returns the default value's constant name if default value is constant or null */ +ZEND_METHOD(reflection_parameter, getDefaultValueConstantName) +{ + zend_op *precv; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (!param) { + return; + } + + precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param); + if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + RETURN_STRINGL(Z_STRVAL_P(precv->op2.zv), Z_STRLEN_P(precv->op2.zv), 1); + } +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionMethod::export(mixed class, 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_method, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2); +} +/* }}} */ + +/* {{{ proto public void ReflectionMethod::__construct(mixed class_or_method [, string name]) + Constructor. Throws an Exception in case the given method does not exist */ +ZEND_METHOD(reflection_method, __construct) +{ + zval *name, *classname; + zval *object, *orig_obj; + reflection_object *intern; + char *lcname; + zend_class_entry **pce; + zend_class_entry *ce; + zend_function *mptr; + char *name_str, *tmp; + int name_len, tmp_len; + zval ztmp; + + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) { + return; + } + if ((tmp = strstr(name_str, "::")) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Invalid method name %s", name_str); + return; + } + classname = &ztmp; + tmp_len = tmp - name_str; + ZVAL_STRINGL(classname, name_str, tmp_len, 1); + name_len = name_len - (tmp_len + 2); + name_str = tmp + 2; + orig_obj = NULL; + } else if (Z_TYPE_P(classname) == IS_OBJECT) { + orig_obj = classname; + } else { + orig_obj = NULL; + } + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + + /* Find the class entry */ + switch (Z_TYPE_P(classname)) { + case IS_STRING: + if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not exist", Z_STRVAL_P(classname)); + if (classname == &ztmp) { + zval_dtor(&ztmp); + } + return; + } + ce = *pce; + break; + + case IS_OBJECT: + ce = Z_OBJCE_P(classname); + break; + + default: + if (classname == &ztmp) { + zval_dtor(&ztmp); + } + _DO_THROW("The parameter class is expected to be either a string or an object"); + /* returns out of this function */ + } + + if (classname == &ztmp) { + zval_dtor(&ztmp); + } + + lcname = zend_str_tolower_dup(name_str, name_len); + + if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && (mptr = zend_get_closure_invoke_method(orig_obj TSRMLS_CC)) != NULL) + { + /* do nothing, mptr already set */ + } else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) { + efree(lcname); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Method %s::%s() does not exist", ce->name, name_str); + return; + } + efree(lcname); + + MAKE_STD_ZVAL(classname); + ZVAL_STRINGL(classname, mptr->common.scope->name, mptr->common.scope->name_length, 1); + + reflection_update_property(object, "class", classname); + + MAKE_STD_ZVAL(name); + ZVAL_STRING(name, mptr->common.function_name, 1); + reflection_update_property(object, "name", name); + intern->ptr = mptr; + intern->ref_type = REF_TYPE_FUNCTION; + intern->ce = ce; +} +/* }}} */ + +/* {{{ proto public string ReflectionMethod::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_method, __toString) +{ + reflection_object *intern; + zend_function *mptr; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(mptr); + string_init(&str); + _function_string(&str, mptr, intern->ce, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public mixed ReflectionMethod::getClosure([mixed object]) + Invokes the function */ +ZEND_METHOD(reflection_method, getClosure) +{ + reflection_object *intern; + zval *obj; + zend_function *mptr; + + METHOD_NOTSTATIC(reflection_method_ptr); + GET_REFLECTION_OBJECT_PTR(mptr); + + if (mptr->common.fn_flags & ZEND_ACC_STATIC) { + zend_create_closure(return_value, mptr, mptr->common.scope, NULL TSRMLS_CC); + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { + return; + } + + if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope TSRMLS_CC)) { + _DO_THROW("Given object is not an instance of the class this method was declared in"); + /* Returns from this function */ + } + + /* This is an original closure object and __invoke is to be called. */ + if (Z_OBJCE_P(obj) == zend_ce_closure && mptr->type == ZEND_INTERNAL_FUNCTION && + (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) + { + RETURN_ZVAL(obj, 1, 0); + } else { + zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC); + } + } +} +/* }}} */ + +/* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args) + Invokes the method. */ +ZEND_METHOD(reflection_method, invoke) +{ + zval *retval_ptr; + zval ***params = NULL; + zval *object_ptr; + reflection_object *intern; + zend_function *mptr; + int result, num_args = 0; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zend_class_entry *obj_ce; + + METHOD_NOTSTATIC(reflection_method_ptr); + + GET_REFLECTION_OBJECT_PTR(mptr); + + if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) + || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) + && intern->ignore_visibility == 0) + { + if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Trying to invoke abstract method %s::%s()", + mptr->common.scope->name, mptr->common.function_name); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Trying to invoke %s method %s::%s() from scope %s", + mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private", + mptr->common.scope->name, mptr->common.function_name, + Z_OBJCE_P(getThis())->name); + } + return; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", ¶ms, &num_args) == FAILURE) { + return; + } + + /* In case this is a static method, we should'nt pass an object_ptr + * (which is used as calling context aka $this). We can thus ignore the + * first parameter. + * + * Else, we verify that the given object is an instance of the class. + */ + if (mptr->common.fn_flags & ZEND_ACC_STATIC) { + object_ptr = NULL; + obj_ce = mptr->common.scope; + } else { + if (Z_TYPE_PP(params[0]) != IS_OBJECT) { + efree(params); + _DO_THROW("Non-object passed to Invoke()"); + /* Returns from this function */ + } + + obj_ce = Z_OBJCE_PP(params[0]); + + if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) { + if (params) { + efree(params); + } + _DO_THROW("Given object is not an instance of the class this method was declared in"); + /* Returns from this function */ + } + + object_ptr = *params[0]; + } + + fci.size = sizeof(fci); + fci.function_table = NULL; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = object_ptr; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = num_args - 1; + fci.params = params + 1; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = mptr; + fcc.calling_scope = obj_ce; + fcc.called_scope = intern->ce; + fcc.object_ptr = object_ptr; + + result = zend_call_function(&fci, &fcc TSRMLS_CC); + + if (params) { + efree(params); + } + + if (result == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name); + return; + } + + if (retval_ptr) { + COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); + } +} +/* }}} */ + +/* {{{ proto public mixed ReflectionMethod::invokeArgs(mixed object, array args) + Invokes the function and pass its arguments as array. */ +ZEND_METHOD(reflection_method, invokeArgs) +{ + zval *retval_ptr; + zval ***params; + zval *object; + reflection_object *intern; + zend_function *mptr; + int argc; + int result; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zend_class_entry *obj_ce; + zval *param_array; + + METHOD_NOTSTATIC(reflection_method_ptr); + + GET_REFLECTION_OBJECT_PTR(mptr); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a", &object, ¶m_array) == FAILURE) { + return; + } + + if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) + || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) + && intern->ignore_visibility == 0) + { + if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Trying to invoke abstract method %s::%s()", + mptr->common.scope->name, mptr->common.function_name); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Trying to invoke %s method %s::%s() from scope %s", + mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private", + mptr->common.scope->name, mptr->common.function_name, + Z_OBJCE_P(getThis())->name); + } + return; + } + + argc = zend_hash_num_elements(Z_ARRVAL_P(param_array)); + + params = safe_emalloc(sizeof(zval **), argc, 0); + zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC); + params -= argc; + + /* In case this is a static method, we should'nt pass an object_ptr + * (which is used as calling context aka $this). We can thus ignore the + * first parameter. + * + * Else, we verify that the given object is an instance of the class. + */ + if (mptr->common.fn_flags & ZEND_ACC_STATIC) { + object = NULL; + obj_ce = mptr->common.scope; + } else { + if (!object) { + efree(params); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Trying to invoke non static method %s::%s() without an object", + mptr->common.scope->name, mptr->common.function_name); + return; + } + + obj_ce = Z_OBJCE_P(object); + + if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) { + efree(params); + _DO_THROW("Given object is not an instance of the class this method was declared in"); + /* Returns from this function */ + } + } + + fci.size = sizeof(fci); + fci.function_table = NULL; + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = object; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = argc; + fci.params = params; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = mptr; + fcc.calling_scope = obj_ce; + fcc.called_scope = intern->ce; + fcc.object_ptr = object; + + /* + * Copy the zend_function when calling via handler (e.g. Closure::__invoke()) + */ + if (mptr->type == ZEND_INTERNAL_FUNCTION && + (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0) { + fcc.function_handler = _copy_function(mptr TSRMLS_CC); + } + + result = zend_call_function(&fci, &fcc TSRMLS_CC); + + efree(params); + + if (result == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name); + return; + } + + if (retval_ptr) { + COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isFinal() + Returns whether this method is final */ +ZEND_METHOD(reflection_method, isFinal) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isAbstract() + Returns whether this method is abstract */ +ZEND_METHOD(reflection_method, isAbstract) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isPublic() + Returns whether this method is public */ +ZEND_METHOD(reflection_method, isPublic) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isPrivate() + Returns whether this method is private */ +ZEND_METHOD(reflection_method, isPrivate) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isProtected() + Returns whether this method is protected */ +ZEND_METHOD(reflection_method, isProtected) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isStatic() + Returns whether this method is static */ +ZEND_METHOD(reflection_method, isStatic) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::isDeprecated() + Returns whether this function is deprecated */ +ZEND_METHOD(reflection_function, isDeprecated) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED); +} +/* }}} */ + +/* {{{ proto public bool ReflectionFunction::inNamespace() + Returns whether this function is defined in namespace */ +ZEND_METHOD(reflection_function, inNamespace) +{ + zval **name; + const char *backslash; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) { + RETURN_FALSE; + } + if (Z_TYPE_PP(name) == IS_STRING + && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name))) + && backslash > Z_STRVAL_PP(name)) + { + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public string ReflectionFunction::getNamespaceName() + Returns the name of namespace where this function is defined */ +ZEND_METHOD(reflection_function, getNamespaceName) +{ + zval **name; + const char *backslash; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) { + RETURN_FALSE; + } + if (Z_TYPE_PP(name) == IS_STRING + && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name))) + && backslash > Z_STRVAL_PP(name)) + { + RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1); + } + RETURN_EMPTY_STRING(); +} +/* }}} */ + +/* {{{ proto public string ReflectionFunction::getShortName() + Returns the short name of the function (without namespace part) */ +ZEND_METHOD(reflection_function, getShortName) +{ + zval **name; + const char *backslash; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) { + RETURN_FALSE; + } + if (Z_TYPE_PP(name) == IS_STRING + && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name))) + && backslash > Z_STRVAL_PP(name)) + { + RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1); + } + RETURN_ZVAL(*name, 1, 0); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isConstructor() + Returns whether this method is the constructor */ +ZEND_METHOD(reflection_method, isConstructor) +{ + reflection_object *intern; + zend_function *mptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(mptr); + /* we need to check if the ctor is the ctor of the class level we we + * looking at since we might be looking at an inherited old style ctor + * defined in base class. */ + RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope); +} +/* }}} */ + +/* {{{ proto public bool ReflectionMethod::isDestructor() + Returns whether this method is static */ +ZEND_METHOD(reflection_method, isDestructor) +{ + reflection_object *intern; + zend_function *mptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(mptr); + RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR); +} +/* }}} */ + +/* {{{ proto public int ReflectionMethod::getModifiers() + Returns a bitfield of the access modifiers for this method */ +ZEND_METHOD(reflection_method, getModifiers) +{ + reflection_object *intern; + zend_function *mptr; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(mptr); + + RETURN_LONG(mptr->common.fn_flags); +} +/* }}} */ + +/* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass() + Get the declaring class */ +ZEND_METHOD(reflection_method, getDeclaringClass) +{ + reflection_object *intern; + zend_function *mptr; + + METHOD_NOTSTATIC(reflection_method_ptr); + GET_REFLECTION_OBJECT_PTR(mptr); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + zend_reflection_class_factory(mptr->common.scope, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public ReflectionClass ReflectionMethod::getPrototype() + Get the prototype */ +ZEND_METHOD(reflection_method, getPrototype) +{ + reflection_object *intern; + zend_function *mptr; + + METHOD_NOTSTATIC(reflection_method_ptr); + GET_REFLECTION_OBJECT_PTR(mptr); + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + if (!mptr->common.prototype) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Method %s::%s does not have a prototype", intern->ce->name, mptr->common.function_name); + return; + } + + reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public void ReflectionMethod::setAccessible(bool visible) + Sets whether non-public methods can be invoked */ +ZEND_METHOD(reflection_method, setAccessible) +{ + reflection_object *intern; + zend_bool visible; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) { + return; + } + + intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); + + if (intern == NULL) { + return; + } + + intern->ignore_visibility = visible; +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException + Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ +ZEND_METHOD(reflection_class, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1); +} +/* }}} */ + +/* {{{ reflection_class_object_ctor */ +static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object) +{ + zval *argument; + zval *object; + zval *classname; + reflection_object *intern; + zend_class_entry **ce; + + if (is_object) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &argument) == FAILURE) { + return; + } + } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &argument) == FAILURE) { + return; + } + } + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + + if (Z_TYPE_P(argument) == IS_OBJECT) { + MAKE_STD_ZVAL(classname); + ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1); + reflection_update_property(object, "name", classname); + intern->ptr = Z_OBJCE_P(argument); + if (is_object) { + intern->obj = argument; + zval_add_ref(&argument); + } + } else { + convert_to_string_ex(&argument); + if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) { + if (!EG(exception)) { + zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument)); + } + return; + } + + MAKE_STD_ZVAL(classname); + ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1); + reflection_update_property(object, "name", classname); + + intern->ptr = *ce; + } + intern->ref_type = REF_TYPE_OTHER; +} +/* }}} */ + +/* {{{ proto public void ReflectionClass::__construct(mixed argument) throws ReflectionException + Constructor. Takes a string or an instance as an argument */ +ZEND_METHOD(reflection_class, __construct) +{ + reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} +/* }}} */ + +/* {{{ add_class_vars */ +static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC) +{ + HashPosition pos; + zend_property_info *prop_info; + zval *prop, *prop_copy; + char *key; + uint key_len; + ulong num_index; + + zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS) { + zend_hash_get_current_key_ex(&ce->properties_info, &key, &key_len, &num_index, 0, &pos); + zend_hash_move_forward_ex(&ce->properties_info, &pos); + if (((prop_info->flags & ZEND_ACC_SHADOW) && + prop_info->ce != ce) || + ((prop_info->flags & ZEND_ACC_PROTECTED) && + !zend_check_protected(prop_info->ce, ce)) || + ((prop_info->flags & ZEND_ACC_PRIVATE) && + prop_info->ce != ce)) { + continue; + } + prop = NULL; + if (prop_info->offset >= 0) { + if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) { + prop = ce->default_static_members_table[prop_info->offset]; + } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { + prop = ce->default_properties_table[prop_info->offset]; + } + } + if (!prop) { + continue; + } + + /* copy: enforce read only access */ + ALLOC_ZVAL(prop_copy); + *prop_copy = *prop; + zval_copy_ctor(prop_copy); + INIT_PZVAL(prop_copy); + + /* this is necessary to make it able to work with default array + * properties, returned to user */ + if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + zval_update_constant(&prop_copy, (void *) 1 TSRMLS_CC); + } + + add_assoc_zval(return_value, key, prop_copy); + } +} +/* }}} */ + +/* {{{ proto public array ReflectionClass::getStaticProperties() + Returns an associative array containing all static property values of the class */ +ZEND_METHOD(reflection_class, getStaticProperties) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + + zend_update_class_constants(ce TSRMLS_CC); + + array_init(return_value); + add_class_vars(ce, 1, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public mixed ReflectionClass::getStaticPropertyValue(string name [, mixed default]) + Returns the value of a static property */ +ZEND_METHOD(reflection_class, getStaticPropertyValue) +{ + reflection_object *intern; + zend_class_entry *ce; + char *name; + int name_len; + zval **prop, *def_value = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &name_len, &def_value) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + + zend_update_class_constants(ce TSRMLS_CC); + prop = zend_std_get_static_property(ce, name, name_len, 1, NULL TSRMLS_CC); + if (!prop) { + if (def_value) { + RETURN_ZVAL(def_value, 1, 0); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not have a property named %s", ce->name, name); + } + return; + } else { + RETURN_ZVAL(*prop, 1, 0); + } +} +/* }}} */ + +/* {{{ proto public void ReflectionClass::setStaticPropertyValue($name, $value) + Sets the value of a static property */ +ZEND_METHOD(reflection_class, setStaticPropertyValue) +{ + reflection_object *intern; + zend_class_entry *ce; + char *name; + int name_len; + zval **variable_ptr, *value; + int refcount; + zend_uchar is_ref; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &value) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + + zend_update_class_constants(ce TSRMLS_CC); + variable_ptr = zend_std_get_static_property(ce, name, name_len, 1, NULL TSRMLS_CC); + if (!variable_ptr) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not have a property named %s", ce->name, name); + return; + } + refcount = Z_REFCOUNT_PP(variable_ptr); + is_ref = Z_ISREF_PP(variable_ptr); + zval_dtor(*variable_ptr); + **variable_ptr = *value; + zval_copy_ctor(*variable_ptr); + Z_SET_REFCOUNT_PP(variable_ptr, refcount); + Z_SET_ISREF_TO_PP(variable_ptr, is_ref); + +} +/* }}} */ + +/* {{{ proto public array ReflectionClass::getDefaultProperties() + Returns an associative array containing copies of all default property values of the class */ +ZEND_METHOD(reflection_class, getDefaultProperties) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + array_init(return_value); + zend_update_class_constants(ce TSRMLS_CC); + add_class_vars(ce, 1, return_value TSRMLS_CC); + add_class_vars(ce, 0, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public string ReflectionClass::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_class, __toString) +{ + reflection_object *intern; + zend_class_entry *ce; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + string_init(&str); + _class_string(&str, ce, intern->obj, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public string ReflectionClass::getName() + Returns the class' name */ +ZEND_METHOD(reflection_class, getName) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isInternal() + Returns whether this class is an internal class */ +ZEND_METHOD(reflection_class, isInternal) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isUserDefined() + Returns whether this class is user-defined */ +ZEND_METHOD(reflection_class, isUserDefined) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + RETURN_BOOL(ce->type == ZEND_USER_CLASS); +} +/* }}} */ + +/* {{{ proto public string ReflectionClass::getFileName() + Returns the filename of the file this class was declared in */ +ZEND_METHOD(reflection_class, getFileName) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + if (ce->type == ZEND_USER_CLASS) { + RETURN_STRING(ce->info.user.filename, 1); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public int ReflectionClass::getStartLine() + Returns the line this class' declaration starts at */ +ZEND_METHOD(reflection_class, getStartLine) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + if (ce->type == ZEND_USER_FUNCTION) { + RETURN_LONG(ce->info.user.line_start); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public int ReflectionClass::getEndLine() + Returns the line this class' declaration ends at */ +ZEND_METHOD(reflection_class, getEndLine) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + if (ce->type == ZEND_USER_CLASS) { + RETURN_LONG(ce->info.user.line_end); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public string ReflectionClass::getDocComment() + Returns the doc comment for this class */ +ZEND_METHOD(reflection_class, getDocComment) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) { + RETURN_STRINGL(ce->info.user.doc_comment, ce->info.user.doc_comment_len, 1); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public ReflectionMethod ReflectionClass::getConstructor() + Returns the class' constructor if there is one, NULL otherwise */ +ZEND_METHOD(reflection_class, getConstructor) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + if (ce->constructor) { + reflection_method_factory(ce, ce->constructor, NULL, return_value TSRMLS_CC); + } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::hasMethod(string name) + Returns whether a method exists or not */ +ZEND_METHOD(reflection_class, hasMethod) +{ + reflection_object *intern; + zend_class_entry *ce; + char *name, *lc_name; + int name_len; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == 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_exists(&ce->function_table, lc_name, name_len + 1)) { + efree(lc_name); + RETURN_TRUE; + } else { + efree(lc_name); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto public ReflectionMethod ReflectionClass::getMethod(string name) throws ReflectionException + Returns the class' method specified by its name */ +ZEND_METHOD(reflection_class, getMethod) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_function *mptr; + zval obj_tmp; + char *name, *lc_name; + int name_len; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + lc_name = zend_str_tolower_dup(name, name_len); + if (ce == zend_ce_closure && intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) != 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 TSRMLS_CC); + efree(lc_name); + } else if (ce == zend_ce_closure && !intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(&obj_tmp TSRMLS_CC)) != 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 TSRMLS_CC); + zval_dtor(&obj_tmp); + efree(lc_name); + } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) { + reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC); + efree(lc_name); + } else { + efree(lc_name); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Method %s does not exist", name); + return; + } +} +/* }}} */ + +/* {{{ _addmethod */ +static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, long filter, zval *obj TSRMLS_DC) +{ + zval *method; + uint len = strlen(mptr->common.function_name); + zend_function *closure; + + if (mptr->common.fn_flags & filter) { + ALLOC_ZVAL(method); + if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) + && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 + && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL) + { + mptr = closure; + } + /* don't assign closure_object since we only reflect the invoke handler + method and not the closure definition itself, even if we have a + closure */ + reflection_method_factory(ce, mptr, NULL, method TSRMLS_CC); + add_next_index_zval(retval, method); + } +} +/* }}} */ + +/* {{{ _addmethod */ +static int _addmethod_va(zend_function *mptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + zend_class_entry *ce = *va_arg(args, zend_class_entry**); + zval *retval = va_arg(args, zval*); + long filter = va_arg(args, long); + zval *obj = va_arg(args, zval *); + + _addmethod(mptr, ce, retval, filter, obj TSRMLS_CC); + 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; + long filter = 0; + int argc = ZEND_NUM_ARGS(); + + METHOD_NOTSTATIC(reflection_class_ptr); + if (argc) { + if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) { + return; + } + } else { + /* No parameters given, default to "return all" */ + filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC; + } + + GET_REFLECTION_OBJECT_PTR(ce); + + array_init(return_value); + zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter, intern->obj); + if (intern->obj && instanceof_function(ce, zend_ce_closure TSRMLS_CC)) { + zend_function *closure = zend_get_closure_invoke_method(intern->obj TSRMLS_CC); + if (closure) { + _addmethod(closure, ce, return_value, filter, intern->obj TSRMLS_CC); + _free_function(closure TSRMLS_CC); + } + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::hasProperty(string name) + Returns whether a property exists or not */ +ZEND_METHOD(reflection_class, hasProperty) +{ + reflection_object *intern; + zend_property_info *property_info; + zend_class_entry *ce; + char *name; + int name_len; + zval *property; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + if (zend_hash_find(&ce->properties_info, name, name_len+1, (void **) &property_info) == SUCCESS) { + if (property_info->flags & ZEND_ACC_SHADOW) { + RETURN_FALSE; + } + RETURN_TRUE; + } else { + if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property)) { + MAKE_STD_ZVAL(property); + ZVAL_STRINGL(property, name, name_len, 1); + if (Z_OBJ_HANDLER_P(intern->obj, has_property)(intern->obj, property, 2, 0 TSRMLS_CC)) { + zval_ptr_dtor(&property); + RETURN_TRUE; + } + zval_ptr_dtor(&property); + } + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto public ReflectionProperty ReflectionClass::getProperty(string name) throws ReflectionException + Returns the class' property specified by its name */ +ZEND_METHOD(reflection_class, getProperty) +{ + reflection_object *intern; + zend_class_entry *ce, **pce; + zend_property_info *property_info; + char *name, *tmp, *classname; + int name_len, classname_len; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS) { + if ((property_info->flags & ZEND_ACC_SHADOW) == 0) { + reflection_property_factory(ce, property_info, return_value TSRMLS_CC); + return; + } + } else if (intern->obj) { + /* Check for dynamic properties */ + if (zend_hash_exists(Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC), name, name_len+1)) { + zend_property_info property_info_tmp; + property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC; + property_info_tmp.name = estrndup(name, name_len); + property_info_tmp.name_length = name_len; + property_info_tmp.h = zend_get_hash_value(name, name_len+1); + property_info_tmp.doc_comment = NULL; + property_info_tmp.ce = ce; + + reflection_property_factory(ce, &property_info_tmp, return_value TSRMLS_CC); + intern = (reflection_object *) zend_object_store_get_object(return_value TSRMLS_CC); + intern->ref_type = REF_TYPE_DYNAMIC_PROPERTY; + return; + } + } + if ((tmp = strstr(name, "::")) != NULL) { + classname_len = tmp - name; + classname = zend_str_tolower_dup(name, classname_len); + classname[classname_len] = '\0'; + name_len = name_len - (classname_len + 2); + name = tmp + 2; + + if (zend_lookup_class(classname, classname_len, &pce TSRMLS_CC) == FAILURE) { + if (!EG(exception)) { + zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", classname); + } + efree(classname); + return; + } + efree(classname); + + if (!instanceof_function(ce, *pce TSRMLS_CC)) { + zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Fully qualified property name %s::%s does not specify a base class of %s", (*pce)->name, name, ce->name); + return; + } + ce = *pce; + + if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS && (property_info->flags & ZEND_ACC_SHADOW) == 0) { + reflection_property_factory(ce, property_info, return_value TSRMLS_CC); + return; + } + } + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Property %s does not exist", name); +} +/* }}} */ + +/* {{{ _addproperty */ +static int _addproperty(zend_property_info *pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + zval *property; + 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 & filter) { + ALLOC_ZVAL(property); + reflection_property_factory(ce, pptr, property TSRMLS_CC); + add_next_index_zval(retval, property); + } + return 0; +} +/* }}} */ + +/* {{{ _adddynproperty */ +static int _adddynproperty(zval **pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + zval *property; + zend_class_entry *ce = *va_arg(args, zend_class_entry**); + zval *retval = va_arg(args, zval*), member; + + /* under some circumstances, the properties hash table may contain numeric + * properties (e.g. when casting from array). This is a WONT FIX bug, at + * least for the moment. Ignore these */ + if (hash_key->nKeyLength == 0) { + return 0; + } + + if (hash_key->arKey[0] == '\0') { + return 0; /* non public cannot be dynamic */ + } + + ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0); + if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) { + MAKE_STD_ZVAL(property); + EG(std_property_info).flags = ZEND_ACC_IMPLICIT_PUBLIC; + reflection_property_factory(ce, &EG(std_property_info), property TSRMLS_CC); + add_next_index_zval(retval, property); + } + return 0; +} +/* }}} */ + +/* {{{ proto public ReflectionProperty[] ReflectionClass::getProperties([long $filter]) + Returns an array of this class' properties */ +ZEND_METHOD(reflection_class, getProperties) +{ + reflection_object *intern; + zend_class_entry *ce; + long filter = 0; + int argc = ZEND_NUM_ARGS(); + + METHOD_NOTSTATIC(reflection_class_ptr); + if (argc) { + if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) { + return; + } + } else { + /* No parameters given, default to "return all" */ + filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC; + } + + GET_REFLECTION_OBJECT_PTR(ce); + + array_init(return_value); + zend_hash_apply_with_arguments(&ce->properties_info TSRMLS_CC, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter); + + if (intern->obj && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT_P(intern->obj)->get_properties) { + HashTable *properties = Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC); + zend_hash_apply_with_arguments(properties TSRMLS_CC, (apply_func_args_t) _adddynproperty, 2, &ce, return_value); + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::hasConstant(string name) + Returns whether a constant exists or not */ +ZEND_METHOD(reflection_class, hasConstant) +{ + reflection_object *intern; + zend_class_entry *ce; + char *name; + int name_len; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + if (zend_hash_exists(&ce->constants_table, name, name_len + 1)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto public array ReflectionClass::getConstants() + Returns an associative array containing this class' constants and their values */ +ZEND_METHOD(reflection_class, getConstants) +{ + zval *tmp_copy; + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + array_init(return_value); + zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC); + zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *)); +} +/* }}} */ + +/* {{{ proto public mixed ReflectionClass::getConstant(string name) + Returns the class' constant specified by its name */ +ZEND_METHOD(reflection_class, getConstant) +{ + reflection_object *intern; + zend_class_entry *ce; + zval **value; + char *name; + int name_len; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { + return; + } + + GET_REFLECTION_OBJECT_PTR(ce); + zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC); + if (zend_hash_find(&ce->constants_table, name, name_len + 1, (void **) &value) == FAILURE) { + RETURN_FALSE; + } + MAKE_COPY_ZVAL(value, return_value); +} +/* }}} */ + +/* {{{ _class_check_flag */ +static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + RETVAL_BOOL(ce->ce_flags & mask); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isInstantiable() + Returns whether this class is instantiable */ +ZEND_METHOD(reflection_class, isInstantiable) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) { + RETURN_FALSE; + } + + /* Basically, the class is instantiable. Though, if there is a constructor + * and it is not publicly accessible, it isn't! */ + if (!ce->constructor) { + RETURN_TRUE; + } + + RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isCloneable() + Returns whether this class is cloneable */ +ZEND_METHOD(reflection_class, isCloneable) +{ + reflection_object *intern; + zend_class_entry *ce; + zval obj; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) { + RETURN_FALSE; + } + if (intern->obj) { + if (ce->clone) { + RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC); + } else { + RETURN_BOOL(Z_OBJ_HANDLER_P(intern->obj, clone_obj) != NULL); + } + } else { + if (ce->clone) { + RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC); + } else { + object_init_ex(&obj, ce); + RETVAL_BOOL(Z_OBJ_HANDLER(obj, clone_obj) != NULL); + zval_dtor(&obj); + } + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isInterface() + Returns whether this is an interface or a class */ +ZEND_METHOD(reflection_class, isInterface) +{ + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isTrait() + Returns whether this is a trait */ +ZEND_METHOD(reflection_class, isTrait) +{ + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isFinal() + Returns whether this class is final */ +ZEND_METHOD(reflection_class, isFinal) +{ + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL_CLASS); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isAbstract() + Returns whether this class is abstract */ +ZEND_METHOD(reflection_class, isAbstract) +{ + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); +} +/* }}} */ + +/* {{{ proto public int ReflectionClass::getModifiers() + Returns a bitfield of the access modifiers for this class */ +ZEND_METHOD(reflection_class, getModifiers) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + RETURN_LONG(ce->ce_flags); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isInstance(stdclass object) + Returns whether the given object is an instance of this class */ +ZEND_METHOD(reflection_class, isInstance) +{ + reflection_object *intern; + zend_class_entry *ce; + zval *object; + + METHOD_NOTSTATIC(reflection_class_ptr); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + RETURN_BOOL(HAS_CLASS_ENTRY(*object) && instanceof_function(Z_OBJCE_P(object), ce TSRMLS_CC)); +} +/* }}} */ + +/* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...) + Returns an instance of this class */ +ZEND_METHOD(reflection_class, newInstance) +{ + zval *retval_ptr = NULL; + reflection_object *intern; + zend_class_entry *ce; + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + /* Run the constructor if there is one */ + if (ce->constructor) { + zval ***params = NULL; + int num_args = 0; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + + if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name); + return; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", ¶ms, &num_args) == FAILURE) { + if (params) { + efree(params); + } + RETURN_FALSE; + } + + object_init_ex(return_value, ce); + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = return_value; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = num_args; + fci.params = params; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = ce->constructor; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(return_value); + fcc.object_ptr = return_value; + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { + if (params) { + efree(params); + } + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name); + RETURN_NULL(); + } + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + if (params) { + efree(params); + } + } else if (!ZEND_NUM_ARGS()) { + object_init_ex(return_value, ce); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name); + } +} +/* }}} */ + +/* {{{ proto public stdclass ReflectionClass::newInstanceWithoutConstructor() + Returns an instance of this class without invoking its constructor */ +ZEND_METHOD(reflection_class, newInstanceWithoutConstructor) +{ + reflection_object *intern; + zend_class_entry *ce; + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + if (ce->create_object != NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s is an internal class that cannot be instantiated without invoking its constructor", ce->name); + } + + object_init_ex(return_value, ce); +} +/* }}} */ + +/* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args]) + Returns an instance of this class */ +ZEND_METHOD(reflection_class, newInstanceArgs) +{ + zval *retval_ptr = NULL; + reflection_object *intern; + zend_class_entry *ce; + int argc = 0; + HashTable *args; + + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) { + return; + } + if (ZEND_NUM_ARGS() > 0) { + argc = args->nNumOfElements; + } + + /* Run the constructor if there is one */ + if (ce->constructor) { + zval ***params = NULL; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + + if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name); + return; + } + + if (argc) { + params = safe_emalloc(sizeof(zval **), argc, 0); + zend_hash_apply_with_argument(args, (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC); + params -= argc; + } + + object_init_ex(return_value, ce); + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.function_name = NULL; + fci.symbol_table = NULL; + fci.object_ptr = return_value; + fci.retval_ptr_ptr = &retval_ptr; + fci.param_count = argc; + fci.params = params; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = ce->constructor; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(return_value); + fcc.object_ptr = return_value; + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { + if (params) { + efree(params); + } + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name); + RETURN_NULL(); + } + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + if (params) { + efree(params); + } + } else if (!ZEND_NUM_ARGS() || !argc) { + object_init_ex(return_value, ce); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass[] ReflectionClass::getInterfaces() + Returns an array of interfaces this class implements */ +ZEND_METHOD(reflection_class, getInterfaces) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + /* Return an empty array if this class implements no interfaces */ + array_init(return_value); + + if (ce->num_interfaces) { + zend_uint i; + + for (i=0; i < ce->num_interfaces; i++) { + zval *interface; + ALLOC_ZVAL(interface); + zend_reflection_class_factory(ce->interfaces[i], interface TSRMLS_CC); + add_assoc_zval_ex(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length + 1, interface); + } + } +} +/* }}} */ + +/* {{{ proto public String[] ReflectionClass::getInterfaceNames() + Returns an array of names of interfaces this class implements */ +ZEND_METHOD(reflection_class, getInterfaceNames) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_uint i; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + /* Return an empty array if this class implements no interfaces */ + array_init(return_value); + + for (i=0; i < ce->num_interfaces; i++) { + add_next_index_stringl(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length, 1); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass[] ReflectionClass::getTraits() + Returns an array of traits used by this class */ +ZEND_METHOD(reflection_class, getTraits) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_uint i; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + array_init(return_value); + + for (i=0; i < ce->num_traits; i++) { + zval *trait; + ALLOC_ZVAL(trait); + zend_reflection_class_factory(ce->traits[i], trait TSRMLS_CC); + add_assoc_zval_ex(return_value, ce->traits[i]->name, ce->traits[i]->name_length + 1, trait); + } +} +/* }}} */ + +/* {{{ proto public String[] ReflectionClass::getTraitNames() + Returns an array of names of traits used by this class */ +ZEND_METHOD(reflection_class, getTraitNames) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_uint i; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + array_init(return_value); + + for (i=0; i < ce->num_traits; i++) { + add_next_index_stringl(return_value, ce->traits[i]->name, ce->traits[i]->name_length, 1); + } +} +/* }}} */ + +/* {{{ proto public arra ReflectionClass::getTraitaliases() + Returns an array of trait aliases */ +ZEND_METHOD(reflection_class, getTraitAliases) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + array_init(return_value); + + if (ce->trait_aliases) { + zend_uint i = 0; + while (ce->trait_aliases[i]) { + char *method_name; + int method_name_len; + zend_trait_method_reference *cur_ref = ce->trait_aliases[i]->trait_method; + + if (ce->trait_aliases[i]->alias) { + method_name_len = spprintf(&method_name, 0, "%s::%s", cur_ref->ce->name, cur_ref->method_name); + add_assoc_stringl_ex(return_value, ce->trait_aliases[i]->alias, ce->trait_aliases[i]->alias_len + 1, method_name, method_name_len, 0); + } + i++; + } + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass ReflectionClass::getParentClass() + Returns the class' parent class, or, if none exists, FALSE */ +ZEND_METHOD(reflection_class, getParentClass) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ce); + + if (ce->parent) { + zend_reflection_class_factory(ce->parent, return_value TSRMLS_CC); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class) + Returns whether this class is a subclass of another class */ +ZEND_METHOD(reflection_class, isSubclassOf) +{ + reflection_object *intern, *argument; + zend_class_entry *ce, **pce, *class_ce; + zval *class_name; + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE) { + return; + } + + switch(class_name->type) { + case IS_STRING: + if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not exist", Z_STRVAL_P(class_name)); + return; + } + class_ce = *pce; + break; + case IS_OBJECT: + if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr TSRMLS_CC)) { + argument = (reflection_object *) zend_object_store_get_object(class_name TSRMLS_CC); + if (argument == NULL || argument->ptr == NULL) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object"); + /* Bails out */ + } + class_ce = argument->ptr; + break; + } + /* no break */ + default: + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter one must either be a string or a ReflectionClass object"); + return; + } + + RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce TSRMLS_CC))); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name) + Returns whether this class is a subclass of another class */ +ZEND_METHOD(reflection_class, implementsInterface) +{ + reflection_object *intern, *argument; + zend_class_entry *ce, *interface_ce, **pce; + zval *interface; + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &interface) == FAILURE) { + return; + } + + switch(interface->type) { + case IS_STRING: + if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Interface %s does not exist", Z_STRVAL_P(interface)); + return; + } + interface_ce = *pce; + break; + case IS_OBJECT: + if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr TSRMLS_CC)) { + argument = (reflection_object *) zend_object_store_get_object(interface TSRMLS_CC); + if (argument == NULL || argument->ptr == NULL) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object"); + /* Bails out */ + } + interface_ce = argument->ptr; + break; + } + /* no break */ + default: + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Parameter one must either be a string or a ReflectionClass object"); + return; + } + + if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Interface %s is a Class", interface_ce->name); + return; + } + RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC)); +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::isIterateable() + Returns whether this class is iterateable (can be used inside foreach) */ +ZEND_METHOD(reflection_class, isIterateable) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + RETURN_BOOL(ce->get_iterator != NULL); +} +/* }}} */ + +/* {{{ proto public ReflectionExtension|NULL ReflectionClass::getExtension() + Returns NULL or the extension the class belongs to */ +ZEND_METHOD(reflection_class, getExtension) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) { + reflection_extension_factory(return_value, ce->info.internal.module->name TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public string|false ReflectionClass::getExtensionName() + Returns false or the name of the extension the class belongs to */ +ZEND_METHOD(reflection_class, getExtensionName) +{ + reflection_object *intern; + zend_class_entry *ce; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + METHOD_NOTSTATIC(reflection_class_ptr); + GET_REFLECTION_OBJECT_PTR(ce); + + if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) { + RETURN_STRING(ce->info.internal.module->name, 1); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto public bool ReflectionClass::inNamespace() + Returns whether this class is defined in namespace */ +ZEND_METHOD(reflection_class, inNamespace) +{ + zval **name; + const char *backslash; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) { + RETURN_FALSE; + } + if (Z_TYPE_PP(name) == IS_STRING + && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name))) + && backslash > Z_STRVAL_PP(name)) + { + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public string ReflectionClass::getNamespaceName() + Returns the name of namespace where this class is defined */ +ZEND_METHOD(reflection_class, getNamespaceName) +{ + zval **name; + const char *backslash; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) { + RETURN_FALSE; + } + if (Z_TYPE_PP(name) == IS_STRING + && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name))) + && backslash > Z_STRVAL_PP(name)) + { + RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1); + } + RETURN_EMPTY_STRING(); +} +/* }}} */ + +/* {{{ proto public string ReflectionClass::getShortName() + Returns the short name of the class (without namespace part) */ +ZEND_METHOD(reflection_class, getShortName) +{ + zval **name; + const char *backslash; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) { + RETURN_FALSE; + } + if (Z_TYPE_PP(name) == IS_STRING + && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name))) + && backslash > Z_STRVAL_PP(name)) + { + RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1); + } + RETURN_ZVAL(*name, 1, 0); +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionObject::export(mixed argument [, bool return]) throws ReflectionException + Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ +ZEND_METHOD(reflection_object, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionObject::__construct(mixed argument) throws ReflectionException + Constructor. Takes an instance as an argument */ +ZEND_METHOD(reflection_object, __construct) +{ + reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionProperty::export(mixed class, 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_property, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2); +} +/* }}} */ + +/* {{{ proto public void ReflectionProperty::__construct(mixed class, string name) + Constructor. Throws an Exception in case the given property does not exist */ +ZEND_METHOD(reflection_property, __construct) +{ + zval *propname, *classname; + char *name_str; + const char *class_name, *prop_name; + int name_len, dynam_prop = 0; + zval *object; + reflection_object *intern; + zend_class_entry **pce; + zend_class_entry *ce; + zend_property_info *property_info = NULL; + property_reference *reference; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) { + return; + } + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + + /* Find the class entry */ + switch (Z_TYPE_P(classname)) { + case IS_STRING: + if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Class %s does not exist", Z_STRVAL_P(classname)); + return; + } + ce = *pce; + break; + + case IS_OBJECT: + ce = Z_OBJCE_P(classname); + break; + + default: + _DO_THROW("The parameter class is expected to be either a string or an object"); + /* returns out of this function */ + } + + if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) { + /* Check for dynamic properties */ + if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) { + if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname TSRMLS_CC), name_str, name_len+1)) { + dynam_prop = 1; + } + } + if (dynam_prop == 0) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Property %s::$%s does not exist", ce->name, name_str); + return; + } + } + + if (dynam_prop == 0 && (property_info->flags & ZEND_ACC_PRIVATE) == 0) { + /* we have to search the class hierarchy for this (implicit) public or protected property */ + zend_class_entry *tmp_ce = ce; + zend_property_info *tmp_info; + + while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, name_str, name_len + 1, (void **) &tmp_info) != SUCCESS) { + ce = tmp_ce; + property_info = tmp_info; + tmp_ce = tmp_ce->parent; + } + } + + MAKE_STD_ZVAL(classname); + MAKE_STD_ZVAL(propname); + + if (dynam_prop == 0) { + zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name); + ZVAL_STRINGL(classname, property_info->ce->name, property_info->ce->name_length, 1); + ZVAL_STRING(propname, prop_name, 1); + } else { + ZVAL_STRINGL(classname, ce->name, ce->name_length, 1); + ZVAL_STRINGL(propname, name_str, name_len, 1); + } + reflection_update_property(object, "class", classname); + reflection_update_property(object, "name", propname); + + reference = (property_reference*) emalloc(sizeof(property_reference)); + if (dynam_prop) { + reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC; + reference->prop.name = Z_STRVAL_P(propname); + reference->prop.name_length = Z_STRLEN_P(propname); + reference->prop.h = zend_get_hash_value(name_str, name_len+1); + reference->prop.doc_comment = NULL; + reference->prop.ce = ce; + } else { + reference->prop = *property_info; + } + reference->ce = ce; + intern->ptr = reference; + intern->ref_type = REF_TYPE_PROPERTY; + intern->ce = ce; + intern->ignore_visibility = 0; +} +/* }}} */ + +/* {{{ proto public string ReflectionProperty::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_property, __toString) +{ + reflection_object *intern; + property_reference *ref; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + string_init(&str); + _property_string(&str, &ref->prop, NULL, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public string ReflectionProperty::getName() + Returns the class' name */ +ZEND_METHOD(reflection_property, getName) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC); +} +/* }}} */ + +static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */ +{ + reflection_object *intern; + property_reference *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + RETURN_BOOL(ref->prop.flags & mask); +} +/* }}} */ + +/* {{{ proto public bool ReflectionProperty::isPublic() + 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); +} +/* }}} */ + +/* {{{ proto public bool ReflectionProperty::isPrivate() + Returns whether this property is private */ +ZEND_METHOD(reflection_property, isPrivate) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE); +} +/* }}} */ + +/* {{{ proto public bool ReflectionProperty::isProtected() + Returns whether this property is protected */ +ZEND_METHOD(reflection_property, isProtected) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED); +} +/* }}} */ + +/* {{{ proto public bool ReflectionProperty::isStatic() + Returns whether this property is static */ +ZEND_METHOD(reflection_property, isStatic) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionProperty::isDefault() + 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); +} +/* }}} */ + +/* {{{ proto public int ReflectionProperty::getModifiers() + Returns a bitfield of the access modifiers for this property */ +ZEND_METHOD(reflection_property, getModifiers) +{ + reflection_object *intern; + property_reference *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + + RETURN_LONG(ref->prop.flags); +} +/* }}} */ + +/* {{{ proto public mixed ReflectionProperty::getValue([stdclass object]) + Returns this property's value */ +ZEND_METHOD(reflection_property, getValue) +{ + reflection_object *intern; + property_reference *ref; + zval *object, name; + zval *member_p = NULL; + + METHOD_NOTSTATIC(reflection_property_ptr); + GET_REFLECTION_OBJECT_PTR(ref); + + if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) { + _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name)); + zval_dtor(&name); + return; + } + + if ((ref->prop.flags & ZEND_ACC_STATIC)) { + zend_update_class_constants(intern->ce TSRMLS_CC); + if (!CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name); + /* Bails out */ + } + *return_value= *CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; + zval_copy_ctor(return_value); + INIT_PZVAL(return_value); + } else { + const char *class_name, *prop_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) { + return; + } + zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name); + member_p = zend_read_property(ref->ce, object, prop_name, strlen(prop_name), 1 TSRMLS_CC); + MAKE_COPY_ZVAL(&member_p, return_value); + if (member_p != EG(uninitialized_zval_ptr)) { + zval_add_ref(&member_p); + zval_ptr_dtor(&member_p); + } + } +} +/* }}} */ + +/* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value) + Sets this property's value */ +ZEND_METHOD(reflection_property, setValue) +{ + reflection_object *intern; + property_reference *ref; + zval **variable_ptr; + zval *object, name; + zval *value; + zval *tmp; + + METHOD_NOTSTATIC(reflection_property_ptr); + GET_REFLECTION_OBJECT_PTR(ref); + + if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { + _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name)); + zval_dtor(&name); + return; + } + + if ((ref->prop.flags & ZEND_ACC_STATIC)) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &tmp, &value) == FAILURE) { + return; + } + } + zend_update_class_constants(intern->ce TSRMLS_CC); + + if (!CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name); + /* Bails out */ + } + variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; + if (*variable_ptr != value) { + if (PZVAL_IS_REF(*variable_ptr)) { + zval garbage = **variable_ptr; /* old value should be destroyed */ + + /* To check: can't *variable_ptr be some system variable like error_zval here? */ + Z_TYPE_PP(variable_ptr) = Z_TYPE_P(value); + (*variable_ptr)->value = value->value; + if (Z_REFCOUNT_P(value) > 0) { + zval_copy_ctor(*variable_ptr); + } + zval_dtor(&garbage); + } else { + zval *garbage = *variable_ptr; + + /* if we assign referenced variable, we should separate it */ + Z_ADDREF_P(value); + if (PZVAL_IS_REF(value)) { + SEPARATE_ZVAL(&value); + } + *variable_ptr = value; + zval_ptr_dtor(&garbage); + } + } + } else { + const char *class_name, *prop_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) { + return; + } + zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name); + zend_update_property(ref->ce, object, prop_name, strlen(prop_name), value TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ proto public ReflectionClass ReflectionProperty::getDeclaringClass() + Get the declaring class */ +ZEND_METHOD(reflection_property, getDeclaringClass) +{ + reflection_object *intern; + property_reference *ref; + zend_class_entry *tmp_ce, *ce; + zend_property_info *tmp_info; + const char *prop_name, *class_name; + int prop_name_len; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + + if (zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name) != SUCCESS) { + RETURN_FALSE; + } + + prop_name_len = strlen(prop_name); + ce = tmp_ce = ref->ce; + while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, prop_name_len + 1, (void **) &tmp_info) == SUCCESS) { + if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) { + /* it's a private property, so it can't be inherited */ + break; + } + ce = tmp_ce; + if (tmp_ce == tmp_info->ce) { + /* declared in this class, done */ + break; + } + tmp_ce = tmp_ce->parent; + } + + zend_reflection_class_factory(ce, return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public string ReflectionProperty::getDocComment() + Returns the doc comment for this property */ +ZEND_METHOD(reflection_property, getDocComment) +{ + reflection_object *intern; + property_reference *ref; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(ref); + if (ref->prop.doc_comment) { + RETURN_STRINGL(ref->prop.doc_comment, ref->prop.doc_comment_len, 1); + } + RETURN_FALSE; +} +/* }}} */ + +/* {{{ proto public int ReflectionProperty::setAccessible(bool visible) + Sets whether non-public properties can be requested */ +ZEND_METHOD(reflection_property, setAccessible) +{ + reflection_object *intern; + zend_bool visible; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) { + return; + } + + intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); + + if (intern == NULL) { + return; + } + + intern->ignore_visibility = visible; +} +/* }}} */ + +/* {{{ 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) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionExtension::__construct(string name) + 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; + zend_module_entry *module; + char *name_str; + int name_len; + ALLOCA_FLAG(use_heap) + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) { + return; + } + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + lcname = do_alloca(name_len + 1, use_heap); + zend_str_tolower_copy(lcname, name_str, name_len); + if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) { + free_alloca(lcname, use_heap); + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Extension %s does not exist", name_str); + return; + } + free_alloca(lcname, use_heap); + MAKE_STD_ZVAL(name); + ZVAL_STRING(name, module->name, 1); + reflection_update_property( object, "name", name); + intern->ptr = module; + intern->ref_type = REF_TYPE_OTHER; + intern->ce = NULL; +} +/* }}} */ + +/* {{{ proto public string ReflectionExtension::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_extension, __toString) +{ + reflection_object *intern; + zend_module_entry *module; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + string_init(&str); + _extension_string(&str, module, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public string ReflectionExtension::getName() + Returns this extension's name */ +ZEND_METHOD(reflection_extension, getName) +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public string ReflectionExtension::getVersion() + Returns this extension's version */ +ZEND_METHOD(reflection_extension, getVersion) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + /* An extension does not necessarily have a version number */ + if (module->version == NO_VERSION_YET) { + RETURN_NULL(); + } else { + RETURN_STRING(module->version, 1); + } +} +/* }}} */ + +/* {{{ proto public ReflectionFunction[] ReflectionExtension::getFunctions() + Returns an array of this extension's fuctions */ +ZEND_METHOD(reflection_extension, getFunctions) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + if (module->functions) { + zval *function; + zend_function *fptr; + const zend_function_entry *func = module->functions; + + /* Is there a better way of doing this? */ + while (func->fname) { + int fname_len = strlen(func->fname); + char *lc_name = zend_str_tolower_dup(func->fname, fname_len); + + if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname); + func++; + efree(lc_name); + continue; + } + + ALLOC_ZVAL(function); + reflection_function_factory(fptr, NULL, function TSRMLS_CC); + add_assoc_zval_ex(return_value, func->fname, fname_len+1, function); + func++; + efree(lc_name); + } + } +} +/* }}} */ + +static int _addconstant(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +{ + zval *const_val; + zval *retval = va_arg(args, zval*); + int number = va_arg(args, int); + + if (number == constant->module_number) { + ALLOC_ZVAL(const_val); + *const_val = constant->value; + zval_copy_ctor(const_val); + INIT_PZVAL(const_val); + add_assoc_zval_ex(retval, constant->name, constant->name_len, 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; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _addconstant, 2, return_value, module->module_number); +} +/* }}} */ + +/* {{{ _addinientry */ +static int _addinientry(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + zval *retval = va_arg(args, zval*); + int number = va_arg(args, int); + + if (number == ini_entry->module_number) { + if (ini_entry->value) { + add_assoc_stringl(retval, ini_entry->name, ini_entry->value, ini_entry->value_length, 1); + } else { + add_assoc_null(retval, ini_entry->name); + } + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +/* {{{ proto public array ReflectionExtension::getINIEntries() + Returns an associative array containing this extension's INI entries and their values */ +ZEND_METHOD(reflection_extension, getINIEntries) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _addinientry, 2, return_value, module->module_number); +} +/* }}} */ + +/* {{{ add_extension_class */ +static int add_extension_class(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +{ + 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 (((*pce)->type == ZEND_INTERNAL_CLASS) && (*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, module->name)) { + if (add_reflection_class) { + ALLOC_ZVAL(zclass); + zend_reflection_class_factory(*pce, zclass TSRMLS_CC); + add_assoc_zval_ex(class_array, (*pce)->name, (*pce)->name_length + 1, zclass); + } else { + add_next_index_stringl(class_array, (*pce)->name, (*pce)->name_length, 1); + } + } + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +/* {{{ proto public ReflectionClass[] ReflectionExtension::getClasses() + Returns an array containing ReflectionClass objects for all classes of this extension */ +ZEND_METHOD(reflection_extension, getClasses) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 1); +} +/* }}} */ + +/* {{{ proto public array ReflectionExtension::getClassNames() + Returns an array containing all names of all classes of this extension */ +ZEND_METHOD(reflection_extension, getClassNames) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 0); +} +/* }}} */ + +/* {{{ proto public array ReflectionExtension::getDependencies() + Returns an array containing all names of all extensions this extension depends on */ +ZEND_METHOD(reflection_extension, getDependencies) +{ + reflection_object *intern; + zend_module_entry *module; + const zend_module_dep *dep; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + + dep = module->deps; + + if (!dep) + { + return; + } + + while(dep->name) { + char *relation; + char *rel_type; + int len; + + switch(dep->type) { + case MODULE_DEP_REQUIRED: + rel_type = "Required"; + break; + case MODULE_DEP_CONFLICTS: + rel_type = "Conflicts"; + break; + case MODULE_DEP_OPTIONAL: + rel_type = "Optional"; + break; + default: + rel_type = "Error"; /* shouldn't happen */ + break; + } + + len = spprintf(&relation, 0, "%s%s%s%s%s", + rel_type, + dep->rel ? " " : "", + dep->rel ? dep->rel : "", + dep->version ? " " : "", + dep->version ? dep->version : ""); + add_assoc_stringl(return_value, dep->name, relation, len, 0); + dep++; + } +} +/* }}} */ + +/* {{{ proto public void ReflectionExtension::info() + Prints phpinfo block for the extension */ +ZEND_METHOD(reflection_extension, info) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + php_info_print_module(module TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto public bool ReflectionExtension::isPersistent() + Returns whether this extension is persistent */ +ZEND_METHOD(reflection_extension, isPersistent) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + RETURN_BOOL(module->type == MODULE_PERSISTENT); +} +/* }}} */ + +/* {{{ proto public bool ReflectionExtension::isTemporary() + Returns whether this extension is temporary */ +ZEND_METHOD(reflection_extension, isTemporary) +{ + reflection_object *intern; + zend_module_entry *module; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(module); + + RETURN_BOOL(module->type == MODULE_TEMPORARY); +} +/* }}} */ + +/* {{{ proto public static mixed ReflectionZendExtension::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_zend_extension, export) +{ + _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_zend_extension_ptr, 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionZendExtension::__construct(string name) + 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; + char *name_str; + int name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) { + return; + } + + object = getThis(); + intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC); + if (intern == NULL) { + return; + } + + extension = zend_get_extension(name_str); + if (!extension) { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Zend Extension %s does not exist", name_str); + return; + } + MAKE_STD_ZVAL(name); + ZVAL_STRING(name, extension->name, 1); + reflection_update_property(object, "name", name); + intern->ptr = extension; + intern->ref_type = REF_TYPE_OTHER; + intern->ce = NULL; +} +/* }}} */ + +/* {{{ proto public string ReflectionZendExtension::__toString() + Returns a string representation */ +ZEND_METHOD(reflection_zend_extension, __toString) +{ + reflection_object *intern; + zend_extension *extension; + string str; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(extension); + string_init(&str); + _zend_extension_string(&str, extension, "" TSRMLS_CC); + RETURN_STRINGL(str.string, str.len - 1, 0); +} +/* }}} */ + +/* {{{ proto public string ReflectionZendExtension::getName() + Returns the name of this Zend extension */ +ZEND_METHOD(reflection_zend_extension, getName) +{ + reflection_object *intern; + zend_extension *extension; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(extension); + + RETURN_STRING(extension->name, 1); +} +/* }}} */ + +/* {{{ proto public string ReflectionZendExtension::getVersion() + Returns the version information of this Zend extension */ +ZEND_METHOD(reflection_zend_extension, getVersion) +{ + reflection_object *intern; + zend_extension *extension; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(extension); + + RETURN_STRING(extension->version ? extension->version : "", 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionZendExtension::getAuthor() + * Returns the name of this Zend extension's author */ +ZEND_METHOD(reflection_zend_extension, getAuthor) +{ + reflection_object *intern; + zend_extension *extension; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(extension); + + RETURN_STRING(extension->author ? extension->author : "", 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionZendExtension::getURL() + Returns this Zend extension's URL*/ +ZEND_METHOD(reflection_zend_extension, getURL) +{ + reflection_object *intern; + zend_extension *extension; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(extension); + + RETURN_STRING(extension->URL ? extension->URL : "", 1); +} +/* }}} */ + +/* {{{ proto public void ReflectionZendExtension::getCopyright() + Returns this Zend extension's copyright information */ +ZEND_METHOD(reflection_zend_extension, getCopyright) +{ + reflection_object *intern; + zend_extension *extension; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(extension); + + RETURN_STRING(extension->copyright ? extension->copyright : "", 1); +} +/* }}} */ + +/* {{{ method tables */ +static const zend_function_entry reflection_exception_functions[] = { + PHP_FE_END +}; + +ZEND_BEGIN_ARG_INFO(arginfo_reflection__void, 0) +ZEND_END_ARG_INFO() + + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0) + ZEND_ARG_INFO(0, modifiers) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0) + ZEND_ARG_INFO(0, return) +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) + 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 +}; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0) + ZEND_ARG_INFO(0, args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0) + ZEND_ARG_ARRAY_INFO(0, args, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry reflection_function_abstract_functions[] = { + ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) + PHP_ABSTRACT_ME(reflection_function, __toString, arginfo_reflection__void) + ZEND_ME(reflection_function, inNamespace, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, isClosure, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getEndLine, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getExtension, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getExtensionName, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getFileName, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getName, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getNamespaceName, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getNumberOfParameters, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getNumberOfRequiredParameters, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getParameters, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getShortName, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getStartLine, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, getStaticVariables, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, returnsReference, arginfo_reflection__void, 0) + PHP_FE_END +}; + +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_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) + ZEND_ME(reflection_function, getClosure, arginfo_reflection__void, 0) + PHP_FE_END +}; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2) + ZEND_ARG_INFO(0, class) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1) + ZEND_ARG_INFO(0, class_or_method) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0) + ZEND_ARG_INFO(0, object) + ZEND_ARG_ARRAY_INFO(0, args, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_getClosure, 0) + ZEND_ARG_INFO(0, object) +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_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) + ZEND_ME(reflection_method, isPrivate, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, getClosure, arginfo_reflection_method_getClosure, 0) + ZEND_ME(reflection_method, getModifiers, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0) + ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0) + ZEND_ME(reflection_method, getDeclaringClass, arginfo_reflection__void, 0) + ZEND_ME(reflection_method, getPrototype, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, setAccessible, arginfo_reflection_method_setAccessible, 0) + PHP_FE_END +}; + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1) + ZEND_ARG_INFO(0, argument) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0) + ZEND_ARG_INFO(0, argument) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, default) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0) + ZEND_ARG_INFO(0, filter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0) + ZEND_ARG_INFO(0, filter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0) + ZEND_ARG_INFO(0, args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstanceWithoutConstructor, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0) + ZEND_ARG_ARRAY_INFO(0, args, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0) + ZEND_ARG_INFO(0, interface) +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_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) + ZEND_ME(reflection_class, isInternal, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isUserDefined, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isInstantiable, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isCloneable, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getFileName, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getStartLine, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getEndLine, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getDocComment, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getConstructor, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0) + ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0) + ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0) + ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0) + ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0) + ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0) + ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0) + ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0) + ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getTraits, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getTraitNames, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getTraitAliases, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isTrait, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0) + ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0) + ZEND_ME(reflection_class, newInstanceWithoutConstructor, arginfo_reflection_class_newInstanceWithoutConstructor, 0) + ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0) + ZEND_ME(reflection_class, getParentClass, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0) + ZEND_ME(reflection_class, getStaticProperties, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0) + ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0) + ZEND_ME(reflection_class, getDefaultProperties, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, isIterateable, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0) + ZEND_ME(reflection_class, getExtension, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getExtensionName, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, inNamespace, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getNamespaceName, arginfo_reflection__void, 0) + ZEND_ME(reflection_class, getShortName, arginfo_reflection__void, 0) + PHP_FE_END +}; + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1) + ZEND_ARG_INFO(0, argument) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0) + ZEND_ARG_INFO(0, argument) +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_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0) + PHP_FE_END +}; + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 2) + ZEND_ARG_INFO(0, class) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property___construct, 0, 0, 2) + ZEND_ARG_INFO(0, class) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_getValue, 0, 0, 0) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, value) +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_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, isPublic, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, isStatic, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, isDefault, arginfo_reflection__void, 0) + ZEND_ME(reflection_property, getModifiers, arginfo_reflection__void, 0) + 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) + PHP_FE_END +}; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2) + ZEND_ARG_INFO(0, function) + ZEND_ARG_INFO(0, parameter) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0) + ZEND_ARG_INFO(0, function) + ZEND_ARG_INFO(0, parameter) +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_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) + ZEND_ME(reflection_parameter, isPassedByReference, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, canBePassedByValue, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, getDeclaringFunction, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isCallable, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0) + PHP_FE_END +}; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, return) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0) + ZEND_ARG_INFO(0, name) +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_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) + ZEND_ME(reflection_extension, getVersion, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, getFunctions, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, getConstants, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, getINIEntries, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, getClasses, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, getClassNames, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, getDependencies, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, info, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, isPersistent, arginfo_reflection__void, 0) + ZEND_ME(reflection_extension, isTemporary, arginfo_reflection__void, 0) + PHP_FE_END +}; + +ZEND_BEGIN_ARG_INFO(arginfo_reflection_zend_extension___construct, 0) + ZEND_ARG_INFO(0, name) +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_ME(reflection_zend_extension, __construct, arginfo_reflection_extension___construct, 0) + ZEND_ME(reflection_zend_extension, __toString, arginfo_reflection__void, 0) + ZEND_ME(reflection_zend_extension, getName, arginfo_reflection__void, 0) + ZEND_ME(reflection_zend_extension, getVersion, arginfo_reflection__void, 0) + ZEND_ME(reflection_zend_extension, getAuthor, arginfo_reflection__void, 0) + ZEND_ME(reflection_zend_extension, getURL, arginfo_reflection__void, 0) + ZEND_ME(reflection_zend_extension, getCopyright, arginfo_reflection__void, 0) + PHP_FE_END +}; +/* }}} */ + +const zend_function_entry reflection_ext_functions[] = { /* {{{ */ + PHP_FE_END +}; /* }}} */ + +static zend_object_handlers *zend_std_obj_handlers; + +/* {{{ _reflection_write_property */ +static void _reflection_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +{ + if ((Z_TYPE_P(member) == IS_STRING) + && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1) + && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name"))) + || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class"))))) + { + zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, + "Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member)); + } + else + { + zend_std_obj_handlers->write_property(object, member, value, key TSRMLS_CC); + } +} +/* }}} */ + +PHP_MINIT_FUNCTION(reflection) /* {{{ */ +{ + zend_class_entry _reflection_entry; + + zend_std_obj_handlers = zend_get_std_object_handlers(); + memcpy(&reflection_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + reflection_object_handlers.clone_obj = NULL; + reflection_object_handlers.write_property = _reflection_write_property; + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions); + reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions); + reflection_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions); + reflector_ptr = zend_register_internal_interface(&_reflection_entry TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + reflection_register_implement(reflection_function_abstract_ptr, reflector_ptr TSRMLS_CC); + zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC); + zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + reflection_register_implement(reflection_parameter_ptr, reflector_ptr TSRMLS_CC); + zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC); + zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED); + REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE); + REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT); + 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_class_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + reflection_register_implement(reflection_class_ptr, reflector_ptr TSRMLS_CC); + zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS); + REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); + REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL_CLASS); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr, NULL TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_property_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + reflection_register_implement(reflection_property_ptr, reflector_ptr TSRMLS_CC); + zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED); + 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_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + reflection_register_implement(reflection_extension_ptr, reflector_ptr TSRMLS_CC); + zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions); + _reflection_entry.create_object = reflection_objects_new; + reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC); + reflection_register_implement(reflection_zend_extension_ptr, reflector_ptr TSRMLS_CC); + zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + return SUCCESS; +} /* }}} */ + +PHP_MINFO_FUNCTION(reflection) /* {{{ */ +{ + php_info_print_table_start(); + php_info_print_table_header(2, "Reflection", "enabled"); + + php_info_print_table_row(2, "Version", "$Id: 25ecbad68e5a4573ffee43ea24a0591ea179492a $"); + + php_info_print_table_end(); +} /* }}} */ + +zend_module_entry reflection_module_entry = { /* {{{ */ + STANDARD_MODULE_HEADER, + "Reflection", + reflection_ext_functions, + PHP_MINIT(reflection), + NULL, + NULL, + NULL, + PHP_MINFO(reflection), + "$Id: 25ecbad68e5a4573ffee43ea24a0591ea179492a $", + STANDARD_MODULE_PROPERTIES +}; /* }}} */ + +/* + * 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 new file mode 100644 index 0000000..48470f4 --- /dev/null +++ b/ext/reflection/php_reflection.h @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 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 | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: George Schlossnagle <george@omniti.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_REFLECTION_H +#define PHP_REFLECTION_H + +#include "php.h" + +extern zend_module_entry reflection_module_entry; +#define phpext_reflection_ptr &reflection_module_entry + +BEGIN_EXTERN_C() + +/* Class entry pointers */ +extern PHPAPI zend_class_entry *reflector_ptr; +extern PHPAPI zend_class_entry *reflection_exception_ptr; +extern PHPAPI zend_class_entry *reflection_ptr; +extern PHPAPI zend_class_entry *reflection_function_abstract_ptr; +extern PHPAPI zend_class_entry *reflection_function_ptr; +extern PHPAPI zend_class_entry *reflection_parameter_ptr; +extern PHPAPI zend_class_entry *reflection_class_ptr; +extern PHPAPI zend_class_entry *reflection_object_ptr; +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; + +PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC); + +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/001.phpt b/ext/reflection/tests/001.phpt new file mode 100644 index 0000000..f68afc9 --- /dev/null +++ b/ext/reflection/tests/001.phpt @@ -0,0 +1,89 @@ +--TEST-- +Reflection inheritance +--FILE-- +<?php + +class ReflectionClassEx extends ReflectionClass +{ + public $bla; + + function getMethodNames() + { + $res = array(); + foreach($this->getMethods() as $m) + { + $res[] = $m->class . '::' . $m->name; + } + return $res; + } +} + +$r = new ReflectionClassEx('ReflectionClassEx'); + +$exp = array ( + 'UMLClass::__clone', + 'UMLClass::export', + 'UMLClass::__construct', + 'UMLClass::__toString', + 'UMLClass::getName', + 'UMLClass::isInternal', + 'UMLClass::isUserDefined', + 'UMLClass::isInstantiable', + 'UMLClass::getFileName', + 'UMLClass::getStartLine', + 'UMLClass::getEndLine', + 'UMLClass::getDocComment', + 'UMLClass::getConstructor', + 'UMLClass::getMethod', + 'UMLClass::getMethods', + 'UMLClass::getProperty', + 'UMLClass::getProperties', + 'UMLClass::getConstants', + 'UMLClass::getConstant', + 'UMLClass::getInterfaces', + 'UMLClass::isInterface', + 'UMLClass::isAbstract', + 'UMLClass::isFinal', + 'UMLClass::getModifiers', + 'UMLClass::isInstance', + 'UMLClass::newInstance', + 'UMLClass::getParentClass', + 'UMLClass::isSubclassOf', + 'UMLClass::getStaticProperties', + 'UMLClass::getDefaultProperties', + 'UMLClass::isIterateable', + 'UMLClass::implementsInterface', + 'UMLClass::getExtension', + 'UMLClass::getExtensionName'); + +$miss = array(); + +$res = $r->getMethodNames(); + +foreach($exp as $m) +{ + if (!in_array($m, $exp)) + { + $miss[] = $m; + } +} + +var_dump($miss); + +$props = array_keys(get_class_vars('ReflectionClassEx')); +sort($props); +var_dump($props); +var_dump($r->name); +?> +===DONE=== +--EXPECT-- +array(0) { +} +array(2) { + [0]=> + string(3) "bla" + [1]=> + string(4) "name" +} +string(17) "ReflectionClassEx" +===DONE=== diff --git a/ext/reflection/tests/002.phpt b/ext/reflection/tests/002.phpt new file mode 100644 index 0000000..833fed4 --- /dev/null +++ b/ext/reflection/tests/002.phpt @@ -0,0 +1,63 @@ +--TEST-- +Reflection properties are read only +--FILE-- +<?php + +class ReflectionMethodEx extends ReflectionMethod +{ + public $foo = "xyz"; + + function __construct($c,$m) + { + echo __METHOD__ . "\n"; + parent::__construct($c,$m); + } +} + +$r = new ReflectionMethodEx('ReflectionMethodEx','getName'); + +var_dump($r->class); +var_dump($r->name); +var_dump($r->foo); +@var_dump($r->bar); + +try +{ + $r->class = 'bullshit'; +} +catch(ReflectionException $e) +{ + echo $e->getMessage() . "\n"; +} +try +{ +$r->name = 'bullshit'; +} +catch(ReflectionException $e) +{ + echo $e->getMessage() . "\n"; +} + +$r->foo = 'bar'; +$r->bar = 'baz'; + +var_dump($r->class); +var_dump($r->name); +var_dump($r->foo); +var_dump($r->bar); + +?> +===DONE=== +--EXPECTF-- +ReflectionMethodEx::__construct +%unicode|string%(26) "ReflectionFunctionAbstract" +%unicode|string%(7) "getName" +%unicode|string%(3) "xyz" +NULL +Cannot set read-only property ReflectionMethodEx::$class +Cannot set read-only property ReflectionMethodEx::$name +%unicode|string%(26) "ReflectionFunctionAbstract" +%unicode|string%(7) "getName" +%unicode|string%(3) "bar" +%unicode|string%(3) "baz" +===DONE=== diff --git a/ext/reflection/tests/003.phpt b/ext/reflection/tests/003.phpt new file mode 100644 index 0000000..80bf0a6 --- /dev/null +++ b/ext/reflection/tests/003.phpt @@ -0,0 +1,31 @@ +--TEST-- +ReflectionMethod::invoke() with base class method +--FILE-- +<?php + +class Foo +{ + function Test() + { + echo __METHOD__ . "\n"; + } +} + +class Bar extends Foo +{ + function Test() + { + echo __METHOD__ . "\n"; + } +} + +$o = new Bar; +$r = new ReflectionMethod('Foo','Test'); + +$r->invoke($o); + +?> +===DONE=== +--EXPECT-- +Foo::Test +===DONE=== diff --git a/ext/reflection/tests/004.phpt b/ext/reflection/tests/004.phpt new file mode 100644 index 0000000..2c81c50 --- /dev/null +++ b/ext/reflection/tests/004.phpt @@ -0,0 +1,42 @@ +--TEST-- +ReflectionMethod::invoke() with non object or null value +--FILE-- +<?php + +class a { + function a(){ + } +} +class b { +} + +$b = new b(); + +$a=new ReflectionClass("a"); +$m=$a->getMethod("a"); + +try { + $m->invoke(null); +} catch (ReflectionException $E) { + echo $E->getMessage()."\n"; +} + + +try { + $m->invoke($b); +} catch (ReflectionException $E) { + echo $E->getMessage()."\n"; +} + +$b = new a(); +try { + $m->invoke($b); +} catch (ReflectionException $E) { + echo $E->getMessage()."\n"; +} + +echo "===DONE===\n";?> +--EXPECT-- +Non-object passed to Invoke() +Given object is not an instance of the class this method was declared in +===DONE=== diff --git a/ext/reflection/tests/005.phpt b/ext/reflection/tests/005.phpt new file mode 100644 index 0000000..f337e44 --- /dev/null +++ b/ext/reflection/tests/005.phpt @@ -0,0 +1,54 @@ +--TEST-- +ReflectionMethod::getDocComment() uses wrong comment block +--FILE-- +<?php + +function strip_doc_comment($c) +{ + if (!strlen($c) || $c === false) return $c; + return trim(substr($c, 3, -2)); +} + +/** Comment for class A */ +class A +{ + /** Method A::bla() + */ + function bla() + { + } + + function foo() { + /** + * This is a valid comment inside a method + */ + } + + function bar() { + // I don't have a doc comment.... + } + + /** + * Comment for A::baz() + */ + function baz() { + } +} + +$r = new ReflectionClass('A'); +var_dump(strip_doc_comment($r->getDocComment())); + +foreach($r->getMethods() as $m) +{ + var_dump(strip_doc_comment($m->getDocComment())); +} + +?> +===DONE=== +--EXPECT-- +string(19) "Comment for class A" +string(15) "Method A::bla()" +bool(false) +bool(false) +string(22) "* Comment for A::baz()" +===DONE=== diff --git a/ext/reflection/tests/006.phpt b/ext/reflection/tests/006.phpt new file mode 100644 index 0000000..89c4387 --- /dev/null +++ b/ext/reflection/tests/006.phpt @@ -0,0 +1,103 @@ +--TEST-- +ReflectionClass::[gs]etStaticPropertyValue +--FILE-- +<?php + +/* ReflectionClass cannot touch protected or private static properties */ + +/* ReflectionClass cannot create or delete static properties */ + +Class Test +{ + static public $pub = 'pub'; + static protected $pro = 'pro'; + static private $pri = 'pri'; + + static function testing() + { + $ref = new ReflectionClass('Test'); + + foreach(array('pub', 'pro', 'pri') as $name) + { + try + { + var_dump($ref->getStaticPropertyValue($name)); + var_dump($ref->getStaticPropertyValue($name)); + $ref->setStaticPropertyValue($name, 'updated'); + var_dump($ref->getStaticPropertyValue($name)); + } + catch(Exception $e) + { + echo "EXCEPTION\n"; + } + } + } +} + +Class TestDerived extends Test +{ +// static public $pub = 'pub'; +// static protected $pro = 'pro'; + static private $pri = 'pri'; + + static function testing() + { + $ref = new ReflectionClass('Test'); + + foreach(array('pub', 'pro', 'pri') as $name) + { + try + { + var_dump($ref->getStaticPropertyValue($name)); + var_dump($ref->getStaticPropertyValue($name)); + $ref->setStaticPropertyValue($name, 'updated'); + var_dump($ref->getStaticPropertyValue($name)); + } + catch(Exception $e) + { + echo "EXCEPTION\n"; + } + } + } +} + +$ref = new ReflectionClass('Test'); + +foreach(array('pub', 'pro', 'pri') as $name) +{ + try + { + var_dump($ref->getStaticPropertyValue($name)); + var_dump($ref->getStaticPropertyValue($name)); + $ref->setStaticPropertyValue($name, 'updated'); + var_dump($ref->getStaticPropertyValue($name)); + } + catch(Exception $e) + { + echo "EXCEPTION\n"; + } +} + +Test::testing(); +TestDerived::testing(); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECT-- +string(3) "pub" +string(3) "pub" +string(7) "updated" +EXCEPTION +EXCEPTION +string(7) "updated" +string(7) "updated" +string(7) "updated" +EXCEPTION +EXCEPTION +string(7) "updated" +string(7) "updated" +string(7) "updated" +EXCEPTION +EXCEPTION +===DONE=== diff --git a/ext/reflection/tests/007.phpt b/ext/reflection/tests/007.phpt new file mode 100644 index 0000000..004158c --- /dev/null +++ b/ext/reflection/tests/007.phpt @@ -0,0 +1,160 @@ +--TEST-- +ReflectionClass::newInstance[Args] +--FILE-- +<?php + +function test($class) +{ + echo "====>$class\n"; + try + { + $ref = new ReflectionClass($class); + } + catch (ReflectionException $e) + { + var_dump($e->getMessage()); + return; // only here + } + + echo "====>newInstance()\n"; + try + { + var_dump($ref->newInstance()); + } + catch (ReflectionException $e) + { + var_dump($e->getMessage()); + } + + echo "====>newInstance(25)\n"; + try + { + var_dump($ref->newInstance(25)); + } + catch (ReflectionException $e) + { + var_dump($e->getMessage()); + } + + echo "====>newInstance(25, 42)\n"; + try + { + var_dump($ref->newInstance(25, 42)); + } + catch (ReflectionException $e) + { + var_dump($e->getMessage()); + } + + echo "\n"; +} + +function __autoload($class) +{ + echo __FUNCTION__ . "($class)\n"; +} + +test('Class_does_not_exist'); + +Class NoCtor +{ +} + +test('NoCtor'); + +Class WithCtor +{ + function __construct() + { + echo __METHOD__ . "()\n"; + var_dump(func_get_args()); + } +} + +test('WithCtor'); + +Class WithCtorWithArgs +{ + function __construct($arg) + { + echo __METHOD__ . "($arg)\n"; + var_dump(func_get_args()); + } +} + +test('WithCtorWithArgs'); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- + +====>Class_does_not_exist +__autoload(Class_does_not_exist) +string(41) "Class Class_does_not_exist does not exist" +====>NoCtor +====>newInstance() +object(NoCtor)#%d (0) { +} +====>newInstance(25) +string(86) "Class NoCtor does not have a constructor, so you cannot pass any constructor arguments" +====>newInstance(25, 42) +string(86) "Class NoCtor does not have a constructor, so you cannot pass any constructor arguments" + +====>WithCtor +====>newInstance() +WithCtor::__construct() +array(0) { +} +object(WithCtor)#%d (0) { +} +====>newInstance(25) +WithCtor::__construct() +array(1) { + [0]=> + int(25) +} +object(WithCtor)#%d (0) { +} +====>newInstance(25, 42) +WithCtor::__construct() +array(2) { + [0]=> + int(25) + [1]=> + int(42) +} +object(WithCtor)#%d (0) { +} + +====>WithCtorWithArgs +====>newInstance() + +Warning: Missing argument 1 for WithCtorWithArgs::__construct() in %s007.php on line %d + +Notice: Undefined variable: arg in %s007.php on line %d +WithCtorWithArgs::__construct() +array(0) { +} +object(WithCtorWithArgs)#%d (0) { +} +====>newInstance(25) +WithCtorWithArgs::__construct(25) +array(1) { + [0]=> + int(25) +} +object(WithCtorWithArgs)#%d (0) { +} +====>newInstance(25, 42) +WithCtorWithArgs::__construct(25) +array(2) { + [0]=> + int(25) + [1]=> + int(42) +} +object(WithCtorWithArgs)#%d (0) { +} + +===DONE=== diff --git a/ext/reflection/tests/008.phpt b/ext/reflection/tests/008.phpt new file mode 100644 index 0000000..2abdcdb --- /dev/null +++ b/ext/reflection/tests/008.phpt @@ -0,0 +1,39 @@ +--TEST-- +ReflectionMethod::__construct() tests +--FILE-- +<?php + +$a = array("", 1, "::", "a::", "::b", "a::b"); + +foreach ($a as $val) { + try { + new ReflectionMethod($val); + } catch (Exception $e) { + var_dump($e->getMessage()); + } +} + +$a = array("", 1, ""); +$b = array("", "", 1); + +foreach ($a as $key=>$val) { + try { + new ReflectionMethod($val, $b[$key]); + } catch (Exception $e) { + var_dump($e->getMessage()); + } +} + +echo "Done\n"; +?> +--EXPECTF-- +string(20) "Invalid method name " +string(21) "Invalid method name 1" +string(21) "Class does not exist" +string(22) "Class a does not exist" +string(21) "Class does not exist" +string(22) "Class a does not exist" +string(21) "Class does not exist" +string(66) "The parameter class is expected to be either a string or an object" +string(21) "Class does not exist" +Done diff --git a/ext/reflection/tests/009.phpt b/ext/reflection/tests/009.phpt new file mode 100644 index 0000000..e96b21e --- /dev/null +++ b/ext/reflection/tests/009.phpt @@ -0,0 +1,112 @@ +--TEST-- +ReflectionFunction basic tests +--FILE-- +<?php + +/** +hoho +*/ +function test ($a, $b = 1, $c = "") { + static $var = 1; +} + +$func = new ReflectionFunction("test"); + +var_dump($func->export("test")); +echo "--getName--\n"; +var_dump($func->getName()); +echo "--isInternal--\n"; +var_dump($func->isInternal()); +echo "--isUserDefined--\n"; +var_dump($func->isUserDefined()); +echo "--getFilename--\n"; +var_dump($func->getFilename()); +echo "--getStartline--\n"; +var_dump($func->getStartline()); +echo "--getEndline--\n"; +var_dump($func->getEndline()); +echo "--getDocComment--\n"; +var_dump($func->getDocComment()); +echo "--getStaticVariables--\n"; +var_dump($func->getStaticVariables()); +echo "--invoke--\n"; +var_dump($func->invoke(array(1,2,3))); +echo "--invokeArgs--\n"; +var_dump($func->invokeArgs(array(1,2,3))); +echo "--returnsReference--\n"; +var_dump($func->returnsReference()); +echo "--getParameters--\n"; +var_dump($func->getParameters()); +echo "--getNumberOfParameters--\n"; +var_dump($func->getNumberOfParameters()); +echo "--getNumberOfRequiredParameters--\n"; +var_dump($func->getNumberOfRequiredParameters()); + +echo "Done\n"; + +?> +--EXPECTF-- +/** +hoho +*/ +Function [ <user> function test ] { + @@ %s009.php 6 - 8 + + - Parameters [3] { + Parameter #0 [ <required> $a ] + Parameter #1 [ <optional> $b = 1 ] + Parameter #2 [ <optional> $c = '' ] + } +} + +NULL +--getName-- +string(4) "test" +--isInternal-- +bool(false) +--isUserDefined-- +bool(true) +--getFilename-- +string(%d) "%s009.php" +--getStartline-- +int(6) +--getEndline-- +int(8) +--getDocComment-- +string(11) "/** +hoho +*/" +--getStaticVariables-- +array(1) { + ["var"]=> + int(1) +} +--invoke-- +NULL +--invokeArgs-- +NULL +--returnsReference-- +bool(false) +--getParameters-- +array(3) { + [0]=> + &object(ReflectionParameter)#2 (1) { + ["name"]=> + string(1) "a" + } + [1]=> + &object(ReflectionParameter)#3 (1) { + ["name"]=> + string(1) "b" + } + [2]=> + &object(ReflectionParameter)#4 (1) { + ["name"]=> + string(1) "c" + } +} +--getNumberOfParameters-- +int(3) +--getNumberOfRequiredParameters-- +int(1) +Done diff --git a/ext/reflection/tests/010.phpt b/ext/reflection/tests/010.phpt new file mode 100644 index 0000000..8f92fee --- /dev/null +++ b/ext/reflection/tests/010.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionMethod::__toString() tests (overriden method) +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Foo { + function func() { + } +} +class Bar extends Foo { + function func() { + } +} +$m = new ReflectionMethod("Bar::func"); +echo $m; +?> +--EXPECTF-- +Method [ <user, overwrites Foo, prototype Foo> public method func ] { + @@ %s010.php 7 - 8 +} diff --git a/ext/reflection/tests/011.phpt b/ext/reflection/tests/011.phpt new file mode 100644 index 0000000..b39be37 --- /dev/null +++ b/ext/reflection/tests/011.phpt @@ -0,0 +1,12 @@ +--TEST-- +ReflectionExtension::getClasses() +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +$ext = new ReflectionExtension("reflection"); +$classes = $ext->getClasses(); +echo $classes["ReflectionException"]->getName(); +?> +--EXPECT-- +ReflectionException diff --git a/ext/reflection/tests/012.phpt b/ext/reflection/tests/012.phpt new file mode 100644 index 0000000..b8a2694 --- /dev/null +++ b/ext/reflection/tests/012.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionClass::getDefaultProperties() +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Foo { + public $test = "ok"; +} +$class = new ReflectionClass("Foo"); +$props = $class->getDefaultProperties(); +echo $props["test"]; +?> +--EXPECT-- +ok + diff --git a/ext/reflection/tests/013.phpt b/ext/reflection/tests/013.phpt new file mode 100644 index 0000000..9ecfa8b --- /dev/null +++ b/ext/reflection/tests/013.phpt @@ -0,0 +1,13 @@ +--TEST-- +ReflectionExtension::getFunctions() +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +$ext = new ReflectionExtension("standard"); +$funcs = $ext->getFunctions(); +echo $funcs["sleep"]->getName(); +?> +--EXPECT-- +sleep + diff --git a/ext/reflection/tests/014.phpt b/ext/reflection/tests/014.phpt new file mode 100644 index 0000000..8b5955f --- /dev/null +++ b/ext/reflection/tests/014.phpt @@ -0,0 +1,13 @@ +--TEST-- +ReflectionExtension::getConstants() +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +$ext = new ReflectionExtension("standard"); +$consts = $ext->getConstants(); +var_dump($consts["CONNECTION_NORMAL"]); +?> +--EXPECT-- +int(0) + diff --git a/ext/reflection/tests/015.phpt b/ext/reflection/tests/015.phpt new file mode 100644 index 0000000..b172362 --- /dev/null +++ b/ext/reflection/tests/015.phpt @@ -0,0 +1,15 @@ +--TEST-- +ReflectionExtension::getINIEntries() +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--INI-- +user_agent=php +--FILE-- +<?php +$ext = new ReflectionExtension("standard"); +$inis = $ext->getINIEntries(); +var_dump($inis["user_agent"]); +?> +--EXPECT-- +string(3) "php" + diff --git a/ext/reflection/tests/016.phpt b/ext/reflection/tests/016.phpt new file mode 100644 index 0000000..d289165 --- /dev/null +++ b/ext/reflection/tests/016.phpt @@ -0,0 +1,20 @@ +--TEST-- +ReflectionExtension::getDependencies() +--SKIPIF-- +<?php +extension_loaded('reflection') or die('skip'); +if (!extension_loaded("xml")) { + die('skip xml extension not available'); +} +?> +--FILE-- +<?php +$ext = new ReflectionExtension("xml"); +$deps = $ext->getDependencies(); +var_dump($deps); +?> +--EXPECT-- +array(1) { + ["libxml"]=> + string(8) "Required" +} diff --git a/ext/reflection/tests/017.phpt b/ext/reflection/tests/017.phpt new file mode 100644 index 0000000..d40c4d8 --- /dev/null +++ b/ext/reflection/tests/017.phpt @@ -0,0 +1,33 @@ +--TEST-- +ReflectionClass::__toString() (constants) +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Foo { + const test = "ok"; +} +$class = new ReflectionClass("Foo"); +echo $class; +?> +--EXPECTF-- +Class [ <user> class Foo ] { + @@ %s017.php 2-4 + + - Constants [1] { + Constant [ string test ] { ok } + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + diff --git a/ext/reflection/tests/018.phpt b/ext/reflection/tests/018.phpt new file mode 100644 index 0000000..fbda5d6 --- /dev/null +++ b/ext/reflection/tests/018.phpt @@ -0,0 +1,15 @@ +--TEST-- +Reflection::getModifierNames +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +var_dump(Reflection::getModifierNames(ReflectionMethod::IS_FINAL | ReflectionMethod::IS_PROTECTED)); +?> +--EXPECT-- +array(2) { + [0]=> + string(5) "final" + [1]=> + string(9) "protected" +} diff --git a/ext/reflection/tests/019.phpt b/ext/reflection/tests/019.phpt new file mode 100644 index 0000000..b6ac20c --- /dev/null +++ b/ext/reflection/tests/019.phpt @@ -0,0 +1,11 @@ +--TEST-- +ReflectionFunction::getExtensionName +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +$f = new ReflectionFunction("sleep"); +var_dump($f->getExtensionName()); +?> +--EXPECT-- +string(8) "standard" diff --git a/ext/reflection/tests/020.phpt b/ext/reflection/tests/020.phpt new file mode 100644 index 0000000..c5b0ae5 --- /dev/null +++ b/ext/reflection/tests/020.phpt @@ -0,0 +1,27 @@ +--TEST-- +ReflectionObject::hasProperty +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Foo { + public $p1; + protected $p2; + private $p3; + + function __isset($name) { + var_dump($name); + return false; + } +} +$obj = new ReflectionObject(new Foo()); +var_dump($obj->hasProperty("p1")); +var_dump($obj->hasProperty("p2")); +var_dump($obj->hasProperty("p3")); +var_dump($obj->hasProperty("p4")); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/reflection/tests/021.phpt b/ext/reflection/tests/021.phpt new file mode 100644 index 0000000..30dbb5a --- /dev/null +++ b/ext/reflection/tests/021.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionClass::hasConstant +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Foo { + const c1 = 1; +} +$class = new ReflectionClass("Foo"); +var_dump($class->hasConstant("c1")); +var_dump($class->hasConstant("c2")); +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/reflection/tests/022.phpt b/ext/reflection/tests/022.phpt new file mode 100644 index 0000000..50dbd6e --- /dev/null +++ b/ext/reflection/tests/022.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionClass::getConstant +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class Foo { + const c1 = 1; +} +$class = new ReflectionClass("Foo"); +var_dump($class->getConstant("c1")); +var_dump($class->getConstant("c2")); +?> +--EXPECT-- +int(1) +bool(false) diff --git a/ext/reflection/tests/023.phpt b/ext/reflection/tests/023.phpt new file mode 100644 index 0000000..ab11365 --- /dev/null +++ b/ext/reflection/tests/023.phpt @@ -0,0 +1,32 @@ +--TEST-- +ReflectionClass::getDefaultProperties (filtering parent privates) +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class C1 { + private $p1 = 1; + protected $p2 = 2; + public $p3 = 3; +} +class C2 extends C1 { + private $p4 = 4; + protected $p5 = 5; + public $p6 = 6; +} +$class = new ReflectionClass("C2"); +var_dump($class->getDefaultProperties()); +?> +--EXPECT-- +array(5) { + ["p4"]=> + int(4) + ["p5"]=> + int(5) + ["p6"]=> + int(6) + ["p2"]=> + int(2) + ["p3"]=> + int(3) +} diff --git a/ext/reflection/tests/024.phpt b/ext/reflection/tests/024.phpt new file mode 100644 index 0000000..a1c2c81 --- /dev/null +++ b/ext/reflection/tests/024.phpt @@ -0,0 +1,45 @@ +--TEST-- +ReflectionObject::__toString (filtering privates/protected dynamic properties) +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php +class C1 { + private $p1 = 1; + protected $p2 = 2; + public $p3 = 3; +} + +$x = new C1(); +$x->z = 4; +$x->p3 = 5; + +$obj = new ReflectionObject($x); +echo $obj; +?> +--EXPECTF-- +Object of class [ <user> class C1 ] { + @@ %s024.php 2-6 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ <default> private $p1 ] + Property [ <default> protected $p2 ] + Property [ <default> public $p3 ] + } + + - Dynamic properties [1] { + Property [ <dynamic> public $z ] + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/025.phpt b/ext/reflection/tests/025.phpt new file mode 100644 index 0000000..a5f604f --- /dev/null +++ b/ext/reflection/tests/025.phpt @@ -0,0 +1,114 @@ +--TEST-- +ReflectionFunction basic tests +--SKIPIF-- +<?php extension_loaded('reflection') or die('skip'); ?> +--FILE-- +<?php + +/** +hoho +*/ +function test ($a, $b = 1, $c = "") { + static $var = 1; +} + +$func = new ReflectionFunction("test"); + +var_dump($func->export("test")); +echo "--getName--\n"; +var_dump($func->getName()); +echo "--isInternal--\n"; +var_dump($func->isInternal()); +echo "--isUserDefined--\n"; +var_dump($func->isUserDefined()); +echo "--getFilename--\n"; +var_dump($func->getFilename()); +echo "--getStartline--\n"; +var_dump($func->getStartline()); +echo "--getEndline--\n"; +var_dump($func->getEndline()); +echo "--getDocComment--\n"; +var_dump($func->getDocComment()); +echo "--getStaticVariables--\n"; +var_dump($func->getStaticVariables()); +echo "--invoke--\n"; +var_dump($func->invoke(array(1,2,3))); +echo "--invokeArgs--\n"; +var_dump($func->invokeArgs(array(1,2,3))); +echo "--returnsReference--\n"; +var_dump($func->returnsReference()); +echo "--getParameters--\n"; +var_dump($func->getParameters()); +echo "--getNumberOfParameters--\n"; +var_dump($func->getNumberOfParameters()); +echo "--getNumberOfRequiredParameters--\n"; +var_dump($func->getNumberOfRequiredParameters()); + +echo "Done\n"; + +?> +--EXPECTF-- +/** +hoho +*/ +Function [ <user> function test ] { + @@ %s 6 - 8 + + - Parameters [3] { + Parameter #0 [ <required> $a ] + Parameter #1 [ <optional> $b = 1 ] + Parameter #2 [ <optional> $c = '' ] + } +} + +NULL +--getName-- +string(4) "test" +--isInternal-- +bool(false) +--isUserDefined-- +bool(true) +--getFilename-- +string(%d) "%s025.php" +--getStartline-- +int(6) +--getEndline-- +int(8) +--getDocComment-- +string(11) "/** +hoho +*/" +--getStaticVariables-- +array(1) { + ["var"]=> + int(1) +} +--invoke-- +NULL +--invokeArgs-- +NULL +--returnsReference-- +bool(false) +--getParameters-- +array(3) { + [0]=> + &object(ReflectionParameter)#2 (1) { + ["name"]=> + string(1) "a" + } + [1]=> + &object(ReflectionParameter)#3 (1) { + ["name"]=> + string(1) "b" + } + [2]=> + &object(ReflectionParameter)#4 (1) { + ["name"]=> + string(1) "c" + } +} +--getNumberOfParameters-- +int(3) +--getNumberOfRequiredParameters-- +int(1) +Done diff --git a/ext/reflection/tests/026.phpt b/ext/reflection/tests/026.phpt new file mode 100644 index 0000000..dc4c4a3 --- /dev/null +++ b/ext/reflection/tests/026.phpt @@ -0,0 +1,34 @@ +--TEST-- +ReflectionExtension::info() +--FILE-- +<?php +$r = new ReflectionExtension("reflection"); +$r->info(); + +date_default_timezone_set('Europe/Berlin'); +$r = new ReflectionExtension("date"); +$r->info(); + +echo "\nDone!\n"; +?> +--EXPECTF-- +Reflection + +Reflection => enabled +Version => %s + +date + +date/time support => enabled +"Olson" Timezone Database Version => %s +Timezone Database => %s +Default timezone => %s + +Directive => %s => %s +date.timezone => %s => %s +date.default_latitude => %s => %s +date.default_longitude => %s => %s +date.sunset_zenith => %s => %s +date.sunrise_zenith => %s => %s + +Done! diff --git a/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt new file mode 100644 index 0000000..6b440cf --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +Reflection class can not be cloned +--CREDITS-- +Stefan Koopmanschap <stefan@phpgg.nl> +TestFest PHP|Tek +--SKIPIF-- +<?php +if (!extension_loaded('reflection)) print 'skip'; +?> +--FILE-- +<?php +$rc = new ReflectionClass("stdClass"); +$rc2 = clone($rc); +--EXPECTF-- +Fatal error: Trying to clone an uncloneable object of class ReflectionClass in %s on line %d diff --git a/ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt b/ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt new file mode 100644 index 0000000..da276e6 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_FileInfo_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +ReflectionClass::getFileName(), ReflectionClass::getStartLine(), ReflectionClass::getEndLine() +--FILE-- +<?php +//New instance of class C - defined below +$rc = new ReflectionClass("C"); + +//Get the file name of the PHP script in which C is defined +var_dump($rc->getFileName()); + +//Get the line number at the start of the definition of class C +var_dump($rc->getStartLine()); + +//Get the line number at the end of the definition of class C +var_dump($rc->getEndLine()); + +//Same tests as above but stdclass is internal - so all results should be false. +$rc = new ReflectionClass("stdClass"); +var_dump($rc->getFileName()); +var_dump($rc->getStartLine()); +var_dump($rc->getEndLine()); + +Class C { + +} +?> +--EXPECTF-- +string(%d) "%sReflectionClass_FileInfo_basic.php" +int(20) +int(22) +bool(false) +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt b/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt new file mode 100644 index 0000000..b42be13 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_FileInfo_error.phpt @@ -0,0 +1,37 @@ +--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_constructor_001.phpt b/ext/reflection/tests/ReflectionClass_constructor_001.phpt new file mode 100644 index 0000000..1a70fe1 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_constructor_001.phpt @@ -0,0 +1,33 @@ +--TEST-- +ReflectionClass::__constructor() +--FILE-- +<?php +$r1 = new ReflectionClass("stdClass"); + +$myInstance = new stdClass; +$r2 = new ReflectionClass($myInstance); + +class TrickClass { + function __toString() { + //Return the name of another class + return "Exception"; + } +} +$myTrickClass = new TrickClass; +$r3 = new ReflectionClass($myTrickClass); + +var_dump($r1, $r2, $r3); +?> +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(8) "stdClass" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(8) "stdClass" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(10) "TrickClass" +} diff --git a/ext/reflection/tests/ReflectionClass_constructor_002.phpt b/ext/reflection/tests/ReflectionClass_constructor_002.phpt new file mode 100644 index 0000000..3685c63 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_constructor_002.phpt @@ -0,0 +1,67 @@ +--TEST-- +ReflectionClass::__constructor() - bad arguments +--FILE-- +<?php +try { + var_dump(new ReflectionClass()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(new ReflectionClass(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(new ReflectionClass(true)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(new ReflectionClass(1)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(new ReflectionClass(array(1,2,3))); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(new ReflectionClass("stdClass", 1)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(new ReflectionClass("X")); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- + +Warning: ReflectionClass::__construct() expects exactly 1 parameter, 0 given in %s on line 3 +object(ReflectionClass)#%d (1) { + ["name"]=> + string(0) "" +} +Class does not exist +Class 1 does not exist +Class 1 does not exist + +Notice: Array to string conversion in %s on line 27 +Class Array does not exist + +Warning: ReflectionClass::__construct() expects exactly 1 parameter, 2 given in %s on line 33 +object(ReflectionClass)#%d (1) { + ["name"]=> + string(0) "" +} +Class X does not exist
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_export_basic1.phpt b/ext/reflection/tests/ReflectionClass_export_basic1.phpt new file mode 100644 index 0000000..8729731 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_export_basic1.phpt @@ -0,0 +1,62 @@ +--TEST-- +ReflectionClass::export() - various parameters +--FILE-- +<?php +Class A { + public function privf(Exception $a) {} + public function pubf(A $a, + $b, + C $c = null, + $d = K, + $e = "15 chars long -", + $f = null, + $g = false, + array $h = null) {} +} + +Class C extends A { } + +define('K', "16 chars long --"); +ReflectionClass::export("C"); +?> +--EXPECTF-- +Class [ <user> class C extends A ] { + @@ %s 14-14 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [2] { + Method [ <user, inherits A> public method privf ] { + @@ %s 3 - 3 + + - Parameters [1] { + Parameter #0 [ <required> Exception $a ] + } + } + + Method [ <user, inherits A> public method pubf ] { + @@ %s 4 - 11 + + - Parameters [8] { + Parameter #0 [ <required> A $a ] + Parameter #1 [ <required> $b ] + Parameter #2 [ <optional> C or NULL $c = NULL ] + Parameter #3 [ <optional> $d = '16 chars long -...' ] + Parameter #4 [ <optional> $e = '15 chars long -' ] + Parameter #5 [ <optional> $f = NULL ] + Parameter #6 [ <optional> $g = false ] + Parameter #7 [ <optional> array or NULL $h = NULL ] + } + } + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_export_basic2.phpt b/ext/reflection/tests/ReflectionClass_export_basic2.phpt new file mode 100644 index 0000000..b664488 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_export_basic2.phpt @@ -0,0 +1,54 @@ +--TEST-- +ReflectionClass::export() - ensure inherited private props are hidden. +--FILE-- +<?php +Class c { + private $a; + static private $b; +} + +class d extends c {} + +ReflectionClass::export("c"); +ReflectionClass::export("d"); +?> +--EXPECTF-- +Class [ <user> class c ] { + @@ %s 2-5 + + - Constants [0] { + } + + - Static properties [1] { + Property [ private static $b ] + } + + - Static methods [0] { + } + + - Properties [1] { + Property [ <default> private $a ] + } + + - Methods [0] { + } +} + +Class [ <user> class d extends c ] { + @@ %s 7-7 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt new file mode 100644 index 0000000..6e05111 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt @@ -0,0 +1,41 @@ +--TEST-- +ReflectionClass::getConstants() +--FILE-- +<?php +class C { + const a = 'hello from C'; +} +class D extends C { +} +class E extends D { +} +class F extends E { + const a = 'hello from F'; +} +class X { +} + +$classes = array("C", "D", "E", "F", "X"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + var_dump($rc->getConstant('a')); + var_dump($rc->getConstant('doesntexist')); +} +?> +--EXPECTF-- +Reflecting on class C: +string(12) "hello from C" +bool(false) +Reflecting on class D: +string(12) "hello from C" +bool(false) +Reflecting on class E: +string(12) "hello from C" +bool(false) +Reflecting on class F: +string(12) "hello from F" +bool(false) +Reflecting on class X: +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_getConstant_error.phpt b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt new file mode 100644 index 0000000..907d6d8 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt @@ -0,0 +1,37 @@ +--TEST-- +ReflectionClass::getConstant() - bad params +--FILE-- +<?php +class C { + const myConst = 1; +} + +$rc = new ReflectionClass("C"); +echo "Check invalid params:\n"; +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-- +Check invalid params: + +Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 0 given in %s on line 8 +NULL + +Warning: ReflectionClass::getConstant() expects exactly 1 parameter, 2 given in %s on line 9 +NULL +bool(false) +bool(false) +bool(false) +bool(false) + +Warning: ReflectionClass::getConstant() expects parameter 1 to be string, array given in %s on line 14 +NULL + +Warning: ReflectionClass::getConstant() expects parameter 1 to be string, object given in %s on line 15 +NULL
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getConstants_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstants_basic.phpt new file mode 100644 index 0000000..9abdcc8 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstants_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +ReflectionClass::getConstants() +--FILE-- +<?php +class C { + const a = 'hello from C'; +} +class D extends C { +} +class E extends D { +} +class F extends E { + const a = 'hello from F'; +} +class X { +} + +$classes = array('C', 'D', 'E', 'F', 'X'); +foreach($classes as $class) { + echo "Constants from class $class: \n"; + $rc = new ReflectionClass($class); + var_dump($rc->getConstants()); +} +?> +--EXPECTF-- +Constants from class C: +array(1) { + ["a"]=> + string(12) "hello from C" +} +Constants from class D: +array(1) { + ["a"]=> + string(12) "hello from C" +} +Constants from class E: +array(1) { + ["a"]=> + string(12) "hello from C" +} +Constants from class F: +array(1) { + ["a"]=> + string(12) "hello from F" +} +Constants from class X: +array(0) { +} diff --git a/ext/reflection/tests/ReflectionClass_getConstants_error.phpt b/ext/reflection/tests/ReflectionClass_getConstants_error.phpt new file mode 100644 index 0000000..1784d71 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstants_error.phpt @@ -0,0 +1,24 @@ +--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_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstructor_basic.phpt new file mode 100644 index 0000000..1f5ba43 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstructor_basic.phpt @@ -0,0 +1,79 @@ +--TEST-- +ReflectionClass::getConstructor() +--FILE-- +<?php +class NewCtor { + function __construct() {} +} + +class ExtendsNewCtor extends NewCtor { +} + +class OldCtor { + function OldCtor() {} +} + +class ExtendsOldCtor extends OldCtor { +} + + +class X { + function Y() {} +} + +class Y extends X { +} + +class OldAndNewCtor { + function OldAndNewCtor() {} + function __construct() {} +} + +class NewAndOldCtor { + function __construct() {} + function NewAndOldCtor() {} +} +class B { + function B() {} +} + +class C extends B { + function C() {} +} + +class D1 extends C { + function __construct() {} +} + +class D2 extends C { +} + +$classes = array('NewCtor', 'ExtendsNewCtor', 'OldCtor', 'ExtendsOldCtor', + 'OldAndNewCtor', 'NewAndOldCtor', 'B', 'C', 'D1', 'D2', 'X', 'Y'); + +foreach ($classes as $class) { + $rc = new ReflectionClass($class); + $rm = $rc->getConstructor(); + if ($rm != null) { + echo "Constructor of $class: " . $rm->getName() . "\n"; + } else { + echo "No constructor for $class\n"; + } + +} + +?> +--EXPECTF-- +Strict Standards: Redefining already defined constructor for class OldAndNewCtor in %s on line %d +Constructor of NewCtor: __construct +Constructor of ExtendsNewCtor: __construct +Constructor of OldCtor: OldCtor +Constructor of ExtendsOldCtor: OldCtor +Constructor of OldAndNewCtor: __construct +Constructor of NewAndOldCtor: __construct +Constructor of B: B +Constructor of C: C +Constructor of D1: __construct +Constructor of D2: C +No constructor for X +No constructor for Y diff --git a/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt b/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt new file mode 100644 index 0000000..7e8932a --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstructor_error.phpt @@ -0,0 +1,23 @@ +--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_001.phpt b/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt new file mode 100644 index 0000000..e19db81 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getDefaultProperties_001.phpt @@ -0,0 +1,194 @@ +--TEST-- +ReflectionClass::getDefaultProperties(), ReflectionClass::getStaticProperties() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + + +class A { + static public $statPubC = "stat pubC in A"; + static protected $statProtC = "stat protC in A"; + static private $statPrivC = "stat privC in A"; + + static public $statPubA = "stat pubA in A"; + static protected $statProtA = "stat protA in A"; + static private $statPrivA = "stat privA in A"; + + public $pubC = "pubC in A"; + protected $protC = "protC in A"; + private $privC = "privC in A"; + + public $pubA = "pubA in A"; + protected $protA = "protA in A"; + private $privA = "privA in A"; +} + +class B extends A { + static public $statPubC = "stat pubC in B"; + static protected $statProtC = "stat protC in B"; + static private $statPrivC = "stat privC in B"; + + static public $statPubB = "stat pubB in B"; + static protected $statProtB = "stat protB in B"; + static private $statPrivB = "stat privB in B"; + + public $pubC = "pubC in B"; + protected $protC = "protC in B"; + private $privC = "privC in B"; + + public $pubB = "pubB in B"; + protected $protB = "protB in B"; + private $privB = "privB in B"; +} + +class C extends B { + static public $statPubC = "stat pubC in C"; + static protected $statProtC = "stat protC in C"; + static private $statPrivC = "stat privC in C"; + + public $pubC = "pubC in C"; + protected $protC = "protC in C"; + private $privC = "privC in C"; +} + +class X { + static public $statPubC = "stat pubC in X"; + static protected $statProtC = "stat protC in X"; + static private $statPrivC = "stat privC in X"; + + public $pubC = "pubC in X"; + protected $protC = "protC in X"; + private $privC = "privC in X"; +} + +$classes = array('A', 'B', 'C', 'X'); +foreach ($classes as $class) { + $rc = new ReflectionClass($class); + echo "\n\n---- Static properties in $class ----\n"; + print_r($rc->getStaticProperties()); + echo "\n\n---- Default properties in $class ----\n"; + print_r($rc->getDefaultProperties()); +} + +?> +--EXPECTF-- +---- Static properties in A ---- +Array +( + [statPubC] => stat pubC in A + [statProtC] => stat protC in A + [statPrivC] => stat privC in A + [statPubA] => stat pubA in A + [statProtA] => stat protA in A + [statPrivA] => stat privA in A +) + + +---- Default properties in A ---- +Array +( + [statPubC] => stat pubC in A + [statProtC] => stat protC in A + [statPrivC] => stat privC in A + [statPubA] => stat pubA in A + [statProtA] => stat protA in A + [statPrivA] => stat privA in A + [pubC] => pubC in A + [protC] => protC in A + [privC] => privC in A + [pubA] => pubA in A + [protA] => protA in A + [privA] => privA in A +) + + +---- Static properties in B ---- +Array +( + [statPubC] => stat pubC in B + [statProtC] => stat protC in B + [statPrivC] => stat privC in B + [statPubB] => stat pubB in B + [statProtB] => stat protB in B + [statPrivB] => stat privB in B + [statPubA] => stat pubA in A + [statProtA] => stat protA in A +) + + +---- Default properties in B ---- +Array +( + [statPubC] => stat pubC in B + [statProtC] => stat protC in B + [statPrivC] => stat privC in B + [statPubB] => stat pubB in B + [statProtB] => stat protB in B + [statPrivB] => stat privB in B + [statPubA] => stat pubA in A + [statProtA] => stat protA in A + [pubC] => pubC in B + [protC] => protC in B + [privC] => privC in B + [pubB] => pubB in B + [protB] => protB in B + [privB] => privB in B + [pubA] => pubA in A + [protA] => protA in A +) + + +---- Static properties in C ---- +Array +( + [statPubC] => stat pubC in C + [statProtC] => stat protC in C + [statPrivC] => stat privC in C + [statPubB] => stat pubB in B + [statProtB] => stat protB in B + [statPubA] => stat pubA in A + [statProtA] => stat protA in A +) + + +---- Default properties in C ---- +Array +( + [statPubC] => stat pubC in C + [statProtC] => stat protC in C + [statPrivC] => stat privC in C + [statPubB] => stat pubB in B + [statProtB] => stat protB in B + [statPubA] => stat pubA in A + [statProtA] => stat protA in A + [pubC] => pubC in C + [protC] => protC in C + [privC] => privC in C + [pubB] => pubB in B + [protB] => protB in B + [pubA] => pubA in A + [protA] => protA in A +) + + +---- Static properties in X ---- +Array +( + [statPubC] => stat pubC in X + [statProtC] => stat protC in X + [statPrivC] => stat privC in X +) + + +---- Default properties in X ---- +Array +( + [statPubC] => stat pubC in X + [statProtC] => stat protC in X + [statPrivC] => stat privC in X + [pubC] => pubC in X + [protC] => protC in X + [privC] => privC in X +) diff --git a/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt b/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt new file mode 100644 index 0000000..7c178ac --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getDefaultProperties_002.phpt @@ -0,0 +1,44 @@ +--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_001.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt new file mode 100644 index 0000000..5feb560 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt @@ -0,0 +1,98 @@ +--TEST-- +ReflectionClass::getDocComment() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +/** + + + My +Doc + * Comment +for A + +* */ +class A {} + +/** My DocComment for B */ +class B extends A { } + +class C extends B {} + +/** + * Interface doc comment + */ + + + + +interface I {} + +/*.* + * Not a doc comment + */ +class D implements I {} + +/**** Not a doc comment */ +class E extends C implements I {} {} + +/**?** Not a doc comment */ +class F extends C implements I {} {} + +/** ** Doc comment for G */ +final class G extends C implements I {} {} + +$classes = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'I'); +foreach ($classes as $class) { + echo "\n\n---> Doc comment for class $class:\n"; + $rc = new ReflectionClass($class); + var_dump($rc->getDocComment()); +} + + +?> +--EXPECTF-- + + +---> Doc comment for class A: +string(%d) "/** + + + My +Doc + * Comment +for A + +* */" + + +---> Doc comment for class B: +string(26) "/** My DocComment for B */" + + +---> Doc comment for class C: +bool(false) + + +---> Doc comment for class D: +bool(false) + + +---> Doc comment for class E: +bool(false) + + +---> Doc comment for class F: +bool(false) + + +---> Doc comment for class G: +string(27) "/** ** Doc comment for G */" + + +---> Doc comment for class I: +string(%d) "/** + * Interface doc comment + */"
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt new file mode 100644 index 0000000..5bbd596 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getDocComment_002.phpt @@ -0,0 +1,26 @@ +--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_getExtensionName_basic.phpt b/ext/reflection/tests/ReflectionClass_getExtensionName_basic.phpt new file mode 100644 index 0000000..310b22e --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getExtensionName_basic.phpt @@ -0,0 +1,14 @@ +--TEST-- +ReflectionClass::getExtensionName() method - basic test for getExtensionName() method +--SKIPIF-- +<?php extension_loaded('dom') or die('skip - dom extension not loaded'); ?> +--CREDITS-- +Rein Velt <rein@velt.org> +#testFest Roosendaal 2008-05-10 +--FILE-- +<?php + $rc=new reflectionClass('domDocument'); + var_dump( $rc->getExtensionName()) ; +?> +--EXPECT-- +string(3) "dom" diff --git a/ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt b/ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt new file mode 100644 index 0000000..998355c --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getExtensionName_variation.phpt @@ -0,0 +1,18 @@ +--TEST-- +ReflectionClass::getExtensionName() method - variation test for getExtensionName() +--CREDITS-- +Rein Velt <rein@velt.org> +#testFest Roosendaal 2008-05-10 +--FILE-- +<?php + + class myClass + { + public $varX; + public $varY; + } + $rc=new reflectionClass('myClass'); + var_dump( $rc->getExtensionName()) ; +?> +--EXPECT-- +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_getExtension_basic.phpt b/ext/reflection/tests/ReflectionClass_getExtension_basic.phpt new file mode 100644 index 0000000..dbe157a --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getExtension_basic.phpt @@ -0,0 +1,17 @@ +--TEST-- +ReflectionClass::getExtension() method - basic test for getExtension() method +--SKIPIF-- +<?php extension_loaded('dom') or die('skip - dom extension not loaded'); ?> +--CREDITS-- +Rein Velt <rein@velt.org> +#testFest Roosendaal 2008-05-10 +--FILE-- +<?php + $rc=new reflectionClass('domDocument'); + var_dump($rc->getExtension()) ; +?> +--EXPECTF-- +object(ReflectionExtension)#%d (1) { + ["name"]=> + string(3) "dom" +} diff --git a/ext/reflection/tests/ReflectionClass_getExtension_variation.phpt b/ext/reflection/tests/ReflectionClass_getExtension_variation.phpt new file mode 100644 index 0000000..5409504 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getExtension_variation.phpt @@ -0,0 +1,18 @@ +--TEST-- +ReflectionClass::getExtension() method - variation test for getExtension() +--CREDITS-- +Rein Velt <rein@velt.org> +#testFest Roosendaal 2008-05-10 +--FILE-- +<?php + + class myClass + { + public $varX; + public $varY; + } + $rc=new reflectionClass('myClass'); + var_dump( $rc->getExtension()) ; +?> +--EXPECT-- +NULL diff --git a/ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt b/ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt new file mode 100644 index 0000000..6681c9f --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getInterfaceNames_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionClass::getInterfaceNames() +--CREDITS-- +Michelangelo van Dam <dragonbe@gmail.com> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php +interface Foo { } + +interface Bar { } + +class Baz implements Foo, Bar { } + +$rc1 = new ReflectionClass("Baz"); +var_dump($rc1->getInterfaceNames()); +?> +--EXPECT-- +array(2) { + [0]=> + string(3) "Foo" + [1]=> + string(3) "Bar" +} diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt new file mode 100644 index 0000000..4213600 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getInterfaces_001.phpt @@ -0,0 +1,311 @@ +--TEST-- +ReflectionClass::getInterfaces() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A0 {} +class B0 extends A0 {} +abstract class A1 {} +class B1 extends A1 {} + +interface I0 {} +interface I1 {} +interface I2 {} +interface I3 {} +interface I4 extends I3 {} +interface I5 extends I4 {} +interface I6 extends I5, I1, I2 {} +interface I7 extends I6 {} + +class C0 implements I0 {} +class C1 implements I1, I3 {} +class C2 extends C1 {} +class C3 extends C2 implements I1 {} +class C4 extends C3 implements I2 {} +class C5 extends C4 implements I7 {} +class C6 implements I1, I2, I3, I4, I5, I6, I7 {} + + +$classes = array( 'A0', 'A1', 'B0', 'B1', + 'I0', 'I1', 'I2', 'I3', 'I4', 'I5', 'I6', 'I7', + 'C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6' ); + +foreach ($classes as $class) { + echo "---( Interfaces implemented by $class )---\n "; + $rc = new ReflectionClass($class); + $interfaces = $rc->getInterfaces(); + // Sort interfaces so that tests do not fail because of wrong order. + ksort($interfaces); + print_r($interfaces); +} + +?> +--EXPECTF-- +---( Interfaces implemented by A0 )--- + Array +( +) +---( Interfaces implemented by A1 )--- + Array +( +) +---( Interfaces implemented by B0 )--- + Array +( +) +---( Interfaces implemented by B1 )--- + Array +( +) +---( Interfaces implemented by I0 )--- + Array +( +) +---( Interfaces implemented by I1 )--- + Array +( +) +---( Interfaces implemented by I2 )--- + Array +( +) +---( Interfaces implemented by I3 )--- + Array +( +) +---( Interfaces implemented by I4 )--- + Array +( + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + +) +---( Interfaces implemented by I5 )--- + Array +( + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + + [I4] => ReflectionClass Object + ( + [name] => I4 + ) + +) +---( Interfaces implemented by I6 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I2] => ReflectionClass Object + ( + [name] => I2 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + + [I4] => ReflectionClass Object + ( + [name] => I4 + ) + + [I5] => ReflectionClass Object + ( + [name] => I5 + ) + +) +---( Interfaces implemented by I7 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I2] => ReflectionClass Object + ( + [name] => I2 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + + [I4] => ReflectionClass Object + ( + [name] => I4 + ) + + [I5] => ReflectionClass Object + ( + [name] => I5 + ) + + [I6] => ReflectionClass Object + ( + [name] => I6 + ) + +) +---( Interfaces implemented by C0 )--- + Array +( + [I0] => ReflectionClass Object + ( + [name] => I0 + ) + +) +---( Interfaces implemented by C1 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + +) +---( Interfaces implemented by C2 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + +) +---( Interfaces implemented by C3 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + +) +---( Interfaces implemented by C4 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I2] => ReflectionClass Object + ( + [name] => I2 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + +) +---( Interfaces implemented by C5 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I2] => ReflectionClass Object + ( + [name] => I2 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + + [I4] => ReflectionClass Object + ( + [name] => I4 + ) + + [I5] => ReflectionClass Object + ( + [name] => I5 + ) + + [I6] => ReflectionClass Object + ( + [name] => I6 + ) + + [I7] => ReflectionClass Object + ( + [name] => I7 + ) + +) +---( Interfaces implemented by C6 )--- + Array +( + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I2] => ReflectionClass Object + ( + [name] => I2 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + + [I4] => ReflectionClass Object + ( + [name] => I4 + ) + + [I5] => ReflectionClass Object + ( + [name] => I5 + ) + + [I6] => ReflectionClass Object + ( + [name] => I6 + ) + + [I7] => ReflectionClass Object + ( + [name] => I7 + ) + +) diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt new file mode 100644 index 0000000..328a7c3 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getInterfaces_002.phpt @@ -0,0 +1,53 @@ +--TEST-- +ReflectionClass::getInterfaces() - interface ordering. +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +interface I1 {} +interface I2 {} +interface I3 {} +interface I4 extends I3 {} +interface I5 extends I4 {} +interface I6 extends I5, I1, I2 {} +interface I7 extends I6 {} + +$rc = new ReflectionClass('I7'); +$interfaces = $rc->getInterfaces(); +print_r($interfaces); +?> +--EXPECTF-- +Array +( + [I6] => ReflectionClass Object + ( + [name] => I6 + ) + + [I2] => ReflectionClass Object + ( + [name] => I2 + ) + + [I1] => ReflectionClass Object + ( + [name] => I1 + ) + + [I4] => ReflectionClass Object + ( + [name] => I4 + ) + + [I3] => ReflectionClass Object + ( + [name] => I3 + ) + + [I5] => ReflectionClass Object + ( + [name] => I5 + ) + +)
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt new file mode 100644 index 0000000..74044f7 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getInterfaces_003.phpt @@ -0,0 +1,69 @@ +--TEST-- +ReflectionClass::getInterfaces() - odd ampersand behaviour. +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +echo "An object is in an array and is referenced. As expected, var_dumping the array shows '&':\n"; +$a = array(new stdclass); +$b =& $a[0]; +var_dump($a); + +echo "Naturally, this remains true if we modify the object:\n"; +$a[0]->x = 1; +var_dump($a); + + +echo "\n\nObtain the array of interfaces implemented by C.\n"; +interface I {} +class C implements I {} +$rc = new ReflectionClass('C'); +$a = $rc->getInterfaces(); +echo "The result is an array in which each element is an object (an instance of ReflectionClass)\n"; +echo "Var_dumping this array shows that the elements are referenced. By what?\n"; +var_dump($a); + +echo "Modify the object, and it is apparently no longer referenced.\n"; +$a['I']->x = 1; +var_dump($a); + +?> +--EXPECTF-- +An object is in an array and is referenced. As expected, var_dumping the array shows '&': +array(1) { + [0]=> + &object(stdClass)#%d (0) { + } +} +Naturally, this remains true if we modify the object: +array(1) { + [0]=> + &object(stdClass)#%d (1) { + ["x"]=> + int(1) + } +} + + +Obtain the array of interfaces implemented by C. +The result is an array in which each element is an object (an instance of ReflectionClass) +Var_dumping this array shows that the elements are referenced. By what? +array(1) { + ["I"]=> + &object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "I" + } +} +Modify the object, and it is apparently no longer referenced. +array(1) { + ["I"]=> + object(ReflectionClass)#%d (2) { + ["name"]=> + string(1) "I" + ["x"]=> + int(1) + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt b/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt new file mode 100644 index 0000000..f62d58c --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getInterfaces_004.phpt @@ -0,0 +1,27 @@ +--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_getMethod_001.phpt b/ext/reflection/tests/ReflectionClass_getMethod_001.phpt new file mode 100644 index 0000000..2f2d790 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getMethod_001.phpt @@ -0,0 +1,168 @@ +--TEST-- +ReflectionClass::getMethod() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class pubf { + public function f() {} + static public function s() {} +} +class subpubf extends pubf { +} + +class protf { + protected function f() {} + static protected function s() {} +} +class subprotf extends protf { +} + +class privf { + private function f() {} + static private function s() {} +} +class subprivf extends privf { +} + +$classes = array("pubf", "subpubf", "protf", "subprotf", + "privf", "subprivf"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + echo " --> Check for f(): "; + var_dump($rc->getMethod("f")); + echo " --> Check for s(): "; + var_dump($rc->getMethod("s")); + echo " --> Check for F(): "; + var_dump($rc->getMethod("F")); + echo " --> Check for doesntExist(): "; + try { + var_dump($rc->getMethod("doesntExist")); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECTF-- +Reflecting on class pubf: + --> Check for f(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for s(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for F(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for doesntExist(): Method doesntExist does not exist +Reflecting on class subpubf: + --> Check for f(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for s(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for F(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for doesntExist(): Method doesntExist does not exist +Reflecting on class protf: + --> Check for f(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for s(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for F(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for doesntExist(): Method doesntExist does not exist +Reflecting on class subprotf: + --> Check for f(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for s(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for F(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for doesntExist(): Method doesntExist does not exist +Reflecting on class privf: + --> Check for f(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for s(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for F(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for doesntExist(): Method doesntExist does not exist +Reflecting on class subprivf: + --> Check for f(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for s(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for F(): object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for doesntExist(): Method doesntExist does not exist diff --git a/ext/reflection/tests/ReflectionClass_getMethod_002.phpt b/ext/reflection/tests/ReflectionClass_getMethod_002.phpt new file mode 100644 index 0000000..2baabde --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getMethod_002.phpt @@ -0,0 +1,74 @@ +--TEST-- +ReflectionClass::getMethod() - error cases +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + function f() {} +} + +$rc = new ReflectionClass("C"); +echo "Check invalid params:\n"; +try { + var_dump($rc->getMethod()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod("f", "f")); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod(1)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod(1.5)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod(true)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod(array(1,2,3))); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getMethod(new C)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + + +?> +--EXPECTF-- +Check invalid params: + +Warning: ReflectionClass::getMethod() expects exactly 1 parameter, 0 given in %s on line 9 +NULL + +Warning: ReflectionClass::getMethod() expects exactly 1 parameter, 2 given in %s on line 14 +NULL +Method does not exist +Method 1 does not exist +Method 1.5 does not exist +Method 1 does not exist + +Warning: ReflectionClass::getMethod() expects parameter 1 to be string, array given in %s on line 39 +NULL + +Warning: ReflectionClass::getMethod() expects parameter 1 to be string, object given in %s on line 44 +NULL
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getMethods_001.phpt b/ext/reflection/tests/ReflectionClass_getMethods_001.phpt new file mode 100644 index 0000000..ce5c980 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getMethods_001.phpt @@ -0,0 +1,140 @@ +--TEST-- +ReflectionClass::getMethods() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class pubf { + public function f() {} + static public function s() {} +} +class subpubf extends pubf { +} + +class protf { + protected function f() {} + static protected function s() {} +} +class subprotf extends protf { +} + +class privf { + private function f() {} + static private function s() {} +} +class subprivf extends privf { +} + +$classes = array("pubf", "subpubf", "protf", "subprotf", + "privf", "subprivf"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + var_dump($rc->getMethods()); +} + +?> +--EXPECTF-- +Reflecting on class pubf: +array(2) { + [0]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } +} +Reflecting on class subpubf: +array(2) { + [0]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } +} +Reflecting on class protf: +array(2) { + [0]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } +} +Reflecting on class subprotf: +array(2) { + [0]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } +} +Reflecting on class privf: +array(2) { + [0]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "privf" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" + } +} +Reflecting on class subprivf: +array(2) { + [0]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "f" + [%u|b%"class"]=> + %unicode|string%(5) "privf" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" + } +} diff --git a/ext/reflection/tests/ReflectionClass_getMethods_002.phpt b/ext/reflection/tests/ReflectionClass_getMethods_002.phpt new file mode 100644 index 0000000..b252225 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getMethods_002.phpt @@ -0,0 +1,18 @@ +--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 long, 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 new file mode 100644 index 0000000..435f5d2 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getMethods_003.phpt @@ -0,0 +1,191 @@ +--TEST-- +ReflectionClass::getMethods() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + public function pubf1() {} + public function pubf2() {} + private function privf1() {} + private function privf2() {} + static public function pubsf1() {} + static public function pubsf2() {} + static private function privsf1() {} + static private function privsf2() {} +} + +$rc = new ReflectionClass("C"); +$StaticFlag = 0x01; +$pubFlag = 0x100; +$privFlag = 0x400; + +echo "No methods:"; +var_dump($rc->getMethods(0)); + +echo "Public methods:"; +var_dump($rc->getMethods($pubFlag)); + +echo "Private methods:"; +var_dump($rc->getMethods($privFlag)); + +echo "Public or static methods:"; +var_dump($rc->getMethods($StaticFlag | $pubFlag)); + +echo "Private or static methods:"; +var_dump($rc->getMethods($StaticFlag | $privFlag)); + + +?> +--EXPECTF-- +No methods:array(0) { +} +Public methods:array(4) { + [0]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(5) "pubf1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(5) "pubf2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "pubsf1" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "pubsf2" + ["class"]=> + string(1) "C" + } +} +Private methods:array(4) { + [0]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "privf1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "privf2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(7) "privsf1" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(7) "privsf2" + ["class"]=> + string(1) "C" + } +} +Public or static methods:array(6) { + [0]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(5) "pubf1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(5) "pubf2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "pubsf1" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "pubsf2" + ["class"]=> + string(1) "C" + } + [4]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(7) "privsf1" + ["class"]=> + string(1) "C" + } + [5]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(7) "privsf2" + ["class"]=> + string(1) "C" + } +} +Private or static methods:array(6) { + [0]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "privf1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "privf2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "pubsf1" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(6) "pubsf2" + ["class"]=> + string(1) "C" + } + [4]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(7) "privsf1" + ["class"]=> + string(1) "C" + } + [5]=> + &object(ReflectionMethod)#%d (2) { + ["name"]=> + string(7) "privsf2" + ["class"]=> + string(1) "C" + } +} diff --git a/ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt b/ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt new file mode 100644 index 0000000..91a0a18 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getModifierNames_basic.phpt @@ -0,0 +1,139 @@ +--TEST-- +ReflectionClass::getModifierNames() basic tests +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--FILE-- +<?php + +class a {} +abstract class b {} +final class c {} + +class x +{ + function __construct() {} + function __destruct() {} + private function a() {} + private static function b() {} + protected function c() {} + protected static function d() {} + public function e() {} + public static function f() {} + final function g() {} + function h() {} +} + +abstract class y +{ + abstract function a(); + abstract protected function b(); +} + +function dump_modifierNames($class) { + $obj = new ReflectionClass($class); + var_dump($obj->getName(), Reflection::getModifierNames($obj->getModifiers())); +} + +function dump_methodModifierNames($class) { + $obj = new ReflectionClass($class); + foreach($obj->getMethods() as $method) { + var_dump($obj->getName() . "::" . $method->getName(), Reflection::getModifierNames($method->getModifiers())); + } +} + +dump_modifierNames('a'); +dump_modifierNames('b'); +dump_modifierNames('c'); + +dump_methodModifierNames('x'); +dump_methodModifierNames('y'); + +?> +==DONE== +--EXPECT-- +string(1) "a" +array(0) { +} +string(1) "b" +array(1) { + [0]=> + string(8) "abstract" +} +string(1) "c" +array(1) { + [0]=> + string(5) "final" +} +string(14) "x::__construct" +array(1) { + [0]=> + string(6) "public" +} +string(13) "x::__destruct" +array(1) { + [0]=> + string(6) "public" +} +string(4) "x::a" +array(1) { + [0]=> + string(7) "private" +} +string(4) "x::b" +array(2) { + [0]=> + string(7) "private" + [1]=> + string(6) "static" +} +string(4) "x::c" +array(1) { + [0]=> + string(9) "protected" +} +string(4) "x::d" +array(2) { + [0]=> + string(9) "protected" + [1]=> + string(6) "static" +} +string(4) "x::e" +array(1) { + [0]=> + string(6) "public" +} +string(4) "x::f" +array(2) { + [0]=> + string(6) "public" + [1]=> + string(6) "static" +} +string(4) "x::g" +array(2) { + [0]=> + string(5) "final" + [1]=> + string(6) "public" +} +string(4) "x::h" +array(1) { + [0]=> + string(6) "public" +} +string(4) "y::a" +array(2) { + [0]=> + string(8) "abstract" + [1]=> + string(6) "public" +} +string(4) "y::b" +array(2) { + [0]=> + string(8) "abstract" + [1]=> + string(9) "protected" +} +==DONE== diff --git a/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt new file mode 100644 index 0000000..65f23c9 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +ReflectionClass::getModifiers() +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--FILE-- +<?php + +class a {} +abstract class b {} +final class c {} +interface d {} +class e implements d {} +interface f extends d {} +class g extends b {} + +function dump_modifiers($class) { + $obj = new ReflectionClass($class); + var_dump($obj->getModifiers()); +} + +dump_modifiers('a'); +dump_modifiers('b'); +dump_modifiers('c'); +dump_modifiers('d'); +dump_modifiers('e'); +dump_modifiers('f'); +dump_modifiers('g'); + +?> +--EXPECT-- +int(0) +int(32) +int(64) +int(128) +int(524288) +int(524416) +int(0) diff --git a/ext/reflection/tests/ReflectionClass_getName_basic.phpt b/ext/reflection/tests/ReflectionClass_getName_basic.phpt new file mode 100644 index 0000000..158413f --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getName_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +ReflectionClass::getName() +--FILE-- +<?php +class TrickClass { + function __toString() { + //Return the name of another class + return "Exception"; + } +} + +$r1 = new ReflectionClass("stdClass"); + +$myInstance = new stdClass; +$r2 = new ReflectionClass($myInstance); + +$r3 = new ReflectionClass("TrickClass"); + +var_dump($r1->getName(), $r2->getName(), $r3->getName()); + +?> +--EXPECTF-- +string(8) "stdClass" +string(8) "stdClass" +string(10) "TrickClass" diff --git a/ext/reflection/tests/ReflectionClass_getName_error.phpt b/ext/reflection/tests/ReflectionClass_getName_error.phpt new file mode 100644 index 0000000..06cc415 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getName_error.phpt @@ -0,0 +1,16 @@ +--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_getName_error1.phpt b/ext/reflection/tests/ReflectionClass_getName_error1.phpt new file mode 100644 index 0000000..5590137 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getName_error1.phpt @@ -0,0 +1,8 @@ +--TEST-- +ReflectionClass::getName - forbid static invocation +--FILE-- +<?php +ReflectionClass::getName(); +?> +--EXPECTF-- +Fatal error: Non-static method ReflectionClass::getName() cannot be called statically in %s on line 2 diff --git a/ext/reflection/tests/ReflectionClass_getNamespaceName.phpt b/ext/reflection/tests/ReflectionClass_getNamespaceName.phpt new file mode 100644 index 0000000..1c46e06 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getNamespaceName.phpt @@ -0,0 +1,30 @@ +--TEST-- +ReflectionClass::getNamespaceName() +--FILE-- +<?php +namespace A\B; +class Foo { +} + +$function = new \ReflectionClass('stdClass'); +var_dump($function->inNamespace()); +var_dump($function->getName()); +var_dump($function->getNamespaceName()); +var_dump($function->getShortName()); + +$function = new \ReflectionClass('A\\B\\Foo'); +var_dump($function->inNamespace()); +var_dump($function->getName()); +var_dump($function->getNamespaceName()); +var_dump($function->getShortName()); +?> +--EXPECT-- +bool(false) +string(8) "stdClass" +string(0) "" +string(8) "stdClass" +bool(true) +string(7) "A\B\Foo" +string(3) "A\B" +string(3) "Foo" + diff --git a/ext/reflection/tests/ReflectionClass_getParentClass.phpt b/ext/reflection/tests/ReflectionClass_getParentClass.phpt new file mode 100644 index 0000000..46884ca --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getParentClass.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionClass::getParentClass() +--CREDITS-- +Michelangelo van Dam <dragonbe@gmail.com> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php + +class Foo {} + +class Bar extends Foo {} + +$rc1 = new ReflectionClass("Bar"); +var_dump($rc1->getParentClass()); +?> + +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(3) "Foo" +} diff --git a/ext/reflection/tests/ReflectionClass_getParentClass_001.phpt b/ext/reflection/tests/ReflectionClass_getParentClass_001.phpt new file mode 100644 index 0000000..be50dbb --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getParentClass_001.phpt @@ -0,0 +1,38 @@ +--TEST-- +ReflectionClass::getParentClass() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A {} +class B extends A {} + +$rc = new ReflectionClass('B'); +$parent = $rc->getParentClass(); +$grandParent = $parent->getParentClass(); +var_dump($parent, $grandParent); + +echo "\nTest bad params:\n"; +var_dump($rc->getParentClass(null)); +var_dump($rc->getParentClass('x')); +var_dump($rc->getParentClass('x', 123)); + +?> +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "A" +} +bool(false) + +Test bad params: + +Warning: ReflectionClass::getParentClass() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionClass::getParentClass() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionClass::getParentClass() expects exactly 0 parameters, 2 given in %s on line %d +NULL diff --git a/ext/reflection/tests/ReflectionClass_getProperties_001.phpt b/ext/reflection/tests/ReflectionClass_getProperties_001.phpt new file mode 100644 index 0000000..b4f99ca --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperties_001.phpt @@ -0,0 +1,126 @@ +--TEST-- +ReflectionClass::getProperties() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class pubf { + public $a; + static public $s; +} +class subpubf extends pubf { +} + +class protf { + protected $a; + static protected $s; +} +class subprotf extends protf { +} + +class privf { + private $a; + static private $s; +} +class subprivf extends privf { +} + +$classes = array("pubf", "subpubf", "protf", "subprotf", + "privf", "subprivf"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + var_dump($rc->getProperties()); +} + +?> +--EXPECTF-- +Reflecting on class pubf: +array(2) { + [0]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } +} +Reflecting on class subpubf: +array(2) { + [0]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" + } +} +Reflecting on class protf: +array(2) { + [0]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } +} +Reflecting on class subprotf: +array(2) { + [0]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" + } +} +Reflecting on class privf: +array(2) { + [0]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(5) "privf" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" + } +} +Reflecting on class subprivf: +array(0) { +} diff --git a/ext/reflection/tests/ReflectionClass_getProperties_002.phpt b/ext/reflection/tests/ReflectionClass_getProperties_002.phpt new file mode 100644 index 0000000..c21cff2 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperties_002.phpt @@ -0,0 +1,17 @@ +--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 long, 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 new file mode 100644 index 0000000..b4f9a77 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperties_003.phpt @@ -0,0 +1,189 @@ +--TEST-- +ReflectionClass::getProperties() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + public $pub1; + public $pub2; + private $priv1; + private $priv2; + static public $pubs; + static public $pubs2; + static private $privs1; + static private $privs2; +} + +$rc = new ReflectionClass("C"); +$StaticFlag = 0x01; +$pubFlag = 0x100; +$privFlag = 0x400; + +echo "No properties:"; +var_dump($rc->getProperties(0)); + +echo "Public properties:"; +var_dump($rc->getProperties($pubFlag)); + +echo "Private properties:"; +var_dump($rc->getProperties($privFlag)); + +echo "Public or static properties:"; +var_dump($rc->getProperties($StaticFlag | $pubFlag)); + +echo "Private or static properties:"; +var_dump($rc->getProperties($StaticFlag | $privFlag)); +?> +--EXPECTF-- +No properties:array(0) { +} +Public properties:array(4) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pub1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pub2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pubs" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "pubs2" + ["class"]=> + string(1) "C" + } +} +Private properties:array(4) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "priv1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "priv2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(6) "privs1" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(6) "privs2" + ["class"]=> + string(1) "C" + } +} +Public or static properties:array(6) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pub1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pub2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pubs" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "pubs2" + ["class"]=> + string(1) "C" + } + [4]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(6) "privs1" + ["class"]=> + string(1) "C" + } + [5]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(6) "privs2" + ["class"]=> + string(1) "C" + } +} +Private or static properties:array(6) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "priv1" + ["class"]=> + string(1) "C" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "priv2" + ["class"]=> + string(1) "C" + } + [2]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "pubs" + ["class"]=> + string(1) "C" + } + [3]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "pubs2" + ["class"]=> + string(1) "C" + } + [4]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(6) "privs1" + ["class"]=> + string(1) "C" + } + [5]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(6) "privs2" + ["class"]=> + string(1) "C" + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getProperty_001.phpt b/ext/reflection/tests/ReflectionClass_getProperty_001.phpt new file mode 100644 index 0000000..9e174b7 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperty_001.phpt @@ -0,0 +1,146 @@ +--TEST-- +ReflectionClass::getProperty() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class pubf { + public $a; + static public $s; +} +class subpubf extends pubf { +} + +class protf { + protected $a; + static protected $s; +} +class subprotf extends protf { +} + +class privf { + private $a; + static protected $s; +} +class subprivf extends privf { +} + +$classes = array("pubf", "subpubf", "protf", "subprotf", + "privf", "subprivf"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + try { + echo " --> Check for s: "; + var_dump($rc->getProperty("s")); + } catch (exception $e) { + echo $e->getMessage() . "\n"; + } + try { + echo " --> Check for a: "; + var_dump($rc->getProperty("a")); + } catch (exception $e) { + echo $e->getMessage() . "\n"; + } + try { + echo " --> Check for A: "; + var_dump($rc->getProperty("A")); + } catch (exception $e) { + echo $e->getMessage() . "\n"; + } + try { + echo " --> Check for doesntExist: "; + var_dump($rc->getProperty("doesntExist")); + } catch (exception $e) { + echo $e->getMessage() . "\n"; + } + +} +?> +--EXPECTF-- +Reflecting on class pubf: + --> Check for s: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for a: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for A: Property A does not exist + --> Check for doesntExist: Property doesntExist does not exist +Reflecting on class subpubf: + --> Check for s: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for a: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(4) "pubf" +} + --> Check for A: Property A does not exist + --> Check for doesntExist: Property doesntExist does not exist +Reflecting on class protf: + --> Check for s: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for a: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for A: Property A does not exist + --> Check for doesntExist: Property doesntExist does not exist +Reflecting on class subprotf: + --> Check for s: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for a: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(5) "protf" +} + --> Check for A: Property A does not exist + --> Check for doesntExist: Property doesntExist does not exist +Reflecting on class privf: + --> Check for s: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for a: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "a" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for A: Property A does not exist + --> Check for doesntExist: Property doesntExist does not exist +Reflecting on class subprivf: + --> Check for s: object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(1) "s" + [%u|b%"class"]=> + %unicode|string%(5) "privf" +} + --> Check for a: Property a does not exist + --> Check for A: Property A does not exist + --> Check for doesntExist: Property doesntExist does not exist diff --git a/ext/reflection/tests/ReflectionClass_getProperty_002.phpt b/ext/reflection/tests/ReflectionClass_getProperty_002.phpt new file mode 100644 index 0000000..be7bb53 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperty_002.phpt @@ -0,0 +1,72 @@ +--TEST-- +ReflectionClass::getProperty() - error cases +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + public $a; +} + +$rc = new ReflectionClass("C"); +echo "Check invalid params:\n"; +try { + var_dump($rc->getProperty()); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty("a", "a")); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty(null)); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty(1)); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty(1.5)); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty(true)); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty(array(1,2,3))); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getProperty(new C)); +} catch (exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +Check invalid params: + +Warning: ReflectionClass::getProperty() expects exactly 1 parameter, 0 given in %s on line 9 +NULL + +Warning: ReflectionClass::getProperty() expects exactly 1 parameter, 2 given in %s on line 14 +NULL +Property does not exist +Property 1 does not exist +Property 1.5 does not exist +Property 1 does not exist + +Warning: ReflectionClass::getProperty() expects parameter 1 to be string, array given in %s on line 39 +NULL + +Warning: ReflectionClass::getProperty() expects parameter 1 to be string, object given in %s on line 44 +NULL
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_getProperty_003.phpt b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt new file mode 100644 index 0000000..515d986 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt @@ -0,0 +1,251 @@ +--TEST-- +ReflectionClass::getProperty() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A { + static public $pubC = "pubC in A"; + static protected $protC = "protC in A"; + static private $privC = "privC in A"; + + static public $pubA = "pubA in A"; + static protected $protA = "protA in A"; + static private $privA = "privA in A"; +} + +class B extends A { + static public $pubC = "pubC in B"; + static protected $protC = "protC in B"; + static private $privC = "privC in B"; + + static public $pubB = "pubB in B"; + static protected $protB = "protB in B"; + static private $privB = "privB in B"; +} + +class C extends B { + static public $pubC = "pubC in C"; + static protected $protC = "protC in C"; + static private $privC = "privC in C"; +} + +class X { + static public $pubC = "pubC in X"; + static protected $protC = "protC in X"; + static private $privC = "privC in X"; +} + +$myC = new C; +$rc = new ReflectionClass("C"); + +function showInfo($name) { + global $rc, $myC; + echo "--- (Reflecting on $name) ---\n"; + try { + $rp = $rc->getProperty($name); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + return; + } + try { + var_dump($rp); + var_dump($rp->getValue($myC)); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + return; + } +} + + +showInfo("pubA"); +showInfo("protA"); +showInfo("privA"); + +showInfo("pubB"); +showInfo("protB"); +showInfo("privB"); + +showInfo("pubC"); +showInfo("protC"); +showInfo("privC"); +showInfo("doesntExist"); + +showInfo("A::pubC"); +showInfo("A::protC"); +showInfo("A::privC"); + +showInfo("B::pubC"); +showInfo("B::protC"); +showInfo("B::privC"); + +showInfo("c::pubC"); +showInfo("c::PUBC"); +showInfo("C::pubC"); +showInfo("C::protC"); +showInfo("C::privC"); + +showInfo("X::pubC"); +showInfo("X::protC"); +showInfo("X::privC"); +showInfo("X::doesntExist"); + +showInfo("doesntexist::doesntExist"); + +?> +--EXPECTF-- +--- (Reflecting on pubA) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubA" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +%unicode|string%(9) "pubA in A" +--- (Reflecting on protA) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protA" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +Cannot access non-public member C::protA +--- (Reflecting on privA) --- +Property privA does not exist +--- (Reflecting on pubB) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubB" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +%unicode|string%(9) "pubB in B" +--- (Reflecting on protB) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protB" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +Cannot access non-public member C::protB +--- (Reflecting on privB) --- +Property privB does not exist +--- (Reflecting on pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::protC +--- (Reflecting on privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::privC +--- (Reflecting on doesntExist) --- +Property doesntExist does not exist +--- (Reflecting on A::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +%unicode|string%(9) "pubC in A" +--- (Reflecting on A::protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +Cannot access non-public member A::protC +--- (Reflecting on A::privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +Cannot access non-public member A::privC +--- (Reflecting on B::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +%unicode|string%(9) "pubC in B" +--- (Reflecting on B::protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +Cannot access non-public member B::protC +--- (Reflecting on B::privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +Cannot access non-public member B::privC +--- (Reflecting on c::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on c::PUBC) --- +Property PUBC does not exist +--- (Reflecting on C::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on C::protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::protC +--- (Reflecting on C::privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::privC +--- (Reflecting on X::pubC) --- +Fully qualified property name X::pubC does not specify a base class of C +--- (Reflecting on X::protC) --- +Fully qualified property name X::protC does not specify a base class of C +--- (Reflecting on X::privC) --- +Fully qualified property name X::privC does not specify a base class of C +--- (Reflecting on X::doesntExist) --- +Fully qualified property name X::doesntExist does not specify a base class of C +--- (Reflecting on doesntexist::doesntExist) --- +Class doesntexist does not exist diff --git a/ext/reflection/tests/ReflectionClass_getProperty_004.phpt b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt new file mode 100644 index 0000000..1070d57 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt @@ -0,0 +1,251 @@ +--TEST-- +ReflectionClass::getProperty() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A { + public $pubC = "pubC in A"; + protected $protC = "protC in A"; + private $privC = "privC in A"; + + public $pubA = "pubA in A"; + protected $protA = "protA in A"; + private $privA = "privA in A"; +} + +class B extends A { + public $pubC = "pubC in B"; + protected $protC = "protC in B"; + private $privC = "privC in B"; + + public $pubB = "pubB in B"; + protected $protB = "protB in B"; + private $privB = "privB in B"; +} + +class C extends B { + public $pubC = "pubC in C"; + protected $protC = "protC in C"; + private $privC = "privC in C"; +} + +class X { + public $pubC = "pubC in X"; + protected $protC = "protC in X"; + private $privC = "privC in X"; +} + +$myC = new C; +$rc = new ReflectionClass("C"); + +function showInfo($name) { + global $rc, $myC; + echo "--- (Reflecting on $name) ---\n"; + try { + $rp = $rc->getProperty($name); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + return; + } + try { + var_dump($rp); + var_dump($rp->getValue($myC)); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + return; + } +} + + +showInfo("pubA"); +showInfo("protA"); +showInfo("privA"); + +showInfo("pubB"); +showInfo("protB"); +showInfo("privB"); + +showInfo("pubC"); +showInfo("protC"); +showInfo("privC"); +showInfo("doesntExist"); + +showInfo("A::pubC"); +showInfo("A::protC"); +showInfo("A::privC"); + +showInfo("B::pubC"); +showInfo("B::protC"); +showInfo("B::privC"); + +showInfo("c::pubC"); +showInfo("c::PUBC"); +showInfo("C::pubC"); +showInfo("C::protC"); +showInfo("C::privC"); + +showInfo("X::pubC"); +showInfo("X::protC"); +showInfo("X::privC"); +showInfo("X::doesntExist"); + +showInfo("doesntexist::doesntExist"); + +?> +--EXPECTF-- +--- (Reflecting on pubA) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubA" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +%unicode|string%(9) "pubA in A" +--- (Reflecting on protA) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protA" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +Cannot access non-public member C::protA +--- (Reflecting on privA) --- +Property privA does not exist +--- (Reflecting on pubB) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubB" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +%unicode|string%(9) "pubB in B" +--- (Reflecting on protB) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protB" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +Cannot access non-public member C::protB +--- (Reflecting on privB) --- +Property privB does not exist +--- (Reflecting on pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::protC +--- (Reflecting on privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::privC +--- (Reflecting on doesntExist) --- +Property doesntExist does not exist +--- (Reflecting on A::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on A::protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +Cannot access non-public member A::protC +--- (Reflecting on A::privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "A" +} +Cannot access non-public member A::privC +--- (Reflecting on B::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on B::protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +Cannot access non-public member B::protC +--- (Reflecting on B::privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "B" +} +Cannot access non-public member B::privC +--- (Reflecting on c::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on c::PUBC) --- +Property PUBC does not exist +--- (Reflecting on C::pubC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(4) "pubC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +%unicode|string%(9) "pubC in C" +--- (Reflecting on C::protC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "protC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::protC +--- (Reflecting on C::privC) --- +object(ReflectionProperty)#%d (2) { + [%u|b%"name"]=> + %unicode|string%(5) "privC" + [%u|b%"class"]=> + %unicode|string%(1) "C" +} +Cannot access non-public member C::privC +--- (Reflecting on X::pubC) --- +Fully qualified property name X::pubC does not specify a base class of C +--- (Reflecting on X::protC) --- +Fully qualified property name X::protC does not specify a base class of C +--- (Reflecting on X::privC) --- +Fully qualified property name X::privC does not specify a base class of C +--- (Reflecting on X::doesntExist) --- +Fully qualified property name X::doesntExist does not specify a base class of C +--- (Reflecting on doesntexist::doesntExist) --- +Class doesntexist does not exist diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt new file mode 100644 index 0000000..ffd81ff --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt @@ -0,0 +1,69 @@ +--TEST-- +ReflectionClass::getStaticPropertyValue() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?> +--FILE-- +<?php +class A { + static private $privateOverridden = "original private"; + static protected $protectedOverridden = "original protected"; + static public $publicOverridden = "original public"; +} + +class B extends A { + static private $privateOverridden = "changed private"; + static protected $protectedOverridden = "changed protected"; + static public $publicOverridden = "changed public"; +} + +echo "Retrieving static values from A:\n"; +$rcA = new ReflectionClass('A'); +var_dump($rcA->getStaticPropertyValue("privateOverridden", "default value")); +var_dump($rcA->getStaticPropertyValue("\0A\0privateOverridden")); +var_dump($rcA->getStaticPropertyValue("protectedOverridden", "default value")); +var_dump($rcA->getStaticPropertyValue("\0*\0protectedOverridden")); +var_dump($rcA->getStaticPropertyValue("publicOverridden")); + +echo "\nRetrieving static values from B:\n"; +$rcB = new ReflectionClass('B'); +var_dump($rcB->getStaticPropertyValue("\0A\0privateOverridden")); +var_dump($rcB->getStaticPropertyValue("\0B\0privateOverridden")); +var_dump($rcB->getStaticPropertyValue("\0*\0protectedOverridden")); +var_dump($rcB->getStaticPropertyValue("publicOverridden")); + +echo "\nRetrieving non-existent values from A with no default value:\n"; +try { + var_dump($rcA->getStaticPropertyValue("protectedOverridden")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump($rcA->getStaticPropertyValue("privateOverridden")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Retrieving static values from A: +string(13) "default value" +string(16) "original private" +string(13) "default value" +string(18) "original protected" +string(15) "original public" + +Retrieving static values from B: +string(16) "original private" +string(15) "changed private" +string(17) "changed protected" +string(14) "changed public" + +Retrieving non-existent values from A with no default value: +Class A does not have a property named protectedOverridden +Class A does not have a property named privateOverridden diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt new file mode 100644 index 0000000..c299412 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt @@ -0,0 +1,61 @@ +--TEST-- +ReflectionClass::getStaticPropertyValue() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?> +--FILE-- +<?php +class A { + static private $privateOverridden = "original private"; + static protected $protectedOverridden = "original protected"; + static public $publicOverridden = "original public"; +} + +class B extends A { + static private $privateOverridden = "changed private"; + static protected $protectedOverridden = "changed protected"; + static public $publicOverridden = "changed public"; +} + +echo "Retrieving static values from A:\n"; +$rcA = new ReflectionClass('A'); +var_dump($rcA->getStaticPropertyValue("privateOverridden", "default value")); +var_dump($rcA->getStaticPropertyValue("\0A\0privateOverridden")); +var_dump($rcA->getStaticPropertyValue("protectedOverridden", "default value")); +var_dump($rcA->getStaticPropertyValue("\0*\0protectedOverridden")); +var_dump($rcA->getStaticPropertyValue("publicOverridden")); + +echo "\nRetrieving static values from B:\n"; +$rcB = new ReflectionClass('B'); +var_dump($rcB->getStaticPropertyValue("\0A\0privateOverridden")); +var_dump($rcB->getStaticPropertyValue("\0B\0privateOverridden")); +var_dump($rcB->getStaticPropertyValue("\0*\0protectedOverridden")); +var_dump($rcB->getStaticPropertyValue("publicOverridden")); + +echo "\nRetrieving non-existent values from A with no default value:\n"; +try { + var_dump($rcA->getStaticPropertyValue("protectedOverridden")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump($rcA->getStaticPropertyValue("privateOverridden")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Retrieving static values from A: +string(13) "default value" + +Fatal error: Uncaught exception 'ReflectionException' with message 'Class A does not have a property named ' in %sReflectionClass_getStaticPropertyValue_001_2_4.php:%d +Stack trace: +#0 %sReflectionClass_getStaticPropertyValue_001_2_4.php(%d): ReflectionClass->getStaticPropertyValue('?A?privateOverr...') +#1 {main} + thrown in %sReflectionClass_getStaticPropertyValue_001_2_4.php on line %d diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt new file mode 100644 index 0000000..36b4744 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_002.phpt @@ -0,0 +1,52 @@ +--TEST-- +ReflectionClass::getStaticPropertyValue() - bad params +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + public static $x; +} + +$rc = new ReflectionClass('C'); +try { + var_dump($rc->getStaticPropertyValue("x", "default value", 'blah')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getStaticPropertyValue()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getStaticPropertyValue(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getStaticPropertyValue(1.5, 'def')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->getStaticPropertyValue(array(1,2,3))); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + + +?> +--EXPECTF-- + +Warning: ReflectionClass::getStaticPropertyValue() expects at most 2 parameters, 3 given in %s on line 8 +NULL + +Warning: ReflectionClass::getStaticPropertyValue() expects at least 1 parameter, 0 given in %s on line 13 +NULL +Class C does not have a property named +string(3) "def" + +Warning: ReflectionClass::getStaticPropertyValue() expects parameter 1 to be string, array given in %s on line 28 +NULL
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_hasConstant_001.phpt b/ext/reflection/tests/ReflectionClass_hasConstant_001.phpt new file mode 100644 index 0000000..6e6d434 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasConstant_001.phpt @@ -0,0 +1,36 @@ +--TEST-- +ReflectionClass::hasConstant() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + const myConst = 1; +} + +class D extends C { +} + + +$rc = new ReflectionClass("C"); +echo "Check existing constant: "; +var_dump($rc->hasConstant("myConst")); +echo "Check existing constant, different case: "; +var_dump($rc->hasConstant("MyCoNsT")); +echo "Check absent constant: "; +var_dump($rc->hasConstant("doesntExist")); + + +$rd = new ReflectionClass("D"); +echo "Check inherited constant: "; +var_dump($rd->hasConstant("myConst")); +echo "Check absent constant: "; +var_dump($rd->hasConstant("doesntExist")); +?> +--EXPECTF-- +Check existing constant: bool(true) +Check existing constant, different case: bool(false) +Check absent constant: bool(false) +Check inherited constant: bool(true) +Check absent constant: bool(false)
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_hasConstant_002.phpt b/ext/reflection/tests/ReflectionClass_hasConstant_002.phpt new file mode 100644 index 0000000..a0a76f0 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasConstant_002.phpt @@ -0,0 +1,40 @@ +--TEST-- +ReflectionClass::hasConstant() - error cases +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + const myConst = 1; +} + +$rc = new ReflectionClass("C"); +echo "Check invalid params:\n"; +var_dump($rc->hasConstant()); +var_dump($rc->hasConstant("myConst", "myConst")); +var_dump($rc->hasConstant(null)); +var_dump($rc->hasConstant(1)); +var_dump($rc->hasConstant(1.5)); +var_dump($rc->hasConstant(true)); +var_dump($rc->hasConstant(array(1,2,3))); +var_dump($rc->hasConstant(new C)); +?> +--EXPECTF-- +Check invalid params: + +Warning: ReflectionClass::hasConstant() expects exactly 1 parameter, 0 given in %s on line 8 +NULL + +Warning: ReflectionClass::hasConstant() expects exactly 1 parameter, 2 given in %s on line 9 +NULL +bool(false) +bool(false) +bool(false) +bool(false) + +Warning: ReflectionClass::hasConstant() expects parameter 1 to be string, array given in %s on line 14 +NULL + +Warning: ReflectionClass::hasConstant() expects parameter 1 to be string, object given in %s on line 15 +NULL
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt b/ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt new file mode 100644 index 0000000..0ff2523 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasConstant_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionClass::hasConstant() +--CREDITS-- +Marc Veldman <marc@ibuildings.nl> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php +//New instance of class C - defined below +$rc = new ReflectionClass("C"); + +//Check if C has constant foo +var_dump($rc->hasConstant('foo')); + +//C should not have constant bar +var_dump($rc->hasConstant('bar')); + +Class C { + const foo=1; +} +?> +--EXPECTF-- +bool(true) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_hasMethod_001.phpt b/ext/reflection/tests/ReflectionClass_hasMethod_001.phpt new file mode 100644 index 0000000..81614bd --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasMethod_001.phpt @@ -0,0 +1,75 @@ +--TEST-- +ReflectionClass::hasMethod() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class pubf { + public function f() {} + static public function s() {} +} +class subpubf extends pubf { +} + +class protf { + protected function f() {} + static protected function s() {} +} +class subprotf extends protf { +} + +class privf { + private function f() {} + static private function s() {} +} +class subprivf extends privf { +} + +$classes = array("pubf", "subpubf", "protf", "subprotf", + "privf", "subprivf"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + echo " --> Check for f(): "; + var_dump($rc->hasMethod("f")); + echo " --> Check for s(): "; + var_dump($rc->hasMethod("s")); + echo " --> Check for F(): "; + var_dump($rc->hasMethod("F")); + echo " --> Check for doesntExist(): "; + var_dump($rc->hasMethod("doesntExist")); +} +?> +--EXPECTF-- +Reflecting on class pubf: + --> Check for f(): bool(true) + --> Check for s(): bool(true) + --> Check for F(): bool(true) + --> Check for doesntExist(): bool(false) +Reflecting on class subpubf: + --> Check for f(): bool(true) + --> Check for s(): bool(true) + --> Check for F(): bool(true) + --> Check for doesntExist(): bool(false) +Reflecting on class protf: + --> Check for f(): bool(true) + --> Check for s(): bool(true) + --> Check for F(): bool(true) + --> Check for doesntExist(): bool(false) +Reflecting on class subprotf: + --> Check for f(): bool(true) + --> Check for s(): bool(true) + --> Check for F(): bool(true) + --> Check for doesntExist(): bool(false) +Reflecting on class privf: + --> Check for f(): bool(true) + --> Check for s(): bool(true) + --> Check for F(): bool(true) + --> Check for doesntExist(): bool(false) +Reflecting on class subprivf: + --> Check for f(): bool(true) + --> Check for s(): bool(true) + --> Check for F(): bool(true) + --> Check for doesntExist(): bool(false) +
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_hasMethod_002.phpt b/ext/reflection/tests/ReflectionClass_hasMethod_002.phpt new file mode 100644 index 0000000..63fe879 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasMethod_002.phpt @@ -0,0 +1,40 @@ +--TEST-- +ReflectionClass::hasMethod() - error cases +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + function f() {} +} + +$rc = new ReflectionClass("C"); +echo "Check invalid params:\n"; +var_dump($rc->hasMethod()); +var_dump($rc->hasMethod("f", "f")); +var_dump($rc->hasMethod(null)); +var_dump($rc->hasMethod(1)); +var_dump($rc->hasMethod(1.5)); +var_dump($rc->hasMethod(true)); +var_dump($rc->hasMethod(array(1,2,3))); +var_dump($rc->hasMethod(new C)); +?> +--EXPECTF-- +Check invalid params: + +Warning: ReflectionClass::hasMethod() expects exactly 1 parameter, 0 given in %s on line 8 +NULL + +Warning: ReflectionClass::hasMethod() expects exactly 1 parameter, 2 given in %s on line 9 +NULL +bool(false) +bool(false) +bool(false) +bool(false) + +Warning: ReflectionClass::hasMethod() expects parameter 1 to be string, array given in %s on line 14 +NULL + +Warning: ReflectionClass::hasMethod() expects parameter 1 to be string, object given in %s on line 15 +NULL diff --git a/ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt b/ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt new file mode 100644 index 0000000..fa4ee48 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasMethod_basic.phpt @@ -0,0 +1,57 @@ +--TEST-- +ReflectionClass::hasMethod() +--CREDITS-- +Marc Veldman <marc@ibuildings.nl> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php +//New instance of class C - defined below +$rc = new ReflectionClass("C"); + +//Check if C has public method publicFoo +var_dump($rc->hasMethod('publicFoo')); + +//Check if C has protected method protectedFoo +var_dump($rc->hasMethod('protectedFoo')); + +//Check if C has private method privateFoo +var_dump($rc->hasMethod('privateFoo')); + +//Check if C has static method staticFoo +var_dump($rc->hasMethod('staticFoo')); + +//C should not have method bar +var_dump($rc->hasMethod('bar')); + +//Method names are case insensitive +var_dump($rc->hasMethod('PUBLICfOO')); + +Class C { + public function publicFoo() + { + return true; + } + + protected function protectedFoo() + { + return true; + } + + private function privateFoo() + { + return true; + } + + static function staticFoo() + { + return true; + } +} +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionClass_hasProperty_001.phpt b/ext/reflection/tests/ReflectionClass_hasProperty_001.phpt new file mode 100644 index 0000000..88c4cd5 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasProperty_001.phpt @@ -0,0 +1,75 @@ +--TEST-- +ReflectionClass::hasProperty() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class pubf { + public $a; + static public $s; +} +class subpubf extends pubf { +} + +class protf { + protected $a; + static protected $s; +} +class subprotf extends protf { +} + +class privf { + private $a; + static protected $s; +} +class subprivf extends privf { +} + +$classes = array("pubf", "subpubf", "protf", "subprotf", + "privf", "subprivf"); +foreach($classes as $class) { + echo "Reflecting on class $class: \n"; + $rc = new ReflectionClass($class); + echo " --> Check for s: "; + var_dump($rc->hasProperty("s")); + echo " --> Check for a: "; + var_dump($rc->hasProperty("a")); + echo " --> Check for A: "; + var_dump($rc->hasProperty("A")); + echo " --> Check for doesntExist: "; + var_dump($rc->hasProperty("doesntExist")); +} +?> +--EXPECTF-- +Reflecting on class pubf: + --> Check for s: bool(true) + --> Check for a: bool(true) + --> Check for A: bool(false) + --> Check for doesntExist: bool(false) +Reflecting on class subpubf: + --> Check for s: bool(true) + --> Check for a: bool(true) + --> Check for A: bool(false) + --> Check for doesntExist: bool(false) +Reflecting on class protf: + --> Check for s: bool(true) + --> Check for a: bool(true) + --> Check for A: bool(false) + --> Check for doesntExist: bool(false) +Reflecting on class subprotf: + --> Check for s: bool(true) + --> Check for a: bool(true) + --> Check for A: bool(false) + --> Check for doesntExist: bool(false) +Reflecting on class privf: + --> Check for s: bool(true) + --> Check for a: bool(true) + --> Check for A: bool(false) + --> Check for doesntExist: bool(false) +Reflecting on class subprivf: + --> Check for s: bool(true) + --> Check for a: bool(false) + --> Check for A: bool(false) + --> Check for doesntExist: bool(false) + diff --git a/ext/reflection/tests/ReflectionClass_hasProperty_002.phpt b/ext/reflection/tests/ReflectionClass_hasProperty_002.phpt new file mode 100644 index 0000000..7538903 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasProperty_002.phpt @@ -0,0 +1,40 @@ +--TEST-- +ReflectionClass::hasProperty() - error cases +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + public $a; +} + +$rc = new ReflectionClass("C"); +echo "Check invalid params:\n"; +var_dump($rc->hasProperty()); +var_dump($rc->hasProperty("a", "a")); +var_dump($rc->hasProperty(null)); +var_dump($rc->hasProperty(1)); +var_dump($rc->hasProperty(1.5)); +var_dump($rc->hasProperty(true)); +var_dump($rc->hasProperty(array(1,2,3))); +var_dump($rc->hasProperty(new C)); +?> +--EXPECTF-- +Check invalid params: + +Warning: ReflectionClass::hasProperty() expects exactly 1 parameter, 0 given in %s on line 8 +NULL + +Warning: ReflectionClass::hasProperty() expects exactly 1 parameter, 2 given in %s on line 9 +NULL +bool(false) +bool(false) +bool(false) +bool(false) + +Warning: ReflectionClass::hasProperty() expects parameter 1 to be string, array given in %s on line 14 +NULL + +Warning: ReflectionClass::hasProperty() expects parameter 1 to be string, object given in %s on line 15 +NULL diff --git a/ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt b/ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt new file mode 100644 index 0000000..d6dda7c --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_hasProperty_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +ReflectionClass::hasProperty() +--CREDITS-- +Marc Veldman <marc@ibuildings.nl> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php +//New instance of class C - defined below +$rc = new ReflectionClass("C"); + +//Check if C has public property publicFoo +var_dump($rc->hasProperty('publicFoo')); + +//Check if C has protected property protectedFoo +var_dump($rc->hasProperty('protectedFoo')); + +//Check if C has private property privateFoo +var_dump($rc->hasProperty('privateFoo')); + +//Check if C has static property staticFoo +var_dump($rc->hasProperty('staticFoo')); + +//C should not have property bar +var_dump($rc->hasProperty('bar')); + +Class C { + public $publicFoo; + protected $protectedFoo; + private $privateFoo; + public static $staticFoo; +} +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt b/ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt new file mode 100644 index 0000000..9c2fded --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_implementsInterface_001.phpt @@ -0,0 +1,155 @@ +--TEST-- +ReflectionClass::implementsInterface() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +interface I1 {} +class A implements I1 {} +class B extends A {} + +interface I2 extends I1 {} +class C implements I2 {} + +$classNames = array('A', 'B', 'C', 'I1', 'I2'); + +foreach ($classNames as $className) { + $rcs[$className] = new ReflectionClass($className); +} + +foreach ($rcs as $childName => $child) { + foreach ($rcs as $parentName => $parent) { + echo "Does " . $childName . " implement " . $parentName . "? \n"; + echo " - Using object argument: "; + try { + var_dump($child->implementsInterface($parent)); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + echo " - Using string argument: "; + try { + var_dump($child->implementsInterface($parentName)); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + } +} + + + +echo "\n\nTest bad arguments:\n"; +try { + var_dump($rcs['A']->implementsInterface()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rcs['A']->implementsInterface('C', 'C')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rcs['A']->implementsInterface(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rcs['A']->implementsInterface('ThisClassDoesNotExist')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rcs['A']->implementsInterface(2)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +Does A implement A? + - Using object argument: Interface A is a Class + - Using string argument: Interface A is a Class +Does A implement B? + - Using object argument: Interface B is a Class + - Using string argument: Interface B is a Class +Does A implement C? + - Using object argument: Interface C is a Class + - Using string argument: Interface C is a Class +Does A implement I1? + - Using object argument: bool(true) + - Using string argument: bool(true) +Does A implement I2? + - Using object argument: bool(false) + - Using string argument: bool(false) +Does B implement A? + - Using object argument: Interface A is a Class + - Using string argument: Interface A is a Class +Does B implement B? + - Using object argument: Interface B is a Class + - Using string argument: Interface B is a Class +Does B implement C? + - Using object argument: Interface C is a Class + - Using string argument: Interface C is a Class +Does B implement I1? + - Using object argument: bool(true) + - Using string argument: bool(true) +Does B implement I2? + - Using object argument: bool(false) + - Using string argument: bool(false) +Does C implement A? + - Using object argument: Interface A is a Class + - Using string argument: Interface A is a Class +Does C implement B? + - Using object argument: Interface B is a Class + - Using string argument: Interface B is a Class +Does C implement C? + - Using object argument: Interface C is a Class + - Using string argument: Interface C is a Class +Does C implement I1? + - Using object argument: bool(true) + - Using string argument: bool(true) +Does C implement I2? + - Using object argument: bool(true) + - Using string argument: bool(true) +Does I1 implement A? + - Using object argument: Interface A is a Class + - Using string argument: Interface A is a Class +Does I1 implement B? + - Using object argument: Interface B is a Class + - Using string argument: Interface B is a Class +Does I1 implement C? + - Using object argument: Interface C is a Class + - Using string argument: Interface C is a Class +Does I1 implement I1? + - Using object argument: bool(true) + - Using string argument: bool(true) +Does I1 implement I2? + - Using object argument: bool(false) + - Using string argument: bool(false) +Does I2 implement A? + - Using object argument: Interface A is a Class + - Using string argument: Interface A is a Class +Does I2 implement B? + - Using object argument: Interface B is a Class + - Using string argument: Interface B is a Class +Does I2 implement C? + - Using object argument: Interface C is a Class + - Using string argument: Interface C is a Class +Does I2 implement I1? + - Using object argument: bool(true) + - Using string argument: bool(true) +Does I2 implement I2? + - Using object argument: bool(true) + - Using string argument: bool(true) + + +Test bad arguments: + +Warning: ReflectionClass::implementsInterface() expects exactly 1 parameter, 0 given in %s on line 37 +NULL + +Warning: ReflectionClass::implementsInterface() expects exactly 1 parameter, 2 given in %s on line 42 +NULL +Parameter one must either be a string or a ReflectionClass object +Interface ThisClassDoesNotExist does not exist +Parameter one must either be a string or a ReflectionClass object diff --git a/ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt b/ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt new file mode 100644 index 0000000..a7d1982 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isAbstract_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionClass::isAbstract() method +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php + +class TestClass {} +abstract class TestAbstractClass {} + +$testClass = new ReflectionClass('TestClass'); +$abstractClass = new ReflectionClass('TestAbstractClass'); + +var_dump($testClass->isAbstract()); +var_dump($abstractClass->isAbstract()); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionClass_isCloneable_001.phpt b/ext/reflection/tests/ReflectionClass_isCloneable_001.phpt new file mode 100644 index 0000000..f1042cc --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isCloneable_001.phpt @@ -0,0 +1,71 @@ +--TEST-- +Testing ReflectionClass::isCloneable() +--SKIPIF-- +<?php if (!extension_loaded('simplexml') || !extension_loaded('xmlwriter')) die("skip SimpleXML and XMLWriter is required for this test"); ?> +--FILE-- +<?php + +class foo { +} +$foo = new foo; + +print "User class\n"; +$obj = new ReflectionClass($foo); +var_dump($obj->isCloneable()); +$obj = new ReflectionObject($foo); +var_dump($obj->isCloneable()); +$h = clone $foo; + +class bar { + private function __clone() { + } +} +$bar = new bar; +print "User class - private __clone\n"; +$obj = new ReflectionClass($bar); +var_dump($obj->isCloneable()); +$obj = new ReflectionObject($bar); +var_dump($obj->isCloneable()); +$h = clone $foo; + +print "Closure\n"; +$closure = function () { }; +$obj = new ReflectionClass($closure); +var_dump($obj->isCloneable()); +$obj = new ReflectionObject($closure); +var_dump($obj->isCloneable()); +$h = clone $closure; + +print "Internal class - SimpleXMLElement\n"; +$obj = new ReflectionClass('simplexmlelement'); +var_dump($obj->isCloneable()); +$obj = new ReflectionObject(new simplexmlelement('<test></test>')); +var_dump($obj->isCloneable()); +$h = clone new simplexmlelement('<test></test>'); + +print "Internal class - XMLWriter\n"; +$obj = new ReflectionClass('xmlwriter'); +var_dump($obj->isCloneable()); +$obj = new ReflectionObject(new XMLWriter); +var_dump($obj->isCloneable()); +$h = clone new xmlwriter; + +?> +--EXPECTF-- +User class +bool(true) +bool(true) +User class - private __clone +bool(false) +bool(false) +Closure +bool(true) +bool(true) +Internal class - SimpleXMLElement +bool(true) +bool(true) +Internal class - XMLWriter +bool(false) +bool(false) + +Fatal error: Trying to clone an uncloneable object of class XMLWriter in %s on line %d diff --git a/ext/reflection/tests/ReflectionClass_isCloneable_002.phpt b/ext/reflection/tests/ReflectionClass_isCloneable_002.phpt new file mode 100644 index 0000000..7cde576 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isCloneable_002.phpt @@ -0,0 +1,25 @@ +--TEST-- +Testing ReflectionClass::isCloneable() with non instantiable objects +--FILE-- +<?php + +trait foo { +} +$obj = new ReflectionClass('foo'); +var_dump($obj->isCloneable()); + +abstract class bar { +} +$obj = new ReflectionClass('bar'); +var_dump($obj->isCloneable()); + +interface baz { +} +$obj = new ReflectionClass('baz'); +var_dump($obj->isCloneable()); + +?> +--EXPECT-- +bool(false) +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isFinal_basic.phpt b/ext/reflection/tests/ReflectionClass_isFinal_basic.phpt new file mode 100644 index 0000000..57e577a --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isFinal_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionClass::isFinal() method +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php + +class TestClass {} +final class TestFinalClass {} + +$normalClass = new ReflectionClass('TestClass'); +$finalClass = new ReflectionClass('TestFinalClass'); + +var_dump($normalClass->isFinal()); +var_dump($finalClass->isFinal()); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionClass_isInstance_basic.phpt b/ext/reflection/tests/ReflectionClass_isInstance_basic.phpt new file mode 100644 index 0000000..2da0944 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInstance_basic.phpt @@ -0,0 +1,51 @@ +--TEST-- +ReflectionClass::isInstance() +--FILE-- +<?php +class A {} +class B extends A {} + +interface I {} +class C implements I {} + +class X {} + +$classes = array("A", "B", "C", "I", "X"); + +$instances = array( "myA" => new A, + "myB" => new B, + "myC" => new C, + "myX" => new X ); + +foreach ($classes as $class) { + $rc = new ReflectionClass($class); + + foreach ($instances as $name => $instance) { + echo "is $name a $class? "; + var_dump($rc->isInstance($instance)); + } + +} + +?> +--EXPECTF-- +is myA a A? bool(true) +is myB a A? bool(true) +is myC a A? bool(false) +is myX a A? bool(false) +is myA a B? bool(false) +is myB a B? bool(true) +is myC a B? bool(false) +is myX a B? bool(false) +is myA a C? bool(false) +is myB a C? bool(false) +is myC a C? bool(true) +is myX a C? bool(false) +is myA a I? bool(false) +is myB a I? bool(false) +is myC a I? bool(true) +is myX a I? bool(false) +is myA a X? bool(false) +is myB a X? bool(false) +is myC a X? bool(false) +is myX a X? bool(true) diff --git a/ext/reflection/tests/ReflectionClass_isInstance_error.phpt b/ext/reflection/tests/ReflectionClass_isInstance_error.phpt new file mode 100644 index 0000000..2c4f49b --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInstance_error.phpt @@ -0,0 +1,39 @@ +--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, double given in %s on line 10 +NULL + +Warning: ReflectionClass::isInstance() expects parameter 1 to be object, boolean 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_basic.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_basic.phpt new file mode 100644 index 0000000..6ebcfa9 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInstantiable_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +ReflectionClass::IsInstantiable() +--FILE-- +<?php +class C { +} + +interface iface { + function f1(); +} + +class ifaceImpl implements iface { + function f1() {} +} + +abstract class abstractClass { + function f1() {} + abstract function f2(); +} + +class D extends abstractClass { + function f2() {} +} + +$classes = array("C", "iface", "ifaceImpl", "abstractClass", "D"); + +foreach($classes as $class ) { + $reflectionClass = new ReflectionClass($class); + echo "Is $class instantiable? "; + var_dump($reflectionClass->IsInstantiable()); + +} + +?> +--EXPECTF-- +Is C instantiable? bool(true) +Is iface instantiable? bool(false) +Is ifaceImpl instantiable? bool(true) +Is abstractClass instantiable? bool(false) +Is D instantiable? bool(true) diff --git a/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt new file mode 100644 index 0000000..52be239 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInstantiable_error.phpt @@ -0,0 +1,19 @@ +--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-- +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_isInstantiable_variation.phpt b/ext/reflection/tests/ReflectionClass_isInstantiable_variation.phpt new file mode 100644 index 0000000..1cf3e61 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInstantiable_variation.phpt @@ -0,0 +1,50 @@ +--TEST-- +ReflectionClass::IsInstantiable() +--FILE-- +<?php +class noCtor { +} + +class publicCtorNew { + public function __construct() {} +} + +class protectedCtorNew { + protected function __construct() {} +} + +class privateCtorNew { + private function __construct() {} +} + +class publicCtorOld { + public function publicCtorOld() {} +} + +class protectedCtorOld { + protected function protectedCtorOld() {} +} + +class privateCtorOld { + private function privateCtorOld() {} +} + + +$classes = array("noCtor", "publicCtorNew", "protectedCtorNew", "privateCtorNew", + "publicCtorOld", "protectedCtorOld", "privateCtorOld"); + +foreach($classes as $class ) { + $reflectionClass = new ReflectionClass($class); + echo "Is $class instantiable? "; + var_dump($reflectionClass->IsInstantiable()); +} + +?> +--EXPECTF-- +Is noCtor instantiable? bool(true) +Is publicCtorNew instantiable? bool(true) +Is protectedCtorNew instantiable? bool(false) +Is privateCtorNew instantiable? bool(false) +Is publicCtorOld instantiable? bool(true) +Is protectedCtorOld instantiable? bool(false) +Is privateCtorOld instantiable? bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isInterface_basic.phpt b/ext/reflection/tests/ReflectionClass_isInterface_basic.phpt new file mode 100644 index 0000000..66c9ae7 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInterface_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +ReflectionClass::isInterface() method +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php + +interface TestInterface {} +class TestClass {} +interface DerivedInterface extends TestInterface {} + +$reflectionClass = new ReflectionClass('TestInterface'); +$reflectionClass2 = new ReflectionClass('TestClass'); +$reflectionClass3 = new ReflectionClass('DerivedInterface'); + +var_dump($reflectionClass->isInterface()); +var_dump($reflectionClass2->isInterface()); +var_dump($reflectionClass3->isInterface()); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionClass_isInternal_basic.phpt b/ext/reflection/tests/ReflectionClass_isInternal_basic.phpt new file mode 100644 index 0000000..2eaacb6 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInternal_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +ReflectionClass::isInternal() +--FILE-- +<?php +class C { +} + +$r1 = new ReflectionClass("stdClass"); +$r2 = new ReflectionClass("ReflectionClass"); +$r3 = new ReflectionClass("ReflectionProperty"); +$r4 = new ReflectionClass("Exception"); +$r5 = new ReflectionClass("C"); + +var_dump($r1->isInternal(), $r2->isInternal(), $r3->isInternal(), + $r4->isInternal(), $r5->isInternal()); +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isInternal_error.phpt b/ext/reflection/tests/ReflectionClass_isInternal_error.phpt new file mode 100644 index 0000000..ef69a4c --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isInternal_error.phpt @@ -0,0 +1,14 @@ +--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_isIterateable_001.phpt b/ext/reflection/tests/ReflectionClass_isIterateable_001.phpt new file mode 100644 index 0000000..4936413 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isIterateable_001.phpt @@ -0,0 +1,89 @@ +--TEST-- +ReflectionClass::isIterateable() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +Interface ExtendsIterator extends Iterator { +} +Interface ExtendsIteratorAggregate extends IteratorAggregate { +} +Class IteratorImpl implements Iterator { + public function next() {} + public function key() {} + public function rewind() {} + public function current() {} + public function valid() {} +} +Class IterarorAggregateImpl implements IteratorAggregate { + public function getIterator() {} +} +Class ExtendsIteratorImpl extends IteratorImpl { +} +Class ExtendsIteratorAggregateImpl extends IterarorAggregateImpl { +} +Class A { +} + +$classes = array('Traversable', 'Iterator', 'IteratorAggregate', 'ExtendsIterator', 'ExtendsIteratorAggregate', + 'IteratorImpl', 'IterarorAggregateImpl', 'ExtendsIteratorImpl', 'ExtendsIteratorAggregateImpl', 'A'); + +foreach($classes as $class) { + $rc = new ReflectionClass($class); + echo "Is $class iterable? "; + var_dump($rc->isIterateable()); +} + +echo "\nTest invalid params:\n"; +$rc = new ReflectionClass('IteratorImpl'); +var_dump($rc->isIterateable(null)); +var_dump($rc->isIterateable(null, null)); +var_dump($rc->isIterateable(1)); +var_dump($rc->isIterateable(1.5)); +var_dump($rc->isIterateable(true)); +var_dump($rc->isIterateable('X')); +var_dump($rc->isIterateable(null)); + +echo "\nTest static invocation:\n"; +ReflectionClass::isIterateable(); + +?> +--EXPECTF-- +Is Traversable iterable? bool(false) +Is Iterator iterable? bool(false) +Is IteratorAggregate iterable? bool(false) +Is ExtendsIterator iterable? bool(false) +Is ExtendsIteratorAggregate iterable? bool(false) +Is IteratorImpl iterable? bool(true) +Is IterarorAggregateImpl iterable? bool(true) +Is ExtendsIteratorImpl iterable? bool(true) +Is ExtendsIteratorAggregateImpl iterable? bool(true) +Is A iterable? bool(false) + +Test invalid params: + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 34 +NULL + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 2 given in %s on line 35 +NULL + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 36 +NULL + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 37 +NULL + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 38 +NULL + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 39 +NULL + +Warning: ReflectionClass::isIterateable() expects exactly 0 parameters, 1 given in %s on line 40 +NULL + +Test static invocation: + +Fatal error: Non-static method ReflectionClass::isIterateable() cannot be called statically in %s on line 43
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt b/ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt new file mode 100644 index 0000000..8b65b9a --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isIterateable_basic.phpt @@ -0,0 +1,34 @@ +--TEST-- +ReflectionClass::isIterateable() basic +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com>, Marc Veldman <marc@ibuildings.nl> +--FILE-- +<?php + +class IteratorClass implements Iterator { + public function __construct() { } + public function key() {} + public function current() {} + function next() {} + function valid() {} + function rewind() {} +} +class DerivedClass extends IteratorClass {} +class NonIterator {} + +function dump_iterateable($class) { + $reflection = new ReflectionClass($class); + var_dump($reflection->isIterateable()); +} + +$classes = array("ArrayObject", "IteratorClass", "DerivedClass", "NonIterator"); +foreach ($classes as $class) { + echo "Is $class iterateable? "; + dump_iterateable($class); +} +?> +--EXPECT-- +Is ArrayObject iterateable? bool(true) +Is IteratorClass iterateable? bool(true) +Is DerivedClass iterateable? bool(true) +Is NonIterator iterateable? bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt b/ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt new file mode 100644 index 0000000..f6d0d53 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isIterateable_variation1.phpt @@ -0,0 +1,25 @@ +--TEST-- +ReflectionClass::isIterateable() variations +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--FILE-- +<?php + +class BasicClass {} + +function dump_iterateable($obj) +{ + $reflection = new ReflectionClass($obj); + var_dump($reflection->isIterateable()); +} + +$basicClass = new BasicClass(); +$stdClass = new StdClass(); + +dump_iterateable($basicClass); +dump_iterateable($stdClass); + +?> +--EXPECT-- +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt new file mode 100644 index 0000000..083b277 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_002.phpt @@ -0,0 +1,49 @@ +--TEST-- +ReflectionObject::isSubclassOf() - bad arguments +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A {} +$rc = new ReflectionClass('A'); + +echo "\n\nTest bad arguments:\n"; +try { + var_dump($rc->isSubclassOf()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->isSubclassOf('C', 'C')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->isSubclassOf(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->isSubclassOf('ThisClassDoesNotExist')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->isSubclassOf(2)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- + +Test bad arguments: + +Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 7 +NULL + +Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 12 +NULL +Parameter one must either be a string or a ReflectionClass object +Class ThisClassDoesNotExist does not exist +Parameter one must either be a string or a ReflectionClass object
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt new file mode 100644 index 0000000..94fcf00 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_basic.phpt @@ -0,0 +1,103 @@ +--TEST-- +ReflectionClass::isSubclassOf() +--FILE-- +<?php +class A {} +class B extends A {} +class C extends B {} + +interface I {} +class X implements I {} + +$classNames = array('A', 'B', 'C', 'I', 'X'); + +foreach ($classNames as $className) { + $rcs[$className] = new ReflectionClass($className); +} + +foreach ($rcs as $childName => $child) { + foreach ($rcs as $parentName => $parent) { + echo "Is " . $childName . " a subclass of " . $parentName . "? \n"; + echo " - Using object argument: "; + var_dump($child->isSubclassOf($parent)); + echo " - Using string argument: "; + var_dump($child->isSubclassOf($parentName)); + } +} +?> +--EXPECTF-- +Is A a subclass of A? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of B? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of C? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of I? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of X? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of A? + - Using object argument: bool(true) + - Using string argument: bool(true) +Is B a subclass of B? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of C? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of I? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of X? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is C a subclass of A? + - Using object argument: bool(true) + - Using string argument: bool(true) +Is C a subclass of B? + - Using object argument: bool(true) + - Using string argument: bool(true) +Is C a subclass of C? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is C a subclass of I? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is C a subclass of X? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is I a subclass of A? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is I a subclass of B? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is I a subclass of C? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is I a subclass of I? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is I a subclass of X? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of A? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of B? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of C? + - Using object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of I? + - Using object argument: bool(true) + - Using string argument: bool(true) +Is X a subclass of X? + - Using object argument: bool(false) + - Using string argument: bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt new file mode 100644 index 0000000..7d929fa --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_error.phpt @@ -0,0 +1,17 @@ +--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_error1.phpt b/ext/reflection/tests/ReflectionClass_isSubclassOf_error1.phpt new file mode 100644 index 0000000..2fabd02 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isSubclassOf_error1.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionClass::isSubclassOf() - non-existent class error +--FILE-- +<?php +class A {} +$rc = new ReflectionClass('A'); + +var_dump($rc->isSubclassOf('X')); + +?> +--EXPECTF-- +Fatal error: Uncaught exception 'ReflectionException' with message 'Class X does not exist' in %s:5 +Stack trace: +#0 %s(5): ReflectionClass->isSubclassOf('X') +#1 {main} + thrown in %s on line 5 diff --git a/ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt b/ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt new file mode 100644 index 0000000..af43fce --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isUserDefined_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +ReflectionClass::isUserDefined() +--FILE-- +<?php +class C { +} + +$r1 = new ReflectionClass("stdClass"); +$r2 = new ReflectionClass("ReflectionClass"); +$r3 = new ReflectionClass("ReflectionProperty"); +$r4 = new ReflectionClass("Exception"); +$r5 = new ReflectionClass("C"); + +var_dump($r1->isUserDefined(), $r2->isUserDefined(), $r3->isUserDefined(), + $r4->isUserDefined(), $r5->isUserDefined()); +?> +--EXPECTF-- +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt b/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt new file mode 100644 index 0000000..ac88884 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isUserDefined_error.phpt @@ -0,0 +1,14 @@ +--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 new file mode 100644 index 0000000..941bfe5 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt @@ -0,0 +1,44 @@ +--TEST-- +Modifiers +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +abstract class A {} +class B extends A {} +class C {} +final class D {} +interface I {} + +$classes = array("A", "B", "C", "D", "I"); + +foreach ($classes as $class) { + $rc = new ReflectionClass($class); + var_dump($rc->isFinal()); + var_dump($rc->isInterface()); + var_dump($rc->isAbstract()); + var_dump($rc->getModifiers()); +} +?> +--EXPECTF-- +bool(false) +bool(false) +bool(true) +int(32) +bool(false) +bool(false) +bool(false) +int(0) +bool(false) +bool(false) +bool(false) +int(0) +bool(true) +bool(false) +bool(false) +int(64) +bool(false) +bool(true) +bool(false) +int(128)
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_modifiers_002.phpt b/ext/reflection/tests/ReflectionClass_modifiers_002.phpt new file mode 100644 index 0000000..a3a567c --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_modifiers_002.phpt @@ -0,0 +1,27 @@ +--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_newInstanceArgs_001.phpt b/ext/reflection/tests/ReflectionClass_newInstanceArgs_001.phpt new file mode 100644 index 0000000..981d675 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_newInstanceArgs_001.phpt @@ -0,0 +1,98 @@ +--TEST-- +ReflectionClass::newInstanceArgs +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A { + public function A() { + echo "In constructor of class A\n"; + } +} + +class B { + public function __construct($a, $b) { + echo "In constructor of class B with args $a, $b\n"; + } +} + +class C { + protected function __construct() { + echo "In constructor of class C\n"; + } +} + +class D { + private function __construct() { + echo "In constructor of class D\n"; + } +} +class E { +} + + +$rcA = new ReflectionClass('A'); +$rcB = new ReflectionClass('B'); +$rcC = new ReflectionClass('C'); +$rcD = new ReflectionClass('D'); +$rcE = new ReflectionClass('E'); + +$a1 = $rcA->newInstanceArgs(); +$a2 = $rcA->newInstanceArgs(array('x')); +var_dump($a1, $a2); + +$b1 = $rcB->newInstanceArgs(); +$b2 = $rcB->newInstanceArgs(array('x', 123)); +var_dump($b1, $b2); + +try { + $rcC->newInstanceArgs(); + echo "you should not see this\n"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + $rcD->newInstanceArgs(); + echo "you should not see this\n"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +$e1 = $rcE->newInstanceArgs(); +var_dump($e1); + +try { + $e2 = $rcE->newInstanceArgs(array('x')); + echo "you should not see this\n"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +In constructor of class A +In constructor of class A +object(A)#%d (0) { +} +object(A)#%d (0) { +} + +Warning: Missing argument 1 for B::__construct() in %s on line 9 + +Warning: Missing argument 2 for B::__construct() in %s on line 9 + +Notice: Undefined variable: a in %s on line 10 + +Notice: Undefined variable: b in %s on line 10 +In constructor of class B with args , +In constructor of class B with args x, 123 +object(B)#%d (0) { +} +object(B)#%d (0) { +} +Access to non-public constructor of class C +Access to non-public constructor of class D +object(E)#%d (0) { +} +Class E does not have a constructor, so you cannot pass any constructor arguments
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt b/ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt new file mode 100644 index 0000000..dd6f438 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_newInstanceArgs_002.phpt @@ -0,0 +1,20 @@ +--TEST-- +ReflectionClass::newInstanceArgs() - wrong arg type +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A { + public function __construct($a, $b) { + echo "In constructor of class B with arg $a\n"; + } +} +$rc = new ReflectionClass('A'); +$a = $rc->newInstanceArgs('x'); +var_dump($a); + +?> +--EXPECTF-- + +Catchable fatal error: Argument 1 passed to ReflectionClass::newInstanceArgs() must be of the type array, string given in %s on line 8 diff --git a/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt new file mode 100644 index 0000000..1932dbf --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_newInstanceWithoutConstructor.phpt @@ -0,0 +1,33 @@ +--TEST-- +ReflectionClass::newInstanceWithoutConstructor() +--CREDITS-- +Sebastian Bergmann <sebastian@php.net> +--FILE-- +<?php +class Foo +{ + public function __construct() + { + print __METHOD__; + } +} + +$class = new ReflectionClass('Foo'); +var_dump($class->newInstanceWithoutConstructor()); + +$class = new ReflectionClass('StdClass'); +var_dump($class->newInstanceWithoutConstructor()); + +$class = new ReflectionClass('DateTime'); +var_dump($class->newInstanceWithoutConstructor()); +--EXPECTF-- +object(Foo)#%d (0) { +} +object(stdClass)#%d (0) { +} + +Fatal error: Uncaught exception 'ReflectionException' with message 'Class DateTime is an internal class 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 diff --git a/ext/reflection/tests/ReflectionClass_newInstance_001.phpt b/ext/reflection/tests/ReflectionClass_newInstance_001.phpt new file mode 100644 index 0000000..3cdb5d7 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_newInstance_001.phpt @@ -0,0 +1,98 @@ +--TEST-- +ReflectionClass::newInstance() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class A { + public function A() { + echo "In constructor of class A\n"; + } +} + +class B { + public function __construct($a, $b) { + echo "In constructor of class B with args $a, $b\n"; + } +} + +class C { + protected function __construct() { + echo "In constructor of class C\n"; + } +} + +class D { + private function __construct() { + echo "In constructor of class D\n"; + } +} +class E { +} + + +$rcA = new ReflectionClass('A'); +$rcB = new ReflectionClass('B'); +$rcC = new ReflectionClass('C'); +$rcD = new ReflectionClass('D'); +$rcE = new ReflectionClass('E'); + +$a1 = $rcA->newInstance(); +$a2 = $rcA->newInstance('x'); +var_dump($a1, $a2); + +$b1 = $rcB->newInstance(); +$b2 = $rcB->newInstance('x', 123); +var_dump($b1, $b2); + +try { + $rcC->newInstance(); + echo "you should not see this\n"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + $rcD->newInstance(); + echo "you should not see this\n"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +$e1 = $rcE->newInstance(); +var_dump($e1); + +try { + $e2 = $rcE->newInstance('x'); + echo "you should not see this\n"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +In constructor of class A +In constructor of class A +object(A)#%d (0) { +} +object(A)#%d (0) { +} + +Warning: Missing argument 1 for B::__construct() in %s on line 9 + +Warning: Missing argument 2 for B::__construct() in %s on line 9 + +Notice: Undefined variable: a in %s on line 10 + +Notice: Undefined variable: b in %s on line 10 +In constructor of class B with args , +In constructor of class B with args x, 123 +object(B)#%d (0) { +} +object(B)#%d (0) { +} +Access to non-public constructor of class C +Access to non-public constructor of class D +object(E)#%d (0) { +} +Class E does not have a constructor, so you cannot pass any constructor arguments
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt new file mode 100644 index 0000000..9e8f01e --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt @@ -0,0 +1,79 @@ +--TEST-- +ReflectionClass::setStaticPropertyValue() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?> +--FILE-- +<?php +class A { + static private $privateOverridden = "original private"; + static protected $protectedOverridden = "original protected"; + static public $publicOverridden = "original public"; +} + +class B extends A { + static private $privateOverridden = "changed private"; + static protected $protectedOverridden = "changed protected"; + static public $publicOverridden = "changed public"; +} + +echo "Set static values in A:\n"; +$rcA = new ReflectionClass('A'); +$rcA->setStaticPropertyValue("\0A\0privateOverridden", "new value 1"); +$rcA->setStaticPropertyValue("\0*\0protectedOverridden", "new value 2"); +$rcA->setStaticPropertyValue("publicOverridden", "new value 3"); +print_r($rcA->getStaticProperties()); + +echo "\nSet static values in B:\n"; +$rcB = new ReflectionClass('B'); +$rcB->setStaticPropertyValue("\0A\0privateOverridden", "new value 4"); +$rcB->setStaticPropertyValue("\0B\0privateOverridden", "new value 5"); +$rcB->setStaticPropertyValue("\0*\0protectedOverridden", "new value 6"); +$rcB->setStaticPropertyValue("publicOverridden", "new value 7"); +print_r($rcA->getStaticProperties()); +print_r($rcB->getStaticProperties()); + +echo "\nSet non-existent values from A with no default value:\n"; +try { + var_dump($rcA->setStaticPropertyValue("protectedOverridden", "new value 8")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump($rcA->setStaticPropertyValue("privateOverridden", "new value 9")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Set static values in A: +Array +( + [privateOverridden] => new value 1 + [protectedOverridden] => new value 2 + [publicOverridden] => new value 3 +) + +Set static values in B: +Array +( + [privateOverridden] => new value 4 + [protectedOverridden] => new value 2 + [publicOverridden] => new value 3 +) +Array +( + [privateOverridden] => new value 5 + [protectedOverridden] => new value 6 + [publicOverridden] => new value 7 +) + +Set non-existent values from A with no default value: +Class A does not have a property named protectedOverridden +Class A does not have a property named privateOverridden diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt new file mode 100644 index 0000000..1092f65 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt @@ -0,0 +1,61 @@ +--TEST-- +ReflectionClass::setStaticPropertyValue() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?> +--FILE-- +<?php +class A { + static private $privateOverridden = "original private"; + static protected $protectedOverridden = "original protected"; + static public $publicOverridden = "original public"; +} + +class B extends A { + static private $privateOverridden = "changed private"; + static protected $protectedOverridden = "changed protected"; + static public $publicOverridden = "changed public"; +} + +echo "Set static values in A:\n"; +$rcA = new ReflectionClass('A'); +$rcA->setStaticPropertyValue("\0A\0privateOverridden", "new value 1"); +$rcA->setStaticPropertyValue("\0*\0protectedOverridden", "new value 2"); +$rcA->setStaticPropertyValue("publicOverridden", "new value 3"); +print_r($rcA->getStaticProperties()); + +echo "\nSet static values in B:\n"; +$rcB = new ReflectionClass('B'); +$rcB->setStaticPropertyValue("\0A\0privateOverridden", "new value 4"); +$rcB->setStaticPropertyValue("\0B\0privateOverridden", "new value 5"); +$rcB->setStaticPropertyValue("\0*\0protectedOverridden", "new value 6"); +$rcB->setStaticPropertyValue("publicOverridden", "new value 7"); +print_r($rcA->getStaticProperties()); +print_r($rcB->getStaticProperties()); + +echo "\nSet non-existent values from A with no default value:\n"; +try { + var_dump($rcA->setStaticPropertyValue("protectedOverridden", "new value 8")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump($rcA->setStaticPropertyValue("privateOverridden", "new value 9")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Set static values in A: + +Fatal error: Uncaught exception 'ReflectionException' with message 'Class A does not have a property named ' in %sReflectionClass_setStaticPropertyValue_001_2_4.php:%d +Stack trace: +#0 %sReflectionClass_setStaticPropertyValue_001_2_4.php(%d): ReflectionClass->setStaticPropertyValue('?A?privateOverr...', 'new value 1') +#1 {main} + thrown in %sReflectionClass_setStaticPropertyValue_001_2_4.php on line %d diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt new file mode 100644 index 0000000..3244ec3 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +ReflectionClass::getStaticPropertyValue() - bad params +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C { + public static $x; +} + +$rc = new ReflectionClass('C'); +try { + var_dump($rc->setStaticPropertyValue("x", "default value", 'blah')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->setStaticPropertyValue()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->setStaticPropertyValue(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->setStaticPropertyValue(null,null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->setStaticPropertyValue(1.5, 'def')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($rc->setStaticPropertyValue(array(1,2,3), 'blah')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + + +?> +--EXPECTF-- + +Warning: ReflectionClass::setStaticPropertyValue() expects exactly 2 parameters, 3 given in %s on line 8 +NULL + +Warning: ReflectionClass::setStaticPropertyValue() expects exactly 2 parameters, 0 given in %s on line 13 +NULL + +Warning: ReflectionClass::setStaticPropertyValue() expects exactly 2 parameters, 1 given in %s on line 18 +NULL +Class C does not have a property named +Class C does not have a property named 1.5 + +Warning: ReflectionClass::setStaticPropertyValue() expects parameter 1 to be string, array given in %s on line 33 +NULL
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt new file mode 100644 index 0000000..508530a --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -0,0 +1,350 @@ +--TEST-- +ReflectionClass::__toString() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +$rc = new ReflectionClass("ReflectionClass"); +echo $rc; +?> +--EXPECTF-- +Class [ <internal:Reflection> class ReflectionClass implements Reflector ] { + + - Constants [3] { + Constant [ integer IS_IMPLICIT_ABSTRACT ] { 16 } + Constant [ integer IS_EXPLICIT_ABSTRACT ] { 32 } + Constant [ integer IS_FINAL ] { 64 } + } + + - Static properties [0] { + } + + - Static methods [1] { + Method [ <internal:Reflection> static public method export ] { + + - Parameters [2] { + Parameter #0 [ <required> $argument ] + Parameter #1 [ <optional> $return ] + } + } + } + + - Properties [1] { + Property [ <default> public $name ] + } + + - Methods [49] { + Method [ <internal:Reflection> final private method __clone ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection, ctor> public method __construct ] { + + - Parameters [1] { + Parameter #0 [ <required> $argument ] + } + } + + Method [ <internal:Reflection> public method __toString ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getName ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isInternal ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isUserDefined ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isInstantiable ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isCloneable ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getFileName ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getStartLine ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getEndLine ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getDocComment ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getConstructor ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method hasMethod ] { + + - Parameters [1] { + Parameter #0 [ <required> $name ] + } + } + + Method [ <internal:Reflection> public method getMethod ] { + + - Parameters [1] { + Parameter #0 [ <required> $name ] + } + } + + Method [ <internal:Reflection> public method getMethods ] { + + - Parameters [1] { + Parameter #0 [ <optional> $filter ] + } + } + + Method [ <internal:Reflection> public method hasProperty ] { + + - Parameters [1] { + Parameter #0 [ <required> $name ] + } + } + + Method [ <internal:Reflection> public method getProperty ] { + + - Parameters [1] { + Parameter #0 [ <required> $name ] + } + } + + Method [ <internal:Reflection> public method getProperties ] { + + - Parameters [1] { + Parameter #0 [ <optional> $filter ] + } + } + + Method [ <internal:Reflection> public method hasConstant ] { + + - Parameters [1] { + Parameter #0 [ <required> $name ] + } + } + + Method [ <internal:Reflection> public method getConstants ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getConstant ] { + + - Parameters [1] { + Parameter #0 [ <required> $name ] + } + } + + Method [ <internal:Reflection> public method getInterfaces ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getInterfaceNames ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isInterface ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getTraits ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getTraitNames ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getTraitAliases ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isTrait ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isAbstract ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isFinal ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getModifiers ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isInstance ] { + + - Parameters [1] { + Parameter #0 [ <required> $object ] + } + } + + Method [ <internal:Reflection> public method newInstance ] { + + - Parameters [1] { + Parameter #0 [ <required> $args ] + } + } + + Method [ <internal:Reflection> public method newInstanceWithoutConstructor ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method newInstanceArgs ] { + + - Parameters [1] { + Parameter #0 [ <optional> array $args ] + } + } + + Method [ <internal:Reflection> public method getParentClass ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isSubclassOf ] { + + - Parameters [1] { + Parameter #0 [ <required> $class ] + } + } + + Method [ <internal:Reflection> public method getStaticProperties ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getStaticPropertyValue ] { + + - Parameters [2] { + Parameter #0 [ <required> $name ] + Parameter #1 [ <optional> $default ] + } + } + + Method [ <internal:Reflection> public method setStaticPropertyValue ] { + + - Parameters [2] { + Parameter #0 [ <required> $name ] + Parameter #1 [ <required> $value ] + } + } + + Method [ <internal:Reflection> public method getDefaultProperties ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method isIterateable ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method implementsInterface ] { + + - Parameters [1] { + Parameter #0 [ <required> $interface ] + } + } + + Method [ <internal:Reflection> public method getExtension ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getExtensionName ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method inNamespace ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getNamespaceName ] { + + - Parameters [0] { + } + } + + Method [ <internal:Reflection> public method getShortName ] { + + - Parameters [0] { + } + } + } +} diff --git a/ext/reflection/tests/ReflectionClass_toString_002.phpt b/ext/reflection/tests/ReflectionClass_toString_002.phpt new file mode 100644 index 0000000..e9aaa50 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_toString_002.phpt @@ -0,0 +1,123 @@ +--TEST-- +ReflectionClass::__toString() - verify 'inherits', 'overwrites' and 'prototype' parts of method representation +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +Class A { + function f() {} +} +Class B extends A { + function f() {} +} +Class C extends B { + +} +Class D extends C { + function f() {} +} +foreach (array('A', 'B', 'C', 'D') as $class) { + echo "\n\n----( Reflection class $class: )----\n"; + $rc = new ReflectionClass($class); + echo $rc; +} + +?> +--EXPECTF-- + + +----( Reflection class A: )---- +Class [ <user> class A ] { + @@ %s 2-4 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user> public method f ] { + @@ %s 3 - 3 + } + } +} + + +----( Reflection class B: )---- +Class [ <user> class B extends A ] { + @@ %s 5-7 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user, overwrites A, prototype A> public method f ] { + @@ %s 6 - 6 + } + } +} + + +----( Reflection class C: )---- +Class [ <user> class C extends B ] { + @@ %s 8-10 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user, inherits B, prototype A> public method f ] { + @@ %s 6 - 6 + } + } +} + + +----( Reflection class D: )---- +Class [ <user> class D extends C ] { + @@ %s 11-13 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user, overwrites B, prototype A> public method f ] { + @@ %s 12 - 12 + } + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionClass_toString_003.phpt b/ext/reflection/tests/ReflectionClass_toString_003.phpt new file mode 100644 index 0000000..ce5afb0 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_toString_003.phpt @@ -0,0 +1,120 @@ +--TEST-- +ReflectionClass::__toString() - verify 'inherits', 'overwrites' and 'prototype' parts of method representation with private methods +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +Class A { + private function f() {} +} +Class B extends A { + private function f() {} +} +Class C extends B { + +} +Class D extends C { + private function f() {} +} +foreach (array('A', 'B', 'C', 'D') as $class) { + echo "\n\n----( Reflection class $class: )----\n"; + $rc = new ReflectionClass($class); + echo $rc; +} + +?> +--EXPECTF-- + + +----( Reflection class A: )---- +Class [ <user> class A ] { + @@ %s 2-4 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user> private method f ] { + @@ %s 3 - 3 + } + } +} + + +----( Reflection class B: )---- +Class [ <user> class B extends A ] { + @@ %s 5-7 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user, overwrites A> private method f ] { + @@ %s 6 - 6 + } + } +} + + +----( Reflection class C: )---- +Class [ <user> class C extends B ] { + @@ %s 8-10 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + + +----( Reflection class D: )---- +Class [ <user> class D extends C ] { + @@ %s 11-13 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user, overwrites B> private method f ] { + @@ %s 12 - 12 + } + } +} diff --git a/ext/reflection/tests/ReflectionExtension_constructor_basic.phpt b/ext/reflection/tests/ReflectionExtension_constructor_basic.phpt new file mode 100644 index 0000000..72c8ac6 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_constructor_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +ReflectionExtension::__construct() +--CREDITS-- +Gerrit "Remi" te Sligte <remi@wolerized.com> +Leon Luijkx <leon@phpgg.nl> +--FILE-- +<?php +$obj = new ReflectionExtension('reflection'); +$test = $obj instanceof ReflectionExtension; +var_dump($test); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_constructor_error.phpt b/ext/reflection/tests/ReflectionExtension_constructor_error.phpt new file mode 100644 index 0000000..9eae206 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_constructor_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionExtension::__construct() +--CREDITS-- +Gerrit "Remi" te Sligte <remi@wolerized.com> +Leon Luijkx <leon@phpgg.nl> +--FILE-- +<?php +$obj = new ReflectionExtension(); +$test = $obj instanceof ReflectionExtension; +var_dump($test); +?> +==DONE== +--EXPECTF-- +Warning: ReflectionExtension::__construct() expects exactly %d parameter, %d given in %s.php on line %d +bool(true) +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_export_basic.phpt b/ext/reflection/tests/ReflectionExtension_export_basic.phpt new file mode 100644 index 0000000..3fa7a66 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_export_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +ReflectionExtension::export() +--CREDITS-- +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) +bool(false) +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt new file mode 100644 index 0000000..465e868 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +ReflectionExtension::getClassNames() method on an extension which acually returns some information +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--FILE-- +<?php +$standard = new ReflectionExtension('standard'); +var_dump($standard->getClassNames()); +?> +==DONE== +--EXPECTF-- +array(3) { + [0]=> + %s(22) "__PHP_Incomplete_Class" + [1]=> + %s(15) "php_user_filter" + [2]=> + %s(9) "Directory" +} +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt b/ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt new file mode 100644 index 0000000..cd5dc0b --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getClassNames_variation1.phpt @@ -0,0 +1,14 @@ +--TEST-- +ReflectionExtension::getClassNames() method on an extension with no classes +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--FILE-- +<?php +$ereg = new ReflectionExtension('ereg'); +var_dump($ereg->getClassNames()); +?> +==DONE== +--EXPECT-- +array(0) { +} +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt new file mode 100644 index 0000000..5df9e08 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt @@ -0,0 +1,74 @@ +--TEST-- +ReflectionExtension::getClasses(); +--CREDITS-- +Thijs Lensselink <tl@lenss.nl> +--FILE-- +<?php +$ext = new ReflectionExtension('reflection'); +var_dump($ext->getClasses()); +?> +==DONE== +--EXPECT-- +array(12) { + ["ReflectionException"]=> + &object(ReflectionClass)#2 (1) { + ["name"]=> + string(19) "ReflectionException" + } + ["Reflection"]=> + &object(ReflectionClass)#3 (1) { + ["name"]=> + string(10) "Reflection" + } + ["Reflector"]=> + &object(ReflectionClass)#4 (1) { + ["name"]=> + string(9) "Reflector" + } + ["ReflectionFunctionAbstract"]=> + &object(ReflectionClass)#5 (1) { + ["name"]=> + string(26) "ReflectionFunctionAbstract" + } + ["ReflectionFunction"]=> + &object(ReflectionClass)#6 (1) { + ["name"]=> + string(18) "ReflectionFunction" + } + ["ReflectionParameter"]=> + &object(ReflectionClass)#7 (1) { + ["name"]=> + string(19) "ReflectionParameter" + } + ["ReflectionMethod"]=> + &object(ReflectionClass)#8 (1) { + ["name"]=> + string(16) "ReflectionMethod" + } + ["ReflectionClass"]=> + &object(ReflectionClass)#9 (1) { + ["name"]=> + string(15) "ReflectionClass" + } + ["ReflectionObject"]=> + &object(ReflectionClass)#10 (1) { + ["name"]=> + string(16) "ReflectionObject" + } + ["ReflectionProperty"]=> + &object(ReflectionClass)#11 (1) { + ["name"]=> + string(18) "ReflectionProperty" + } + ["ReflectionExtension"]=> + &object(ReflectionClass)#12 (1) { + ["name"]=> + string(19) "ReflectionExtension" + } + ["ReflectionZendExtension"]=> + &object(ReflectionClass)#13 (1) { + ["name"]=> + string(23) "ReflectionZendExtension" + } +} +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt b/ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt new file mode 100644 index 0000000..8b5293a --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getDependencies_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +ReflectionExtension::getDependencies() method on an extension with a required and conflicting dependency +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--SKIPIF-- +<?php +if (!extension_loaded("dom")) die("skip no dom extension"); +?> +--FILE-- +<?php +$dom = new ReflectionExtension('dom'); +var_dump($dom->getDependencies()); +?> +==DONE== +--EXPECTF-- +array(2) { + ["libxml"]=> + %s(8) "Required" + ["domxml"]=> + %s(9) "Conflicts" +} +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt b/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt new file mode 100644 index 0000000..5b0ade5 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionExtension::getDependencies() method on an extension with one optional dependency +--CREDITS-- +Felix De Vliegher <felix.devliegher@gmail.com> +--FILE-- +<?php +$standard = new ReflectionExtension('standard'); +var_dump($standard->getDependencies()); +?> +==DONE== +--EXPECTF-- +array(1) { + ["session"]=> + %s(8) "Optional" +} +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getName_basic.phpt b/ext/reflection/tests/ReflectionExtension_getName_basic.phpt new file mode 100644 index 0000000..9dae1f3 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getName_basic.phpt @@ -0,0 +1,14 @@ +--TEST-- +ReflectionExtension::getName() +--CREDITS-- +Gerrit "Remi" te Sligte <remi@wolerized.com> +Leon Luijkx <leon@phpgg.nl> +--FILE-- +<?php +$obj = new ReflectionExtension('reflection'); +var_dump($obj->getName()); +?> +==DONE== +--EXPECT-- +string(10) "Reflection" +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt b/ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt new file mode 100644 index 0000000..19dee82 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_getVersion_basic.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionExtension::getVersion() +--CREDITS-- +Gerrit "Remi" te Sligte <remi@wolerized.com> +Leon Luijkx <leon@phpgg.nl> +--FILE-- +<?php +$obj = new ReflectionExtension('reflection'); +$var = $obj->getVersion() ? $obj->getVersion() : null; +$test = floatval($var) == $var ? true : false; +var_dump($test); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_info_basic.phpt b/ext/reflection/tests/ReflectionExtension_info_basic.phpt new file mode 100644 index 0000000..48f6a65 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_info_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +ReflectionExtension::info() +--CREDITS-- +Gerrit "Remi" te Sligte <remi@wolerized.com> +Leon Luijkx <leon@phpgg.nl> +--FILE-- +<?php +$obj = new ReflectionExtension('reflection'); +ob_start(); +$testa = $obj->info(); +$testb = ob_get_clean(); +var_dump($testa); +var_dump(strlen($testb) > 24); +?> +==DONE== +--EXPECT-- +NULL +bool(true) +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_isPersistant.phpt b/ext/reflection/tests/ReflectionExtension_isPersistant.phpt new file mode 100644 index 0000000..a78a8bb --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_isPersistant.phpt @@ -0,0 +1,11 @@ +--TEST-- +ReflectionExtension::isPersistent() +--FILE-- +<?php +$obj = new ReflectionExtension('reflection'); +var_dump($obj->isPersistent()); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== diff --git a/ext/reflection/tests/ReflectionExtension_isTemporary.phpt b/ext/reflection/tests/ReflectionExtension_isTemporary.phpt new file mode 100644 index 0000000..be97641 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_isTemporary.phpt @@ -0,0 +1,11 @@ +--TEST-- +ReflectionExtension::isTemporary() +--FILE-- +<?php +$obj = new ReflectionExtension('reflection'); +var_dump($obj->isTemporary()); +?> +==DONE== +--EXPECT-- +bool(false) +==DONE== diff --git a/ext/reflection/tests/ReflectionFunction_001.phpt b/ext/reflection/tests/ReflectionFunction_001.phpt new file mode 100644 index 0000000..7c592dc --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_001.phpt @@ -0,0 +1,67 @@ +--TEST-- +ReflectionFunction methods +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +/** + * my doc comment + */ +function foo () { + static $c; + static $a = 1; + static $b = "hello"; + $d = 5; +} + +/*** + * not a doc comment + */ +function bar () {} + + +function dumpFuncInfo($name) { + $funcInfo = new ReflectionFunction($name); + var_dump($funcInfo->getName()); + var_dump($funcInfo->isInternal()); + var_dump($funcInfo->isUserDefined()); + var_dump($funcInfo->getStartLine()); + var_dump($funcInfo->getEndLine()); + var_dump($funcInfo->getStaticVariables()); +} + +dumpFuncInfo('foo'); +dumpFuncInfo('bar'); +dumpFuncInfo('extract'); + +?> +--EXPECT-- +string(3) "foo" +bool(false) +bool(true) +int(6) +int(11) +array(3) { + ["c"]=> + NULL + ["a"]=> + int(1) + ["b"]=> + string(5) "hello" +} +string(3) "bar" +bool(false) +bool(true) +int(16) +int(16) +array(0) { +} +string(7) "extract" +bool(true) +bool(false) +bool(false) +bool(false) +array(0) { +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionFunction_construct.001.phpt b/ext/reflection/tests/ReflectionFunction_construct.001.phpt new file mode 100644 index 0000000..c8e0a17 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_construct.001.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionFunction constructor errors +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +$a = new ReflectionFunction(array(1, 2, 3)); +try { + $a = new ReflectionFunction('nonExistentFunction'); +} catch (Exception $e) { + echo $e->getMessage(); +} +$a = new ReflectionFunction(); +$a = new ReflectionFunction(1, 2); +?> +--EXPECTF-- +Warning: ReflectionFunction::__construct() expects parameter 1 to be string, array given in %s on line %d +Function nonExistentFunction() does not exist +Warning: ReflectionFunction::__construct() expects exactly 1 parameter, 0 given in %s on line %d + +Warning: ReflectionFunction::__construct() expects exactly 1 parameter, 2 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt b/ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt new file mode 100644 index 0000000..f725dfd --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getClosureScopeClass.phpt @@ -0,0 +1,31 @@ +--TEST-- +Reflection::getClosureScopeClass() +--SKIPIF-- +<?php +if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50399) { + print 'skip'; +} +?> +--FILE-- +<?php +$closure = function($param) { return "this is a closure"; }; +$rf = new ReflectionFunction($closure); +var_dump($rf->getClosureScopeClass()); + +Class A { + public static function getClosure() { + return function($param) { return "this is a closure"; }; + } +} + +$closure = A::getClosure(); +$rf = new ReflectionFunction($closure); +var_dump($rf->getClosureScopeClass()); +echo "Done!\n"; +--EXPECTF-- +NULL +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "A" +} +Done! diff --git a/ext/reflection/tests/ReflectionFunction_getClosureThis.phpt b/ext/reflection/tests/ReflectionFunction_getClosureThis.phpt new file mode 100644 index 0000000..776bfaf --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getClosureThis.phpt @@ -0,0 +1,17 @@ +--TEST-- +Reflection::getClosureThis() +--SKIPIF-- +<?php +if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) { + print 'skip'; +} +?> +--FILE-- +<?php +$closure = function($param) { return "this is a closure"; }; +$rf = new ReflectionFunction($closure); +var_dump($rf->getClosureThis()); +echo "Done!\n"; +--EXPECTF-- +NULL +Done! diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt new file mode 100644 index 0000000..786be05 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test ReflectionFunction::getClosure() function : basic 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() : basic functionality ***\n"; + +function foo() +{ + var_dump( "Inside foo function" ); +} + +function bar( $arg ) +{ + var_dump( "Arg is " . $arg ); +} + +$func = new ReflectionFunction( 'foo' ); +$closure = $func->getClosure(); +$closure(); + +$func = new ReflectionFunction( 'bar' ); +$closure = $func->getClosure(); +$closure( 'succeeded' ); + +?> +===DONE=== +--EXPECTF-- +*** Testing ReflectionFunction::getClosure() : basic functionality *** +string(19) "Inside foo function" +string(16) "Arg is succeeded" +===DONE=== diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt new file mode 100644 index 0000000..9a963e4 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt @@ -0,0 +1,27 @@ +--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/ReflectionFunction_getDocComment.001.phpt b/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt new file mode 100644 index 0000000..38c278d --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt @@ -0,0 +1,41 @@ +--TEST-- +ReflectionFunction::getDocComment() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +/** + * my doc comment + */ +function foo () { + static $c; + static $a = 1; + static $b = "hello"; + $d = 5; +} + +/*** + * not a doc comment + */ +function bar () {} + + +function dumpFuncInfo($name) { + $funcInfo = new ReflectionFunction($name); + var_dump($funcInfo->getDocComment()); +} + +dumpFuncInfo('foo'); +dumpFuncInfo('bar'); +dumpFuncInfo('extract'); + +?> +--EXPECTF-- +string(%d) "/** + * my doc comment + */" +bool(false) +bool(false) + diff --git a/ext/reflection/tests/ReflectionFunction_getExtension.phpt b/ext/reflection/tests/ReflectionFunction_getExtension.phpt new file mode 100644 index 0000000..1834589 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getExtension.phpt @@ -0,0 +1,19 @@ +--TEST-- +ReflectionFunction::getExtension() +--FILE-- +<?php +function foo () {} + +$function = new ReflectionFunction('sort'); +var_dump($function->getExtension()); + +$function = new ReflectionFunction('foo'); +var_dump($function->getExtension()); +?> +--EXPECTF-- +object(ReflectionExtension)#%i (1) { + ["name"]=> + string(8) "standard" +} +NULL + diff --git a/ext/reflection/tests/ReflectionFunction_getExtensionName.phpt b/ext/reflection/tests/ReflectionFunction_getExtensionName.phpt new file mode 100644 index 0000000..7553a50 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getExtensionName.phpt @@ -0,0 +1,16 @@ +--TEST-- +ReflectionFunction::getExtensionName() +--FILE-- +<?php +function foo() {} + +$function = new ReflectionFunction('sort'); +var_dump($function->getExtensionName()); + +$function = new ReflectionFunction('foo'); +var_dump($function->getExtensionName()); +?> +--EXPECT-- +string(8) "standard" +bool(false) + diff --git a/ext/reflection/tests/ReflectionFunction_getFileName.001.phpt b/ext/reflection/tests/ReflectionFunction_getFileName.001.phpt new file mode 100644 index 0000000..5dbe7b5 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getFileName.001.phpt @@ -0,0 +1,18 @@ +--TEST-- +ReflectionFunction::getFileName() with function in an included file +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +include "included4.inc"; + +$funcInfo = new ReflectionFunction('g'); +var_dump($funcInfo->getFileName()); + +?> +--EXPECTF-- +%sincluded4.inc +%d +string(%d) "%sincluded4.inc"
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionFunction_getFileName.002.phpt b/ext/reflection/tests/ReflectionFunction_getFileName.002.phpt new file mode 100644 index 0000000..455935e --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getFileName.002.phpt @@ -0,0 +1,39 @@ +--TEST-- +ReflectionFunction::getFileName() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +/** + * my doc comment + */ +function foo () { + static $c; + static $a = 1; + static $b = "hello"; + $d = 5; +} + +/*** + * not a doc comment + */ +function bar () {} + + +function dumpFuncInfo($name) { + $funcInfo = new ReflectionFunction($name); + var_dump($funcInfo->getFileName()); +} + +dumpFuncInfo('foo'); +dumpFuncInfo('bar'); +dumpFuncInfo('extract'); + +?> +--EXPECTF-- +string(%d) "%sReflectionFunction_getFileName.002.php" +string(%d) "%sReflectionFunction_getFileName.002.php" +bool(false) + diff --git a/ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt b/ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt new file mode 100644 index 0000000..08b3ddd --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_getNamespaceName.phpt @@ -0,0 +1,29 @@ +--TEST-- +ReflectionFunction::getNamespaceName() +--FILE-- +<?php +namespace A\B; +function foo() {} + +$function = new \ReflectionFunction('sort'); +var_dump($function->inNamespace()); +var_dump($function->getName()); +var_dump($function->getNamespaceName()); +var_dump($function->getShortName()); + +$function = new \ReflectionFunction('A\\B\\foo'); +var_dump($function->inNamespace()); +var_dump($function->getName()); +var_dump($function->getNamespaceName()); +var_dump($function->getShortName()); +?> +--EXPECT-- +bool(false) +string(4) "sort" +string(0) "" +string(4) "sort" +bool(true) +string(7) "A\B\foo" +string(3) "A\B" +string(3) "foo" + diff --git a/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt new file mode 100644 index 0000000..eeaf8d3 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +Reflection::isClosure +--CREDITS-- +Stefan Koopmanschap <stefan@phpgg.nl> +TestFest PHP|Tek +--SKIPIF-- +<?php +if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) { + print 'skip'; +} +?> +--FILE-- +<?php +$closure = function($param) { return "this is a closure"; }; +$rc = new ReflectionFunction($closure); +echo var_dump($rc->isClosure()); +--EXPECTF-- +bool(true) diff --git a/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt new file mode 100644 index 0000000..31d37a8 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +ReflectionFunction::isDeprecated +--CREDITS-- +Stefan Koopmanschap <stefan@phpgg.nl> +TestFest PHP|Tek +--SKIPIF-- +<?php +if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) print 'skip'; +?> +--FILE-- +<?php +$rc = new ReflectionFunction('ereg'); +echo var_dump($rc->isDeprecated()); +--EXPECTF-- +bool(true) diff --git a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt new file mode 100644 index 0000000..c71b96b --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt @@ -0,0 +1,17 @@ +--TEST-- +ReflectionFunction::isDisabled +--CREDITS-- +Stefan Koopmanschap <stefan@phpgg.nl> +TestFest PHP|Tek +--SKIPIF-- +<?php +if (!extension_loaded('reflection')) print 'skip'; +?> +--INI-- +disable_functions=is_file +--FILE-- +<?php +$rc = new ReflectionFunction('is_file'); +echo var_dump($rc->isDisabled()); +--EXPECTF-- +bool(true) diff --git a/ext/reflection/tests/ReflectionMethod_006.phpt b/ext/reflection/tests/ReflectionMethod_006.phpt new file mode 100644 index 0000000..a516419 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_006.phpt @@ -0,0 +1,100 @@ +--TEST-- +ReflectionMethod methods - wrong num args +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +var_dump(new ReflectionMethod()); +var_dump(new ReflectionMethod('a', 'b', 'c')); + +class C { + public function f() {} +} + +$rm = new ReflectionMethod('C', 'f'); + +var_dump($rm->isFinal(1)); +var_dump($rm->isAbstract(1)); +var_dump($rm->isPrivate(1)); +var_dump($rm->isProtected(1)); +var_dump($rm->isPublic(1)); +var_dump($rm->isStatic(1)); +var_dump($rm->isConstructor(1)); +var_dump($rm->isDestructor(1)); +var_dump($rm->getModifiers(1)); +var_dump($rm->isInternal(1)); +var_dump($rm->isUserDefined(1)); +var_dump($rm->getFileName(1)); +var_dump($rm->getStartLine(1)); +var_dump($rm->getEndLine(1)); +var_dump($rm->getStaticVariables(1)); +var_dump($rm->getName(1)); + + +?> +--EXPECTF-- +Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 0 given in %s on line %d +object(ReflectionMethod)#%d (2) { + ["name"]=> + string(0) "" + ["class"]=> + string(0) "" +} + +Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 3 given in %s on line %d +object(ReflectionMethod)#%d (2) { + ["name"]=> + string(0) "" + ["class"]=> + string(0) "" +} + +Warning: ReflectionMethod::isFinal() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isAbstract() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isPrivate() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isProtected() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isPublic() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isStatic() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isConstructor() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::isDestructor() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::isInternal() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::isUserDefined() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::getFileName() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::getStartLine() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::getEndLine() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::getStaticVariables() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionFunctionAbstract::getName() expects exactly 0 parameters, 1 given in %s on line %d +NULL diff --git a/ext/reflection/tests/ReflectionMethod_basic1.phpt b/ext/reflection/tests/ReflectionMethod_basic1.phpt new file mode 100644 index 0000000..75ab957 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_basic1.phpt @@ -0,0 +1,298 @@ +--TEST-- +ReflectionMethod class - various methods +--FILE-- +<?php + +function reflectMethod($class, $method) { + $methodInfo = new ReflectionMethod($class, $method); + echo "**********************************\n"; + echo "Reflecting on method $class::$method()\n\n"; + echo "\nisFinal():\n"; + var_dump($methodInfo->isFinal()); + echo "\nisAbstract():\n"; + var_dump($methodInfo->isAbstract()); + echo "\nisPublic():\n"; + var_dump($methodInfo->isPublic()); + echo "\nisPrivate():\n"; + var_dump($methodInfo->isPrivate()); + echo "\nisProtected():\n"; + var_dump($methodInfo->isProtected()); + echo "\nisStatic():\n"; + var_dump($methodInfo->isStatic()); + echo "\nisConstructor():\n"; + var_dump($methodInfo->isConstructor()); + echo "\nisDestructor():\n"; + var_dump($methodInfo->isDestructor()); + echo "\n**********************************\n"; +} + +class TestClass +{ + public function foo() { + echo "Called foo()\n"; + } + + static function stat() { + echo "Called stat()\n"; + } + + private function priv() { + echo "Called priv()\n"; + } + + protected function prot() {} + + public function __destruct() {} +} + +class DerivedClass extends TestClass {} + +interface TestInterface { + public function int(); +} + +reflectMethod("DerivedClass", "foo"); +reflectMethod("TestClass", "stat"); +reflectMethod("TestClass", "priv"); +reflectMethod("TestClass", "prot"); +reflectMethod("DerivedClass", "prot"); +reflectMethod("TestInterface", "int"); +reflectMethod("ReflectionProperty", "__construct"); +reflectMethod("TestClass", "__destruct"); + +?> +--EXPECT-- +********************************** +Reflecting on method DerivedClass::foo() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(true) + +isPrivate(): +bool(false) + +isProtected(): +bool(false) + +isStatic(): +bool(false) + +isConstructor(): +bool(false) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method TestClass::stat() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(true) + +isPrivate(): +bool(false) + +isProtected(): +bool(false) + +isStatic(): +bool(true) + +isConstructor(): +bool(false) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method TestClass::priv() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(false) + +isPrivate(): +bool(true) + +isProtected(): +bool(false) + +isStatic(): +bool(false) + +isConstructor(): +bool(false) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method TestClass::prot() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(false) + +isPrivate(): +bool(false) + +isProtected(): +bool(true) + +isStatic(): +bool(false) + +isConstructor(): +bool(false) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method DerivedClass::prot() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(false) + +isPrivate(): +bool(false) + +isProtected(): +bool(true) + +isStatic(): +bool(false) + +isConstructor(): +bool(false) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method TestInterface::int() + + +isFinal(): +bool(false) + +isAbstract(): +bool(true) + +isPublic(): +bool(true) + +isPrivate(): +bool(false) + +isProtected(): +bool(false) + +isStatic(): +bool(false) + +isConstructor(): +bool(false) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method ReflectionProperty::__construct() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(true) + +isPrivate(): +bool(false) + +isProtected(): +bool(false) + +isStatic(): +bool(false) + +isConstructor(): +bool(true) + +isDestructor(): +bool(false) + +********************************** +********************************** +Reflecting on method TestClass::__destruct() + + +isFinal(): +bool(false) + +isAbstract(): +bool(false) + +isPublic(): +bool(true) + +isPrivate(): +bool(false) + +isProtected(): +bool(false) + +isStatic(): +bool(false) + +isConstructor(): +bool(false) + +isDestructor(): +bool(true) + +********************************** + + diff --git a/ext/reflection/tests/ReflectionMethod_basic2.phpt b/ext/reflection/tests/ReflectionMethod_basic2.phpt new file mode 100644 index 0000000..c91af67 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_basic2.phpt @@ -0,0 +1,188 @@ +--TEST-- +ReflectionMethod class __toString() and export() methods +--FILE-- +<?php + +function reflectMethod($class, $method) { + $methodInfo = new ReflectionMethod($class, $method); + echo "**********************************\n"; + echo "Reflecting on method $class::$method()\n\n"; + echo "__toString():\n"; + var_dump($methodInfo->__toString()); + echo "\nexport():\n"; + var_dump(ReflectionMethod::export($class, $method, true)); + echo "\n**********************************\n"; +} + +class TestClass +{ + public function foo() { + echo "Called foo()\n"; + } + + static function stat() { + echo "Called stat()\n"; + } + + private function priv() { + echo "Called priv()\n"; + } + + protected function prot() {} + + public function __destruct() {} +} + +class DerivedClass extends TestClass {} + +interface TestInterface { + public function int(); +} + +reflectMethod("DerivedClass", "foo"); +reflectMethod("TestClass", "stat"); +reflectMethod("TestClass", "priv"); +reflectMethod("TestClass", "prot"); +reflectMethod("DerivedClass", "prot"); +reflectMethod("TestInterface", "int"); +reflectMethod("ReflectionProperty", "__construct"); +reflectMethod("TestClass", "__destruct"); + +?> +--EXPECTF-- +********************************** +Reflecting on method DerivedClass::foo() + +__toString(): +string(%d) "Method [ <user, inherits TestClass> public method foo ] { + @@ %s 16 - 18 +} +" + +export(): +string(%d) "Method [ <user, inherits TestClass> public method foo ] { + @@ %s 16 - 18 +} +" + +********************************** +********************************** +Reflecting on method TestClass::stat() + +__toString(): +string(%d) "Method [ <user> static public method stat ] { + @@ %s 20 - 22 +} +" + +export(): +string(%d) "Method [ <user> static public method stat ] { + @@ %s 20 - 22 +} +" + +********************************** +********************************** +Reflecting on method TestClass::priv() + +__toString(): +string(%d) "Method [ <user> private method priv ] { + @@ %s 24 - 26 +} +" + +export(): +string(%d) "Method [ <user> private method priv ] { + @@ %s 24 - 26 +} +" + +********************************** +********************************** +Reflecting on method TestClass::prot() + +__toString(): +string(%d) "Method [ <user> protected method prot ] { + @@ %s 28 - 28 +} +" + +export(): +string(%d) "Method [ <user> protected method prot ] { + @@ %s 28 - 28 +} +" + +********************************** +********************************** +Reflecting on method DerivedClass::prot() + +__toString(): +string(%d) "Method [ <user, inherits TestClass> protected method prot ] { + @@ %s 28 - 28 +} +" + +export(): +string(%d) "Method [ <user, inherits TestClass> protected method prot ] { + @@ %s 28 - 28 +} +" + +********************************** +********************************** +Reflecting on method TestInterface::int() + +__toString(): +string(%d) "Method [ <user> abstract public method int ] { + @@ %s 36 - 36 +} +" + +export(): +string(%d) "Method [ <user> abstract public method int ] { + @@ %s 36 - 36 +} +" + +********************************** +********************************** +Reflecting on method ReflectionProperty::__construct() + +__toString(): +string(%d) "Method [ <internal:Reflection, ctor> public method __construct ] { + + - Parameters [2] { + Parameter #0 [ <required> $class ] + Parameter #1 [ <required> $name ] + } +} +" + +export(): +string(%d) "Method [ <internal:Reflection, ctor> public method __construct ] { + + - Parameters [2] { + Parameter #0 [ <required> $class ] + Parameter #1 [ <required> $name ] + } +} +" + +********************************** +********************************** +Reflecting on method TestClass::__destruct() + +__toString(): +string(%d) "Method [ <user, dtor> public method __destruct ] { + @@ %s 30 - 30 +} +" + +export(): +string(%d) "Method [ <user, dtor> public method __destruct ] { + @@ %s 30 - 30 +} +" + +********************************** diff --git a/ext/reflection/tests/ReflectionMethod_basic3.phpt b/ext/reflection/tests/ReflectionMethod_basic3.phpt new file mode 100644 index 0000000..7b65927 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_basic3.phpt @@ -0,0 +1,167 @@ +--TEST-- +ReflectionMethod class getName(), isInternal() and isUserDefined() methods +--FILE-- +<?php + +function reflectMethod($class, $method) { + $methodInfo = new ReflectionMethod($class, $method); + echo "**********************************\n"; + echo "Reflecting on method $class::$method()\n\n"; + echo "\ngetName():\n"; + var_dump($methodInfo->getName()); + echo "\nisInternal():\n"; + var_dump($methodInfo->isInternal()); + echo "\nisUserDefined():\n"; + var_dump($methodInfo->isUserDefined()); + echo "\n**********************************\n"; +} + +class TestClass +{ + public function foo() { + echo "Called foo()\n"; + } + + static function stat() { + echo "Called stat()\n"; + } + + private function priv() { + echo "Called priv()\n"; + } + + protected function prot() {} + + public function __destruct() {} +} + +class DerivedClass extends TestClass {} + +interface TestInterface { + public function int(); +} + +reflectMethod("DerivedClass", "foo"); +reflectMethod("TestClass", "stat"); +reflectMethod("TestClass", "priv"); +reflectMethod("TestClass", "prot"); +reflectMethod("DerivedClass", "prot"); +reflectMethod("TestInterface", "int"); +reflectMethod("ReflectionProperty", "__construct"); +reflectMethod("TestClass", "__destruct"); + + +?> +--EXPECT-- +********************************** +Reflecting on method DerivedClass::foo() + + +getName(): +string(3) "foo" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** +********************************** +Reflecting on method TestClass::stat() + + +getName(): +string(4) "stat" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** +********************************** +Reflecting on method TestClass::priv() + + +getName(): +string(4) "priv" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** +********************************** +Reflecting on method TestClass::prot() + + +getName(): +string(4) "prot" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** +********************************** +Reflecting on method DerivedClass::prot() + + +getName(): +string(4) "prot" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** +********************************** +Reflecting on method TestInterface::int() + + +getName(): +string(3) "int" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** +********************************** +Reflecting on method ReflectionProperty::__construct() + + +getName(): +string(11) "__construct" + +isInternal(): +bool(true) + +isUserDefined(): +bool(false) + +********************************** +********************************** +Reflecting on method TestClass::__destruct() + + +getName(): +string(10) "__destruct" + +isInternal(): +bool(false) + +isUserDefined(): +bool(true) + +********************************** diff --git a/ext/reflection/tests/ReflectionMethod_basic4.phpt b/ext/reflection/tests/ReflectionMethod_basic4.phpt new file mode 100644 index 0000000..82672e4 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_basic4.phpt @@ -0,0 +1,170 @@ +--TEST-- +ReflectionMethod class getFileName(), getStartLine() and getEndLine() methods +--FILE-- +<?php + +function reflectMethod($class, $method) { + $methodInfo = new ReflectionMethod($class, $method); + echo "**********************************\n"; + echo "Reflecting on method $class::$method()\n\n"; + echo "\ngetFileName():\n"; + var_dump($methodInfo->getFileName()); + echo "\ngetStartLine():\n"; + var_dump($methodInfo->getStartLine()); + echo "\ngetEndLine():\n"; + var_dump($methodInfo->getEndLine()); + echo "\n**********************************\n"; +} + +class TestClass +{ + public function foo() { + + + echo "Called foo()\n"; + + + } + + static function stat() { + echo "Called stat()\n"; + } + + private function priv() { + echo "Called priv()\n"; + } + + protected function prot() {} + + public function __destruct() {} +} + +class DerivedClass extends TestClass {} + +interface TestInterface { + public function int(); +} + +reflectMethod("DerivedClass", "foo"); +reflectMethod("TestClass", "stat"); +reflectMethod("TestClass", "priv"); +reflectMethod("TestClass", "prot"); +reflectMethod("DerivedClass", "prot"); +reflectMethod("TestInterface", "int"); +reflectMethod("ReflectionProperty", "__construct"); +reflectMethod("TestClass", "__destruct"); + +?> +--EXPECTF-- +********************************** +Reflecting on method DerivedClass::foo() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(18) + +getEndLine(): +int(24) + +********************************** +********************************** +Reflecting on method TestClass::stat() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(26) + +getEndLine(): +int(28) + +********************************** +********************************** +Reflecting on method TestClass::priv() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(30) + +getEndLine(): +int(32) + +********************************** +********************************** +Reflecting on method TestClass::prot() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(34) + +getEndLine(): +int(34) + +********************************** +********************************** +Reflecting on method DerivedClass::prot() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(34) + +getEndLine(): +int(34) + +********************************** +********************************** +Reflecting on method TestInterface::int() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(42) + +getEndLine(): +int(42) + +********************************** +********************************** +Reflecting on method ReflectionProperty::__construct() + + +getFileName(): +bool(false) + +getStartLine(): +bool(false) + +getEndLine(): +bool(false) + +********************************** +********************************** +Reflecting on method TestClass::__destruct() + + +getFileName(): +string(%d) "%sReflectionMethod_basic4.php" + +getStartLine(): +int(36) + +getEndLine(): +int(36) + +********************************** diff --git a/ext/reflection/tests/ReflectionMethod_constructor_basic.phpt b/ext/reflection/tests/ReflectionMethod_constructor_basic.phpt new file mode 100644 index 0000000..2a2f02f --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_constructor_basic.phpt @@ -0,0 +1,117 @@ +--TEST-- +ReflectionMethod::isConstructor() +--FILE-- +<?php + +class NewCtor { + function __construct() { + echo "In " . __METHOD__ . "\n"; + } + +} +echo "New-style constructor:\n"; +$methodInfo = new ReflectionMethod("NewCtor::__construct"); +var_dump($methodInfo->isConstructor()); + +class ExtendsNewCtor extends NewCtor { +} +echo "\nInherited new-style constructor\n"; +$methodInfo = new ReflectionMethod("ExtendsNewCtor::__construct"); +var_dump($methodInfo->isConstructor()); + +class OldCtor { + function OldCtor() { + echo "In " . __METHOD__ . "\n"; + } +} +echo "\nOld-style constructor:\n"; +$methodInfo = new ReflectionMethod("OldCtor::OldCtor"); +var_dump($methodInfo->isConstructor()); + +class ExtendsOldCtor extends OldCtor { +} +echo "\nInherited old-style constructor:\n"; +$methodInfo = new ReflectionMethod("ExtendsOldCtor::OldCtor"); +var_dump($methodInfo->isConstructor()); + +class X { + function Y() { + echo "In " . __METHOD__ . "\n"; + } +} +echo "\nNot a constructor:\n"; +$methodInfo = new ReflectionMethod("X::Y"); +var_dump($methodInfo->isConstructor()); + +class Y extends X { +} +echo "\nInherited method of the same name as the class:\n"; +$methodInfo = new ReflectionMethod("Y::Y"); +var_dump($methodInfo->isConstructor()); + +class OldAndNewCtor { + function OldAndNewCtor() { + echo "In " . __METHOD__ . "\n"; + } + + function __construct() { + echo "In " . __METHOD__ . "\n"; + } +} +echo "\nOld-style constructor:\n"; +$methodInfo = new ReflectionMethod("OldAndNewCtor::OldAndNewCtor"); +var_dump($methodInfo->isConstructor()); + +echo "\nRedefined constructor:\n"; +$methodInfo = new ReflectionMethod("OldAndNewCtor::__construct"); +var_dump($methodInfo->isConstructor()); + +class NewAndOldCtor { + function __construct() { + echo "In " . __METHOD__ . "\n"; + } + + function NewAndOldCtor() { + echo "In " . __METHOD__ . "\n"; + } +} +echo "\nNew-style constructor:\n"; +$methodInfo = new ReflectionMethod("NewAndOldCtor::__construct"); +var_dump($methodInfo->isConstructor()); + +echo "\nRedefined old-style constructor:\n"; +$methodInfo = new ReflectionMethod("NewAndOldCtor::NewAndOldCtor"); +var_dump($methodInfo->isConstructor()); + +?> +--EXPECTF-- +Strict Standards: Redefining already defined constructor for class OldAndNewCtor in %s on line %d +New-style constructor: +bool(true) + +Inherited new-style constructor +bool(true) + +Old-style constructor: +bool(true) + +Inherited old-style constructor: +bool(true) + +Not a constructor: +bool(false) + +Inherited method of the same name as the class: +bool(false) + +Old-style constructor: +bool(false) + +Redefined constructor: +bool(true) + +New-style constructor: +bool(true) + +Redefined old-style constructor: +bool(false) diff --git a/ext/reflection/tests/ReflectionMethod_constructor_error1.phpt b/ext/reflection/tests/ReflectionMethod_constructor_error1.phpt new file mode 100644 index 0000000..7052825 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_constructor_error1.phpt @@ -0,0 +1,103 @@ +--TEST-- +ReflectionMethod constructor errors +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +class TestClass +{ + public function foo() { + } +} + + +try { + echo "\nWrong type of argument (bool):\n"; + $methodInfo = new ReflectionMethod(true); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nWrong type of argument (int):\n"; + $methodInfo = new ReflectionMethod(3); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nWrong type of argument (bool, string):\n"; + $methodInfo = new ReflectionMethod(true, "foo"); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nWrong type of argument (string, bool):\n"; + $methodInfo = new ReflectionMethod('TestClass', true); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nNo method given:\n"; + $methodInfo = new ReflectionMethod("TestClass"); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nClass and Method in same string, bad method name:\n"; + $methodInfo = new ReflectionMethod("TestClass::foop::dedoop"); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nClass and Method in same string, bad class name:\n"; + $methodInfo = new ReflectionMethod("TestCla::foo"); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nClass and Method in same string (ok):\n"; + $methodInfo = new ReflectionMethod("TestClass::foo"); +} catch (Exception $e) { + print $e->__toString(); +} + +?> +--EXPECTF-- +Wrong type of argument (bool): +exception 'ReflectionException' with message 'Invalid method name 1' in %s +Stack trace: +#0 %s ReflectionMethod->__construct('1') +#1 {main} +Wrong type of argument (int): +exception 'ReflectionException' with message 'Invalid method name 3' in %s +Stack trace: +#0 %s ReflectionMethod->__construct('3') +#1 {main} +Wrong type of argument (bool, string): +exception 'ReflectionException' with message 'The parameter class is expected to be either a string or an object' in %s +Stack trace: +#0 %s ReflectionMethod->__construct(true, 'foo') +#1 {main} +Wrong type of argument (string, bool): +exception 'ReflectionException' with message 'Method TestClass::1() does not exist' in %s +Stack trace: +#0 %s ReflectionMethod->__construct('TestClass', '1') +#1 {main} +No method given: +exception 'ReflectionException' with message 'Invalid method name TestClass' in %s +Stack trace: +#0 %s ReflectionMethod->__construct('TestClass') +#1 {main} +Class and Method in same string, bad method name: +exception 'ReflectionException' with message 'Method TestClass::foop::dedoop() does not exist' in %s +Stack trace: +#0 %s ReflectionMethod->__construct('TestClass::foop...') +#1 {main} +Class and Method in same string, bad class name: +exception 'ReflectionException' with message 'Class TestCla does not exist' in %s +Stack trace: +#0 %s ReflectionMethod->__construct('TestCla::foo') +#1 {main} +Class and Method in same string (ok): + diff --git a/ext/reflection/tests/ReflectionMethod_constructor_error2.phpt b/ext/reflection/tests/ReflectionMethod_constructor_error2.phpt new file mode 100644 index 0000000..1c2d3a1 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_constructor_error2.phpt @@ -0,0 +1,37 @@ +--TEST-- +ReflectionMethod constructor errors +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +class TestClass +{ + public function foo() { + } +} + + +try { + echo "Too few arguments:\n"; + $methodInfo = new ReflectionMethod(); +} catch (Exception $e) { + print $e->__toString(); +} +try { + echo "\nToo many arguments:\n"; + $methodInfo = new ReflectionMethod("TestClass", "foo", true); +} catch (Exception $e) { + print $e->__toString(); +} + +?> +--EXPECTF-- +Too few arguments: + +Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 0 given in %s on line 12 + +Too many arguments: + +Warning: ReflectionMethod::__construct() expects exactly 1 parameter, 3 given in %s on line 18 diff --git a/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt b/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt new file mode 100644 index 0000000..58c0999 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getClosureThis.phpt @@ -0,0 +1,53 @@ +--TEST-- +Reflection::getClosureThis() +--SKIPIF-- +<?php +if (!extension_loaded('reflection') || !defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) { + print 'skip'; +} +?> +--FILE-- +<?php +class StaticExample +{ + static function foo() + { + var_dump( "Static Example class, Hello World!" ); + } +} + +class Example +{ + public $bar = 42; + public function foo() + { + var_dump( "Example class, bar: " . $this->bar ); + } +} + +// Initialize classes +$class = new ReflectionClass( 'Example' ); +$staticclass = new ReflectionClass( 'StaticExample' ); +$object = new Example(); + +$method = $staticclass->getMethod( 'foo' ); +$closure = $method->getClosure(); +$rf = new ReflectionFunction($closure); + +var_dump($rf->getClosureThis()); + +$method = $class->getMethod( 'foo' ); + +$closure = $method->getClosure( $object ); +$rf = new ReflectionFunction($closure); + +var_dump($rf->getClosureThis()); + +echo "Done!\n"; +--EXPECTF-- +NULL +object(Example)#%d (1) { + ["bar"]=> + int(42) +} +Done! diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt new file mode 100644 index 0000000..c97c41c --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test ReflectionMethod::getClosure() function : basic functionality +--FILE-- +<?php +/* Prototype : public mixed ReflectionFunction::getClosure() + * Description: Returns a dynamically created closure for the method + * Source code: ext/reflection/php_reflection.c + * Alias to functions: + */ + +echo "*** Testing ReflectionMethod::getClosure() : basic functionality ***\n"; + +class StaticExample +{ + static function foo() + { + var_dump( "Static Example class, Hello World!" ); + } +} + +class Example +{ + public $bar = 42; + public function foo() + { + var_dump( "Example class, bar: " . $this->bar ); + } +} + +// Initialize classes +$class = new ReflectionClass( 'Example' ); +$staticclass = new ReflectionClass( 'StaticExample' ); +$object = new Example(); +$fakeobj = new StdClass(); + + +$method = $staticclass->getMethod( 'foo' ); +$closure = $method->getClosure(); +$closure(); + +$method = $class->getMethod( 'foo' ); + +$closure = $method->getClosure( $object ); +$closure(); +$object->bar = 34; +$closure(); + +?> +===DONE=== +--EXPECTF-- +*** Testing ReflectionMethod::getClosure() : basic functionality *** +string(34) "Static Example class, Hello World!" +string(22) "Example class, bar: 42" +string(22) "Example class, bar: 34" +===DONE=== diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt new file mode 100644 index 0000000..d3b9ca3 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt @@ -0,0 +1,73 @@ +--TEST-- +Test ReflectionMethod::getClosure() function : error functionality +--FILE-- +<?php +/* Prototype : public mixed ReflectionFunction::getClosure() + * Description: Returns a dynamically created closure for the method + * Source code: ext/reflection/php_reflection.c + * Alias to functions: + */ + +echo "*** Testing ReflectionMethod::getClosure() : error conditions ***\n"; + +class StaticExample +{ + static function foo() + { + var_dump( "Static Example class, Hello World!" ); + } +} + +class Example +{ + public $bar = 42; + public function foo() + { + var_dump( "Example class, bar: " . $this->bar ); + } +} + +// Initialize classes +$class = new ReflectionClass( 'Example' ); +$staticclass = new ReflectionClass( 'StaticExample' ); +$method = $class->getMethod( 'foo' ); +$staticmethod = $staticclass->getMethod( 'foo' ); +$object = new Example(); +$fakeobj = new StdClass(); + +echo "\n-- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --\n"; +var_dump( $staticmethod->getClosure( 'foobar' ) ); +var_dump( $staticmethod->getClosure( 'foo', 'bar' ) ); +var_dump( $method->getClosure( $object, 'foobar' ) ); + +echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n"; +$closure = $method->getClosure(); + +echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n"; +try { + var_dump( $method->getClosure( $fakeobj ) ); +} catch( Exception $e ) { + var_dump( $e->getMessage() ); +} + +?> +===DONE=== +--EXPECTF-- +*** Testing ReflectionMethod::getClosure() : error conditions *** + +-- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments -- +object(Closure)#%d (0) { +} +object(Closure)#%d (0) { +} + +Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 2 given in %s on line %d +NULL + +-- Testing ReflectionMethod::getClosure() function with Zero arguments -- + +Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 0 given in %s on line %d + +-- Testing ReflectionMethod::getClosure() function with Zero arguments -- +string(72) "Given object is not an instance of the class this method was declared in" +===DONE=== diff --git a/ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt b/ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt new file mode 100644 index 0000000..6afc700 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getDeclaringClass_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +ReflectionMethod::getDeclaringClass() +--FILE-- +<?php + +class A { + function foo() {} +} + +class B extends A { + function bar() {} +} + +$methodInfo = new ReflectionMethod('B', 'foo'); +var_dump($methodInfo->getDeclaringClass()); + +$methodInfo = new ReflectionMethod('B', 'bar'); +var_dump($methodInfo->getDeclaringClass()); + +?> +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "A" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "B" +} + diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt new file mode 100644 index 0000000..c01f689 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt @@ -0,0 +1,113 @@ +--TEST-- +ReflectionMethod::getDocComment() +--FILE-- +<?php +/** + * My Doc Comment for A + */ +class A { + /** + * My Doc Comment for A::f + */ + function f() {} + + /** + * My Doc Comment for A::privf + */ + private function privf() {} + + /** My Doc Comment for A::protStatf */ + protected static function protStatf() {} + + /** + + * My Doc Comment for A::finalStatPubf + */ + final static public function finalStatPubf() {} + +} + + +class B extends A { + /*** Not a doc comment */ + function f() {} + + /** * + * My Doc Comment for B::privf + */ + + + + + private function privf() {} + + + /** My Doc Comment for B::protStatf + + + + + */ + protected static function protStatf() {} + +} + +foreach (array('A', 'B') as $class) { + $rc = new ReflectionClass($class); + $rms = $rc->getMethods(); + foreach ($rms as $rm) { + echo "\n\n---> Doc comment for $class::" . $rm->getName() . "():\n"; + var_dump($rm->getDocComment()); + } +} +?> +--EXPECTF-- + + +---> Doc comment for A::f(): +string(%d) "/** + * My Doc Comment for A::f + */" + + +---> Doc comment for A::privf(): +string(%d) "/** + * My Doc Comment for A::privf + */" + + +---> Doc comment for A::protStatf(): +string(%d) "/** My Doc Comment for A::protStatf */" + + +---> Doc comment for A::finalStatPubf(): +string(%d) "/** + + * My Doc Comment for A::finalStatPubf + */" + + +---> Doc comment for B::f(): +bool(false) + + +---> Doc comment for B::privf(): +string(%d) "/** * + * My Doc Comment for B::privf + */" + + +---> Doc comment for B::protStatf(): +string(%d) "/** My Doc Comment for B::protStatf + + + + + */" + + +---> Doc comment for B::finalStatPubf(): +string(%d) "/** + + * My Doc Comment for A::finalStatPubf + */" diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt new file mode 100644 index 0000000..02de25b --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getDocComment_error.phpt @@ -0,0 +1,15 @@ +--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 new file mode 100644 index 0000000..72baa53 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getModifiers_basic.phpt @@ -0,0 +1,242 @@ +--TEST-- +ReflectionMethod::getModifiers() +--FILE-- +<?php + +function reflectMethodModifiers($class) { + $classInfo = new reflectionClass($class); + $methodArray = $classInfo->getMethods(); + + foreach ($methodArray as $method) { + echo "Modifiers for method $method->class::$method->name():\n"; + printf("0x%08x\n", $method->getModifiers()); + echo "\n\n"; + } +} + +class TestClass +{ + public function foo() { + echo "Called foo()\n"; + } + + static function stat() { + echo "Called stat()\n"; + } + + private function priv() { + echo "Called priv()\n"; + } + + protected function prot() {} + + public final function fin() {} + + public function __destruct() {} + + public function __call($a, $b) {} + + public function __clone() {} + + public function __get($a) {} + + public function __set($a, $b) {} + + public function __unset($a) {} + + public function __isset($a) {} + + public function __tostring() {} + + public function __sleep() {} + + public function __wakeup() {} + + public function __set_state() {} + + public function __autoload() {} +} + +class DerivedClass extends TestClass {} + +interface TestInterface { + public function int(); + public function __clone(); +} + +abstract class AbstractClass { + public abstract function foo(); +} + + + +reflectMethodModifiers("TestClass"); +reflectMethodModifiers("DerivedClass"); +reflectMethodModifiers("TestInterface"); +reflectMethodModifiers("AbstractClass"); + +echo "Wrong number of params:\n"; +$a = new ReflectionMethod('TestClass::foo'); +$a->getModifiers(1); + +$a = new ReflectionMethod('ReflectionMethod::getModifiers'); + +echo "\nReflectionMethod::getModifiers() modifiers:\n"; +printf("0x%08x\n", $a->getModifiers()); + +?> +--EXPECTF-- +Modifiers for method TestClass::foo(): +0x08010100 + + +Modifiers for method TestClass::stat(): +0x08000101 + + +Modifiers for method TestClass::priv(): +0x08010400 + + +Modifiers for method TestClass::prot(): +0x08010200 + + +Modifiers for method TestClass::fin(): +0x08010104 + + +Modifiers for method TestClass::__destruct(): +0x08004100 + + +Modifiers for method TestClass::__call(): +0x08000100 + + +Modifiers for method TestClass::__clone(): +0x08008100 + + +Modifiers for method TestClass::__get(): +0x08000100 + + +Modifiers for method TestClass::__set(): +0x08000100 + + +Modifiers for method TestClass::__unset(): +0x08000100 + + +Modifiers for method TestClass::__isset(): +0x08000100 + + +Modifiers for method TestClass::__tostring(): +0x08000100 + + +Modifiers for method TestClass::__sleep(): +0x08010100 + + +Modifiers for method TestClass::__wakeup(): +0x08010100 + + +Modifiers for method TestClass::__set_state(): +0x08010100 + + +Modifiers for method TestClass::__autoload(): +0x08010100 + + +Modifiers for method TestClass::foo(): +0x08010100 + + +Modifiers for method TestClass::stat(): +0x08000101 + + +Modifiers for method TestClass::priv(): +0x08010400 + + +Modifiers for method TestClass::prot(): +0x08010200 + + +Modifiers for method TestClass::fin(): +0x08010104 + + +Modifiers for method TestClass::__destruct(): +0x08004100 + + +Modifiers for method TestClass::__call(): +0x08000100 + + +Modifiers for method TestClass::__clone(): +0x08008100 + + +Modifiers for method TestClass::__get(): +0x08000100 + + +Modifiers for method TestClass::__set(): +0x08000100 + + +Modifiers for method TestClass::__unset(): +0x08000100 + + +Modifiers for method TestClass::__isset(): +0x08000100 + + +Modifiers for method TestClass::__tostring(): +0x08000100 + + +Modifiers for method TestClass::__sleep(): +0x08010100 + + +Modifiers for method TestClass::__wakeup(): +0x08010100 + + +Modifiers for method TestClass::__set_state(): +0x08010100 + + +Modifiers for method TestClass::__autoload(): +0x08010100 + + +Modifiers for method TestInterface::int(): +0x08000102 + + +Modifiers for method TestInterface::__clone(): +0x08000102 + + +Modifiers for method AbstractClass::foo(): +0x08010102 + + +Wrong number of params: + +Warning: ReflectionMethod::getModifiers() expects exactly 0 parameters, 1 given in %sReflectionMethod_getModifiers_basic.php on line %d + +ReflectionMethod::getModifiers() modifiers: +0x00000100 diff --git a/ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt b/ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt new file mode 100644 index 0000000..4c50b96 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getStaticVariables_basic.phpt @@ -0,0 +1,63 @@ +--TEST-- +ReflectionMethod::getStaticVariables() +--FILE-- +<?php + +class TestClass { + public function foo() { + static $c; + static $a = 1; + static $b = "hello"; + $d = 5; + } + + private function bar() { + static $a = 1; + } + + public function noStatics() { + $a = 54; + } +} + +echo "Public method:\n"; +$methodInfo = new ReflectionMethod('TestClass::foo'); +var_dump($methodInfo->getStaticVariables()); + +echo "\nPrivate method:\n"; +$methodInfo = new ReflectionMethod('TestClass::bar'); +var_dump($methodInfo->getStaticVariables()); + +echo "\nMethod with no static variables:\n"; +$methodInfo = new ReflectionMethod('TestClass::noStatics'); +var_dump($methodInfo->getStaticVariables()); + +echo "\nInternal Method:\n"; +$methodInfo = new ReflectionMethod('ReflectionClass::getName'); +var_dump($methodInfo->getStaticVariables()); + +?> +--EXPECT-- +Public method: +array(3) { + ["c"]=> + NULL + ["a"]=> + int(1) + ["b"]=> + string(5) "hello" +} + +Private method: +array(1) { + ["a"]=> + int(1) +} + +Method with no static variables: +array(0) { +} + +Internal Method: +array(0) { +} diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt new file mode 100644 index 0000000..24282cd --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_basic.phpt @@ -0,0 +1,73 @@ +--TEST-- +ReflectionMethod::invokeArgs() +--FILE-- +<?php + +class TestClass { + public $prop = 2; + + public function foo() { + echo "Called foo(), property = $this->prop\n"; + var_dump($this); + return "Return Val"; + } + + public function willThrow() { + throw new Exception("Called willThrow()"); + } + + public function methodWithArgs($a, $b) { + echo "Called methodWithArgs($a, $b)\n"; + } +} + + +$testClassInstance = new TestClass(); +$testClassInstance->prop = "Hello"; + +$foo = new ReflectionMethod($testClassInstance, 'foo'); +$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs'); +$methodThatThrows = new ReflectionMethod("TestClass::willThrow"); + + +echo "Public method:\n"; + +var_dump($foo->invokeArgs($testClassInstance, array())); +var_dump($foo->invokeArgs($testClassInstance, array(true))); + +echo "\nMethod with args:\n"; + +var_dump($methodWithArgs->invokeArgs($testClassInstance, array(1, "arg2"))); +var_dump($methodWithArgs->invokeArgs($testClassInstance, array(1, "arg2", 3))); + +echo "\nMethod that throws an exception:\n"; +try { + $methodThatThrows->invokeArgs($testClassInstance, array()); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +?> +--EXPECTF-- +Public method: +Called foo(), property = Hello +object(TestClass)#%d (1) { + ["prop"]=> + string(5) "Hello" +} +string(10) "Return Val" +Called foo(), property = Hello +object(TestClass)#%d (1) { + ["prop"]=> + string(5) "Hello" +} +string(10) "Return Val" + +Method with args: +Called methodWithArgs(1, arg2) +NULL +Called methodWithArgs(1, arg2) +NULL + +Method that throws an exception: +string(18) "Called willThrow()" diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt new file mode 100644 index 0000000..ac97e3e --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error1.phpt @@ -0,0 +1,36 @@ +--TEST-- +ReflectionMethod:invokeArgs() errors +--FILE-- +<?php + +class TestClass { + + public function methodWithArgs($a, $b) { + echo "Called methodWithArgs($a, $b)\n"; + } +} + +abstract class AbstractClass { + abstract function foo(); +} + +$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs'); + +$testClassInstance = new TestClass(); + +echo "\nMethod with args:\n"; +var_dump($methodWithArgs->invokeArgs($testClassInstance, array())); + +?> +--EXPECTF-- +Method with args: + +Warning: Missing argument 1 for TestClass::methodWithArgs() in %s on line %d + +Warning: Missing argument 2 for TestClass::methodWithArgs() in %s on line %d + +Notice: Undefined variable: a in %s on line %d + +Notice: Undefined variable: b in %s on line %d +Called methodWithArgs(, ) +NULL diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt new file mode 100644 index 0000000..5fc7564 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error2.phpt @@ -0,0 +1,27 @@ +--TEST-- +ReflectionMethod::invokeArgs() further errors +--FILE-- +<?php + +class TestClass { + + public function foo() { + echo "Called foo()\n"; + var_dump($this); + return "Return Val"; + } +} + +$foo = new ReflectionMethod('TestClass', 'foo'); + +$testClassInstance = new TestClass(); + +try { + var_dump($foo->invokeArgs($testClassInstance, true)); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +?> +--EXPECTF-- +Catchable fatal error: Argument 2 passed to ReflectionMethod::invokeArgs() must be of the type array, boolean given in %s on line %d diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt new file mode 100644 index 0000000..513cc18 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt @@ -0,0 +1,117 @@ +--TEST-- +ReflectionMethod::invokeArgs() further errors +--FILE-- +<?php + +class TestClass { + public $prop = 2; + + public function foo() { + echo "Called foo(), property = $this->prop\n"; + var_dump($this); + return "Return Val"; + } + + public static function staticMethod() { + echo "Called staticMethod()\n"; + var_dump($this); + } + + private static function privateMethod() { + echo "Called privateMethod()\n"; + } +} + +abstract class AbstractClass { + abstract function foo(); +} + +$testClassInstance = new TestClass(); +$testClassInstance->prop = "Hello"; + +$foo = new ReflectionMethod($testClassInstance, 'foo'); +$staticMethod = new ReflectionMethod('TestClass::staticMethod'); +$privateMethod = new ReflectionMethod("TestClass::privateMethod"); + +echo "Wrong number of parameters:\n"; +var_dump($foo->invokeArgs()); +var_dump($foo->invokeArgs(true)); + +echo "\nNon-instance:\n"; +try { + var_dump($foo->invokeArgs(new stdClass(), array())); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +echo "\nNon-object:\n"; +var_dump($foo->invokeArgs(true, array())); + +echo "\nStatic method:\n"; + +var_dump($staticMethod->invokeArgs()); +var_dump($staticMethod->invokeArgs(true)); +var_dump($staticMethod->invokeArgs(true, array())); +var_dump($staticMethod->invokeArgs(null, array())); + +echo "\nPrivate method:\n"; +try { + var_dump($privateMethod->invokeArgs($testClassInstance, array())); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +echo "\nAbstract method:\n"; +$abstractMethod = new ReflectionMethod("AbstractClass::foo"); +try { + $abstractMethod->invokeArgs($testClassInstance, array()); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} +try { + $abstractMethod->invokeArgs(true); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +?> +--EXPECTF-- +Wrong number of parameters: + +Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 0 given in %s on line %d +NULL + +Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Non-instance: +string(72) "Given object is not an instance of the class this method was declared in" + +Non-object: + +Warning: ReflectionMethod::invokeArgs() expects parameter 1 to be object, boolean given in %s on line %d +NULL + +Static method: + +Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 0 given in %s on line %d +NULL + +Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionMethod::invokeArgs() expects parameter 1 to be object, boolean given in %s on line %d +NULL +Called staticMethod() + +Notice: Undefined variable: this in %s on line %d +NULL +NULL + +Private method: +string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod" + +Abstract method: +string(53) "Trying to invoke abstract method AbstractClass::foo()" + +Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt b/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt new file mode 100644 index 0000000..cbf358c --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invoke_basic.phpt @@ -0,0 +1,108 @@ +--TEST-- +ReflectionMethod::invoke() +--FILE-- +<?php + +class TestClass { + public $prop = 2; + + public function foo() { + echo "Called foo(), property = $this->prop\n"; + var_dump($this); + return "Return Val"; + } + + public function willThrow() { + throw new Exception("Called willThrow()"); + } + + public function methodWithArgs($a, $b) { + echo "Called methodWithArgs($a, $b)\n"; + } + + public static function staticMethod() { + echo "Called staticMethod()\n"; + var_dump($this); + } + + private static function privateMethod() { + echo "Called privateMethod()\n"; + } +} + +abstract class AbstractClass { + abstract function foo(); +} + +$foo = new ReflectionMethod('TestClass', 'foo'); +$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs'); +$staticMethod = new ReflectionMethod('TestClass::staticMethod'); +$privateMethod = new ReflectionMethod("TestClass::privateMethod"); +$methodThatThrows = new ReflectionMethod("TestClass::willThrow"); + +$testClassInstance = new TestClass(); +$testClassInstance->prop = "Hello"; + +echo "Public method:\n"; + +var_dump($foo->invoke($testClassInstance)); + +var_dump($foo->invoke($testClassInstance, true)); + +echo "\nMethod with args:\n"; + +var_dump($methodWithArgs->invoke($testClassInstance, 1, "arg2")); +var_dump($methodWithArgs->invoke($testClassInstance, 1, "arg2", 3)); + +echo "\nStatic method:\n"; + +var_dump($staticMethod->invoke()); +var_dump($staticMethod->invoke(true)); +var_dump($staticMethod->invoke(new stdClass())); + +echo "\nMethod that throws an exception:\n"; +try { + var_dump($methodThatThrows->invoke($testClassInstance)); +} catch (Exception $exc) { + var_dump($exc->getMessage()); +} + +?> +--EXPECTF-- +Public method: +Called foo(), property = Hello +object(TestClass)#%d (1) { + ["prop"]=> + string(5) "Hello" +} +string(10) "Return Val" +Called foo(), property = Hello +object(TestClass)#%d (1) { + ["prop"]=> + string(5) "Hello" +} +string(10) "Return Val" + +Method with args: +Called methodWithArgs(1, arg2) +NULL +Called methodWithArgs(1, arg2) +NULL + +Static method: + +Warning: ReflectionMethod::invoke() expects at least 1 parameter, 0 given in %s on line %d +NULL +Called staticMethod() + +Notice: Undefined variable: this in %s on line %d +NULL +NULL +Called staticMethod() + +Notice: Undefined variable: this in %s on line %d +NULL +NULL + +Method that throws an exception: +string(18) "Called willThrow()" diff --git a/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt new file mode 100644 index 0000000..758f1ac --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt @@ -0,0 +1,71 @@ +--TEST-- +ReflectionMethod::invoke() errors +--FILE-- +<?php + +class TestClass { + public $prop = 2; + + public function foo() { + echo "Called foo(), property = $this->prop\n"; + var_dump($this); + return "Return Val"; + } + + private static function privateMethod() { + echo "Called privateMethod()\n"; + } +} + +abstract class AbstractClass { + abstract function foo(); +} + +$foo = new ReflectionMethod('TestClass', 'foo'); +$privateMethod = new ReflectionMethod("TestClass::privateMethod"); + +$testClassInstance = new TestClass(); +$testClassInstance->prop = "Hello"; + +echo "invoke() on a non-object:\n"; +try { + var_dump($foo->invoke(true)); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +echo "\ninvoke() on a non-instance:\n"; +try { + var_dump($foo->invoke(new stdClass())); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +echo "\nPrivate method:\n"; +try { + var_dump($privateMethod->invoke($testClassInstance)); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +echo "\nAbstract method:\n"; +$abstractMethod = new ReflectionMethod("AbstractClass::foo"); +try { + $abstractMethod->invoke(true); +} catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +?> +--EXPECTF-- +invoke() on a non-object: +string(29) "Non-object passed to Invoke()" + +invoke() on a non-instance: +string(72) "Given object is not an instance of the class this method was declared in" + +Private method: +string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod" + +Abstract method: +string(53) "Trying to invoke abstract method AbstractClass::foo()" diff --git a/ext/reflection/tests/ReflectionMethod_invoke_error2.phpt b/ext/reflection/tests/ReflectionMethod_invoke_error2.phpt new file mode 100644 index 0000000..a070c8f --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_invoke_error2.phpt @@ -0,0 +1,32 @@ +--TEST-- +ReflectionMethod::invoke() further errors +--FILE-- +<?php + +class TestClass { + + public function methodWithArgs($a, $b) { + echo "Called methodWithArgs($a, $b)\n"; + } +} + +$methodWithArgs = new ReflectionMethod('TestClass', 'methodWithArgs'); + +$testClassInstance = new TestClass(); + +echo "\nMethod with args:\n"; +var_dump($methodWithArgs->invoke($testClassInstance)); + +?> +--EXPECTF-- +Method with args: + +Warning: Missing argument 1 for TestClass::methodWithArgs() in %s on line %d + +Warning: Missing argument 2 for TestClass::methodWithArgs() in %s on line %d + +Notice: Undefined variable: a in %s on line %d + +Notice: Undefined variable: b in %s on line %d +Called methodWithArgs(, ) +NULL diff --git a/ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt b/ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt new file mode 100644 index 0000000..f1fd205 --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_returnsReference_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionMethod::returnsReference() +--FILE-- +<?php + +class TestClass { + public function &foo() { + } + + private function bar() { + } +} + +$methodInfo = new ReflectionMethod('TestClass::foo'); +var_dump($methodInfo->returnsReference()); + +$methodInfo = new ReflectionMethod('TestClass::bar'); +var_dump($methodInfo->returnsReference()); + +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt new file mode 100644 index 0000000..79a8fbe --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt @@ -0,0 +1,111 @@ +--TEST-- +Test ReflectionMethod::setAccessible(). +--FILE-- +<?php +class A { + private function aPrivate($a) { print __METHOD__ . "\n"; } + private static function aPrivateStatic($a) { print __METHOD__ . "\n"; } + protected function aProtected($a) { print __METHOD__ . "\n"; } + protected static function aProtectedStatic($a) { print __METHOD__ . "\n"; } +} + +$private = new ReflectionMethod('A', 'aPrivate'); +$privateStatic = new ReflectionMethod('A', 'aPrivateStatic'); +$protected = new ReflectionMethod('A', 'aProtected'); +$protectedStatic = new ReflectionMethod('A', 'aProtectedStatic'); + +try { + $private->invoke(new A, NULL); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $private->invokeArgs(new A, array(NULL)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $privateStatic->invoke(NULL, NULL); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $privateStatic->invokeArgs(NULL, array(NULL)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $protected->invoke(new A, NULL); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $protected->invokeArgs(new A, array(NULL)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $protectedStatic->invoke(NULL, NULL); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + $protectedStatic->invokeArgs(NULL, array(NULL)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +$private->setAccessible(TRUE); +$privateStatic->setAccessible(TRUE); +$protected->setAccessible(TRUE); +$protectedStatic->setAccessible(TRUE); + +$private->invoke(new A, NULL); +$private->invokeArgs(new A, array(NULL)); +$privateStatic->invoke(NULL, NULL); +$privateStatic->invokeArgs(NULL, array(NULL)); +$protected->invoke(new A, NULL); +$protected->invokeArgs(new A, array(NULL)); +$protectedStatic->invoke(NULL, NULL); +$protectedStatic->invokeArgs(NULL, array(NULL)); +?> +--EXPECT-- +string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod" +string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod" +string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod" +string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod" +string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod" +string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod" +string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod" +string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod" +A::aPrivate +A::aPrivate +A::aPrivateStatic +A::aPrivateStatic +A::aProtected +A::aProtected +A::aProtectedStatic +A::aProtectedStatic diff --git a/ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt b/ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt new file mode 100644 index 0000000..00214dc --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_FileInfo_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +ReflectionObject::getFileName(), ReflectionObject::getStartLine(), ReflectionObject::getEndLine() - basic function +--FILE-- +<?php +$rc = new ReflectionObject(new C); +var_dump($rc->getFileName()); +var_dump($rc->getStartLine()); +var_dump($rc->getEndLine()); + +$rc = new ReflectionObject(new stdclass); +var_dump($rc->getFileName()); +var_dump($rc->getStartLine()); +var_dump($rc->getEndLine()); + +Class C { + +} +?> +--EXPECTF-- +string(%d) "%sReflectionObject_FileInfo_basic.php" +int(12) +int(14) +bool(false) +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt b/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt new file mode 100644 index 0000000..d30e677 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_FileInfo_error.phpt @@ -0,0 +1,37 @@ +--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___toString_basic1.phpt b/ext/reflection/tests/ReflectionObject___toString_basic1.phpt new file mode 100644 index 0000000..fefa220 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject___toString_basic1.phpt @@ -0,0 +1,36 @@ +--TEST-- +ReflectionObject::__toString() : very basic test with no dynamic properties +--FILE-- +<?php + +class Foo { + public $bar = 1; +} +$f = new foo; + +echo new ReflectionObject($f); + +?> +--EXPECTF-- +Object of class [ <user> class Foo ] { + @@ %s 3-5 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [1] { + Property [ <default> public $bar ] + } + + - Dynamic properties [0] { + } + + - Methods [0] { + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionObject___toString_basic2.phpt b/ext/reflection/tests/ReflectionObject___toString_basic2.phpt new file mode 100644 index 0000000..332386a --- /dev/null +++ b/ext/reflection/tests/ReflectionObject___toString_basic2.phpt @@ -0,0 +1,39 @@ +--TEST-- +ReflectionObject::__toString() : very basic test with dynamic properties +--FILE-- +<?php + +class Foo { + public $bar = 1; +} +$f = new foo; +$f->dynProp = 'hello'; +$f->dynProp2 = 'hello again'; +echo new ReflectionObject($f); + +?> +--EXPECTF-- +Object of class [ <user> class Foo ] { + @@ %s 3-5 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [1] { + Property [ <default> public $bar ] + } + + - Dynamic properties [2] { + Property [ <dynamic> public $dynProp ] + Property [ <dynamic> public $dynProp2 ] + } + + - Methods [0] { + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionObject_constructor_basic.phpt b/ext/reflection/tests/ReflectionObject_constructor_basic.phpt new file mode 100644 index 0000000..8f4a908 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_constructor_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +ReflectionObject::__construct - basic function test +--FILE-- +<?php +$r1 = new ReflectionObject(new stdClass); +var_dump($r1); + +class C { } +$myInstance = new C; +$r2 = new ReflectionObject($myInstance); +var_dump($r2); + +$r3 = new ReflectionObject($r2); +var_dump($r3); +?> +--EXPECTF-- +object(ReflectionObject)#%d (1) { + ["name"]=> + string(8) "stdClass" +} +object(ReflectionObject)#%d (1) { + ["name"]=> + string(1) "C" +} +object(ReflectionObject)#%d (1) { + ["name"]=> + string(16) "ReflectionObject" +} diff --git a/ext/reflection/tests/ReflectionObject_constructor_error.phpt b/ext/reflection/tests/ReflectionObject_constructor_error.phpt new file mode 100644 index 0000000..baa6129 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_constructor_error.phpt @@ -0,0 +1,49 @@ +--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, integer 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 new file mode 100644 index 0000000..f7dfef8 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_export_basic1.phpt @@ -0,0 +1,36 @@ +--TEST-- +ReflectionObject::export() : very basic test with no dynamic properties +--FILE-- +<?php + +class Foo { + public $bar = 1; +} +$f = new foo; + +ReflectionObject::export($f); + +?> +--EXPECTF-- +Object of class [ <user> class Foo ] { + @@ %s 3-5 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [1] { + Property [ <default> public $bar ] + } + + - Dynamic properties [0] { + } + + - Methods [0] { + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionObject_export_basic2.phpt b/ext/reflection/tests/ReflectionObject_export_basic2.phpt new file mode 100644 index 0000000..277f06e --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_export_basic2.phpt @@ -0,0 +1,39 @@ +--TEST-- +ReflectionObject::export() : very basic test with dynamic properties +--FILE-- +<?php + +class Foo { + public $bar = 1; +} +$f = new foo; +$f->dynProp = 'hello'; +$f->dynProp2 = 'hello again'; +ReflectionObject::export($f); + +?> +--EXPECTF-- +Object of class [ <user> class Foo ] { + @@ %s 3-5 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [1] { + Property [ <default> public $bar ] + } + + - Dynamic properties [2] { + Property [ <dynamic> public $dynProp ] + Property [ <dynamic> public $dynProp2 ] + } + + - Methods [0] { + } +}
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionObject_export_basic3.phpt b/ext/reflection/tests/ReflectionObject_export_basic3.phpt new file mode 100644 index 0000000..7c1da34 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_export_basic3.phpt @@ -0,0 +1,38 @@ +--TEST-- +ReflectionObject::export() - ensure dynamic property with same name as inherited private property is shown. +--FILE-- +<?php +class C { + private $p = 1; +} + +class D extends C{ +} + +$Obj = new D; +$Obj->p = 'value'; +ReflectionObject::export($Obj) +?> +--EXPECTF-- +Object of class [ <user> class D extends C ] { + @@ %s 6-7 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Dynamic properties [0] { + } + + - Methods [0] { + } +} + diff --git a/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt new file mode 100644 index 0000000..3d151bc --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt @@ -0,0 +1,41 @@ +--TEST-- +ReflectionObject::getConstant() basic function test +--FILE-- +<?php +class C { + const a = 'hello from C'; +} +class D extends C { +} +class E extends D { +} +class F extends E { + const a = 'hello from F'; +} +class X { +} + +$classes = array("C", "D", "E", "F", "X"); +foreach($classes as $class) { + echo "Reflecting on instance of class $class: \n"; + $rc = new ReflectionObject(new $class); + var_dump($rc->getConstant('a')); + var_dump($rc->getConstant('doesntexist')); +} +?> +--EXPECTF-- +Reflecting on instance of class C: +string(12) "hello from C" +bool(false) +Reflecting on instance of class D: +string(12) "hello from C" +bool(false) +Reflecting on instance of class E: +string(12) "hello from C" +bool(false) +Reflecting on instance of class F: +string(12) "hello from F" +bool(false) +Reflecting on instance of class X: +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionObject_getConstant_error.phpt b/ext/reflection/tests/ReflectionObject_getConstant_error.phpt new file mode 100644 index 0000000..3f12f3a --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getConstant_error.phpt @@ -0,0 +1,34 @@ +--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_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstants_basic.phpt new file mode 100644 index 0000000..6479ec9 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getConstants_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +ReflectionObject::getConstants() - basic function test +--FILE-- +<?php +class C { + const a = 'hello from C'; +} +class D extends C { +} +class E extends D { +} +class F extends E { + const a = 'hello from F'; +} +class X { +} + +$classes = array("C", "D", "E", "F", "X"); +foreach($classes as $class) { + echo "Reflecting on instance of class $class: \n"; + $rc = new ReflectionObject(new $class); + var_dump($rc->getConstants()); +} + +?> +--EXPECTF-- +Reflecting on instance of class C: +array(1) { + ["a"]=> + string(12) "hello from C" +} +Reflecting on instance of class D: +array(1) { + ["a"]=> + string(12) "hello from C" +} +Reflecting on instance of class E: +array(1) { + ["a"]=> + string(12) "hello from C" +} +Reflecting on instance of class F: +array(1) { + ["a"]=> + string(12) "hello from F" +} +Reflecting on instance of class X: +array(0) { +} diff --git a/ext/reflection/tests/ReflectionObject_getConstants_error.phpt b/ext/reflection/tests/ReflectionObject_getConstants_error.phpt new file mode 100644 index 0000000..d3b9080 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getConstants_error.phpt @@ -0,0 +1,17 @@ +--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_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstructor_basic.phpt new file mode 100644 index 0000000..5a0c36f --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getConstructor_basic.phpt @@ -0,0 +1,79 @@ +--TEST-- +ReflectionObject::getConstructor() - basic function test +--FILE-- +<?php +class NewCtor { + function __construct() {} +} + +class ExtendsNewCtor extends NewCtor { +} + +class OldCtor { + function OldCtor() {} +} + +class ExtendsOldCtor extends OldCtor { +} + + +class X { + function Y() {} +} + +class Y extends X { +} + +class OldAndNewCtor { + function OldAndNewCtor() {} + function __construct() {} +} + +class NewAndOldCtor { + function __construct() {} + function NewAndOldCtor() {} +} +class B { + function B() {} +} + +class C extends B { + function C() {} +} + +class D1 extends C { + function __construct() {} +} + +class D2 extends C { +} + +$classes = array('NewCtor', 'ExtendsNewCtor', 'OldCtor', 'ExtendsOldCtor', + 'OldAndNewCtor', 'NewAndOldCtor', 'B', 'C', 'D1', 'D2', 'X', 'Y'); + +foreach ($classes as $class) { + $rc = new ReflectionObject(new $class); + $rm = $rc->getConstructor(); + if ($rm != null) { + echo "Constructor of $class: " . $rm->getName() . "\n"; + } else { + echo "No constructor for $class\n"; + } + +} + +?> +--EXPECTF-- +Strict Standards: Redefining already defined constructor for class OldAndNewCtor in %s on line %d +Constructor of NewCtor: __construct +Constructor of ExtendsNewCtor: __construct +Constructor of OldCtor: OldCtor +Constructor of ExtendsOldCtor: OldCtor +Constructor of OldAndNewCtor: __construct +Constructor of NewAndOldCtor: __construct +Constructor of B: B +Constructor of C: C +Constructor of D1: __construct +Constructor of D2: C +No constructor for X +No constructor for Y diff --git a/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt b/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt new file mode 100644 index 0000000..2f52de2 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getConstructor_error.phpt @@ -0,0 +1,23 @@ +--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_basic.phpt b/ext/reflection/tests/ReflectionObject_getName_basic.phpt new file mode 100644 index 0000000..db0cbfb --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getName_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +ReflectionObject::getName() - basic function test +--FILE-- +<?php +$r0 = new ReflectionObject(); +var_dump($r0->getName()); + +$r1 = new ReflectionObject(new stdClass); +var_dump($r1->getName()); + +class C { } +$myInstance = new C; +$r2 = new ReflectionObject($myInstance); +var_dump($r2->getName()); + +$r3 = new ReflectionObject($r2); +var_dump($r3->getName()); + +?> +--EXPECTF-- + +Warning: ReflectionObject::__construct() expects exactly 1 parameter, 0 given in %s on line 2 +string(0) "" +string(8) "stdClass" +string(1) "C" +string(16) "ReflectionObject" + diff --git a/ext/reflection/tests/ReflectionObject_getName_error.phpt b/ext/reflection/tests/ReflectionObject_getName_error.phpt new file mode 100644 index 0000000..ff8e279 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getName_error.phpt @@ -0,0 +1,23 @@ +--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_getName_error1.phpt b/ext/reflection/tests/ReflectionObject_getName_error1.phpt new file mode 100644 index 0000000..26c342d --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_getName_error1.phpt @@ -0,0 +1,8 @@ +--TEST-- +ReflectionObject::getName - forbid static invocation +--FILE-- +<?php +ReflectionObject::getName(); +?> +--EXPECTF-- +Fatal error: Non-static method ReflectionClass::getName() cannot be called statically in %s on line 2 diff --git a/ext/reflection/tests/ReflectionObject_isInstance_basic.phpt b/ext/reflection/tests/ReflectionObject_isInstance_basic.phpt new file mode 100644 index 0000000..ef605aa --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInstance_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +ReflectionObject::isInstance() - basic function test +--FILE-- +<?php +class A {} +class B extends A {} +class X {} + +$classes = array("A", "B", "X"); + +$instances = array( "myA" => new A, + "myB" => new B, + "myX" => new X ); + +foreach ($classes as $class) { + $ro = new ReflectionObject(new $class); + foreach ($instances as $name => $instance) { + echo "is $name a $class? "; + var_dump($ro->isInstance($instance)); + } +} + +?> +--EXPECTF-- +is myA a A? bool(true) +is myB a A? bool(true) +is myX a A? bool(false) +is myA a B? bool(false) +is myB a B? bool(true) +is myX a B? bool(false) +is myA a X? bool(false) +is myB a X? bool(false) +is myX a X? bool(true) diff --git a/ext/reflection/tests/ReflectionObject_isInstance_error.phpt b/ext/reflection/tests/ReflectionObject_isInstance_error.phpt new file mode 100644 index 0000000..692c2f8 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInstance_error.phpt @@ -0,0 +1,38 @@ +--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, integer given in %s on line 8 +NULL + +Warning: ReflectionClass::isInstance() expects parameter 1 to be object, double given in %s on line 9 +NULL + +Warning: ReflectionClass::isInstance() expects parameter 1 to be object, boolean 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_basic.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_basic.phpt new file mode 100644 index 0000000..4b8a6ec --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInstantiable_basic.phpt @@ -0,0 +1,36 @@ +--TEST-- +ReflectionObject::IsInstantiable() - basic function test +--FILE-- +<?php +class C { +} + +interface iface { + function f1(); +} + +class ifaceImpl implements iface { + function f1() {} +} + +abstract class abstractClass { + function f1() {} + abstract function f2(); +} + +class D extends abstractClass { + function f2() {} +} + +$classes = array("C", "ifaceImpl", "D"); + +foreach($classes as $class ) { + $ro = new ReflectionObject(new $class); + echo "Is $class instantiable? "; + var_dump($ro->IsInstantiable()); +} +?> +--EXPECTF-- +Is C instantiable? bool(true) +Is ifaceImpl instantiable? bool(true) +Is D instantiable? bool(true) diff --git a/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt new file mode 100644 index 0000000..f993367 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInstantiable_error.phpt @@ -0,0 +1,22 @@ +--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-- +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_isInstantiable_variation.phpt b/ext/reflection/tests/ReflectionObject_isInstantiable_variation.phpt new file mode 100644 index 0000000..ac7199c --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInstantiable_variation.phpt @@ -0,0 +1,78 @@ +--TEST-- +ReflectionObject::IsInstantiable() - variation - constructors +--FILE-- +<?php + +class noCtor { + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + +class publicCtorNew { + public function __construct() {} + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + +class protectedCtorNew { + protected function __construct() {} + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + +class privateCtorNew { + private function __construct() {} + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + +class publicCtorOld { + public function publicCtorOld() {} + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + +class protectedCtorOld { + protected function protectedCtorOld() {} + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + +class privateCtorOld { + private function privateCtorOld() {} + public static function reflectionObjectFactory() { + return new ReflectionObject(new self); + } +} + + +$reflectionObjects = array( + noCtor::reflectionObjectFactory(), + publicCtorNew::reflectionObjectFactory(), + protectedCtorNew::reflectionObjectFactory(), + privateCtorNew::reflectionObjectFactory(), + publicCtorOld::reflectionObjectFactory(), + protectedCtorOld::reflectionObjectFactory(), + privateCtorOld::reflectionObjectFactory() + ); + +foreach($reflectionObjects as $reflectionObject ) { + $name = $reflectionObject->getName(); + echo "Is $name instantiable? "; + var_dump($reflectionObject->IsInstantiable()); +} +?> +--EXPECTF-- +Is noCtor instantiable? bool(true) +Is publicCtorNew instantiable? bool(true) +Is protectedCtorNew instantiable? bool(false) +Is privateCtorNew instantiable? bool(false) +Is publicCtorOld instantiable? bool(true) +Is protectedCtorOld instantiable? bool(false) +Is privateCtorOld instantiable? bool(false) diff --git a/ext/reflection/tests/ReflectionObject_isInternal_basic.phpt b/ext/reflection/tests/ReflectionObject_isInternal_basic.phpt new file mode 100644 index 0000000..066bca7 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInternal_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionObject::isInternal() - basic function test +--FILE-- +<?php +class C { +} + +$r1 = new ReflectionObject(new stdClass); +$r2 = new ReflectionObject(new ReflectionClass('C')); +$r3 = new ReflectionObject(new ReflectionProperty('Exception', 'message')); +$r4 = new ReflectionObject(new Exception); +$r5 = new ReflectionObject(new C); + +var_dump($r1->isInternal(), $r2->isInternal(), $r3->isInternal(), + $r4->isInternal(), $r5->isInternal()); + +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/ext/reflection/tests/ReflectionObject_isInternal_error.phpt b/ext/reflection/tests/ReflectionObject_isInternal_error.phpt new file mode 100644 index 0000000..996add6 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isInternal_error.phpt @@ -0,0 +1,15 @@ +--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_isSubclassOf.002.phpt b/ext/reflection/tests/ReflectionObject_isSubclassOf.002.phpt new file mode 100644 index 0000000..2fb8cb0 --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isSubclassOf.002.phpt @@ -0,0 +1,48 @@ +--TEST-- +ReflectionObject::isSubclassOf() - bad arguments +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class C {} +$ro = new ReflectionObject(new C); + +echo "\n\nTest bad arguments:\n"; +try { + var_dump($ro->isSubclassOf()); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($ro->isSubclassOf('C', 'C')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($ro->isSubclassOf(null)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($ro->isSubclassOf('ThisClassDoesNotExist')); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + var_dump($ro->isSubclassOf(2)); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +Test bad arguments: + +Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 0 given in %s on line 7 +NULL + +Warning: ReflectionClass::isSubclassOf() expects exactly 1 parameter, 2 given in %s on line 12 +NULL +Parameter one must either be a string or a ReflectionClass object +Class ThisClassDoesNotExist does not exist +Parameter one must either be a string or a ReflectionClass object
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt b/ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt new file mode 100644 index 0000000..e89066a --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isSubclassOf_basic.phpt @@ -0,0 +1,116 @@ +--TEST-- +ReflectionObject::isSubclassOf() - basic function test +--FILE-- +<?php +class A {} +class B extends A {} +class C extends B {} + +interface I {} +class X implements I {} + +$classNames = array('A', 'B', 'C', 'I', 'X'); + +//Create ReflectionClasses +foreach ($classNames as $className) { + $rcs[$className] = new ReflectionClass($className); +} + +//Create ReflectionObjects +foreach ($classNames as $className) { + if ($rcs[$className]->isInstantiable()) { + $ros[$className] = new ReflectionObject(new $className); + } +} + +foreach ($ros as $childName => $child) { + foreach ($rcs as $parentName => $parent) { + echo "Is " . $childName . " a subclass of " . $parentName . "? \n"; + echo " - Using ReflectionClass object argument: "; + var_dump($child->isSubclassOf($parent)); + if ($parent->isInstantiable()) { + echo " - Using ReflectionObject object argument: "; + var_dump($child->isSubclassOf($ros[$parentName])); + } + echo " - Using string argument: "; + var_dump($child->isSubclassOf($parentName)); + } +} +?> +--EXPECTF-- +Is A a subclass of A? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of B? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of C? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of I? + - Using ReflectionClass object argument: bool(false) + - Using string argument: bool(false) +Is A a subclass of X? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of A? + - Using ReflectionClass object argument: bool(true) + - Using ReflectionObject object argument: bool(true) + - Using string argument: bool(true) +Is B a subclass of B? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of C? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of I? + - Using ReflectionClass object argument: bool(false) + - Using string argument: bool(false) +Is B a subclass of X? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is C a subclass of A? + - Using ReflectionClass object argument: bool(true) + - Using ReflectionObject object argument: bool(true) + - Using string argument: bool(true) +Is C a subclass of B? + - Using ReflectionClass object argument: bool(true) + - Using ReflectionObject object argument: bool(true) + - Using string argument: bool(true) +Is C a subclass of C? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is C a subclass of I? + - Using ReflectionClass object argument: bool(false) + - Using string argument: bool(false) +Is C a subclass of X? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of A? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of B? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of C? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) +Is X a subclass of I? + - Using ReflectionClass object argument: bool(true) + - Using string argument: bool(true) +Is X a subclass of X? + - Using ReflectionClass object argument: bool(false) + - Using ReflectionObject object argument: bool(false) + - Using string argument: bool(false) diff --git a/ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt b/ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt new file mode 100644 index 0000000..9387b7d --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isSubclassOf_error.phpt @@ -0,0 +1,24 @@ +--TEST-- +ReflectionObject::isSubclassOf() - invalid params +--FILE-- +<?php +class A {} +$ro = new ReflectionObject(new A); + +var_dump($ro->isSubclassOf()); +var_dump($ro->isSubclassOf('A',5)); +var_dump($ro->isSubclassOf('X')); + +?> +--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 + +Fatal error: Uncaught exception 'ReflectionException' with message 'Class X does not exist' in %s:7 +Stack trace: +#0 %s(7): ReflectionClass->isSubclassOf('X') +#1 {main} + thrown in %s on line 7 diff --git a/ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt b/ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt new file mode 100644 index 0000000..4cb08fc --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isUserDefined_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionObject::isUserDefined() - basic function test +--FILE-- +<?php +class C { +} + +$r1 = new ReflectionObject(new stdClass); +$r2 = new ReflectionObject(new ReflectionClass('C')); +$r3 = new ReflectionObject(new ReflectionProperty('Exception', 'message')); +$r4 = new ReflectionObject(new Exception); +$r5 = new ReflectionObject(new C); + +var_dump($r1->isUserDefined(), $r2->isUserDefined(), $r3->isUserDefined(), + $r4->isUserDefined(), $r5->isUserDefined()); + +?> +--EXPECTF-- +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt b/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt new file mode 100644 index 0000000..06be47a --- /dev/null +++ b/ext/reflection/tests/ReflectionObject_isUserDefined_error.phpt @@ -0,0 +1,15 @@ +--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_001.phpt b/ext/reflection/tests/ReflectionParameter_001.phpt new file mode 100644 index 0000000..dae3ac7 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_001.phpt @@ -0,0 +1,80 @@ +--TEST-- +ReflectionParameter class - getNames() method. +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class ReflectTestClass { + public static function twoArgFunction($theIncrement, $anotherParam) { + return ++$theIncrement; + } + + public function oneArgNonStatic($theParam) { + $theParam--; + } + + public function noArgs() { + echo "No arg function\n"; + } +} + +// Create an instance of the Reflection_Method class +$method = new ReflectionMethod('ReflectTestClass', 'twoArgFunction'); +// Get the parameters +$parameters = $method->getParameters(); +echo "Parameters from twoArgMethod:\n\n"; +foreach($parameters as $parameter) { + var_dump($parameter); + $name = $parameter->getName(); + echo "\n"; +} + +$method = new ReflectionMethod('ReflectTestClass', 'oneArgNonStatic'); +$parameters = $method->getParameters(); +echo "Parameters from oneArgNonStatic:\n\n"; +foreach($parameters as $parameter) { + var_dump($parameter); + $name = $parameter->getName(); + echo "\n"; +} + + +$method = new ReflectionMethod('ReflectTestClass', 'noArgs'); +$parameters = $method->getParameters(); +echo "Parameters from noArgs:\n\n"; +var_dump($parameters); +foreach($parameters as $parameter) { + var_dump($parameter); + $name = $parameter->getName(); + echo "\n"; +} + +echo "done\n"; + +?> +--EXPECTF-- +Parameters from twoArgMethod: + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(12) "theIncrement" +} + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(12) "anotherParam" +} + +Parameters from oneArgNonStatic: + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(8) "theParam" +} + +Parameters from noArgs: + +array(0) { +} +done
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionParameter_002.phpt b/ext/reflection/tests/ReflectionParameter_002.phpt new file mode 100644 index 0000000..3b7df6f --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_002.phpt @@ -0,0 +1,80 @@ +--TEST-- +ReflectionParameter class - isPassedByReferenceMethod() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php +class ReflectTestClass { + public static function staticMethod(&$paramOne, $anotherParam) { + return ++$theIncrement; + } + + public function instanceMethod($firstParam, &$secondParam) { + $firstParam = "Hello\n"; + } +} + +// Create an instance of the Reflection_Method class +$method = new ReflectionMethod('ReflectTestClass', 'staticMethod'); +// Get the parameters +$parameters = $method->getParameters(); +echo "Parameters from staticMethod:\n\n"; +foreach($parameters as $parameter) { + var_dump($parameter); + if($parameter->isPassedByReference()) { + echo "This param is passed by reference\n"; + } else { + echo "This param is not passed by reference\n"; + } + echo "\n"; +} + +// Create an instance of the Reflection_Method class +$method = new ReflectionMethod('ReflectTestClass', 'instanceMethod'); +// Get the parameters +$parameters = $method->getParameters(); +echo "Parameters from instanceMethod:\n\n"; +foreach($parameters as $parameter) { + var_dump($parameter); + if($parameter->isPassedByReference()) { + echo "This param is passed by reference\n"; + } else { + echo "This param is not passed by reference\n"; + } + echo "\n"; +} + +echo "done\n"; + +?> +--EXPECTF-- +Parameters from staticMethod: + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(8) "paramOne" +} +This param is passed by reference + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(12) "anotherParam" +} +This param is not passed by reference + +Parameters from instanceMethod: + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(10) "firstParam" +} +This param is not passed by reference + +object(ReflectionParameter)#%i (1) { + ["name"]=> + string(11) "secondParam" +} +This param is passed by reference + +done
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionParameter_003.phpt b/ext/reflection/tests/ReflectionParameter_003.phpt new file mode 100644 index 0000000..f7ced9a --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_003.phpt @@ -0,0 +1,88 @@ +--TEST-- +ReflectionParameter class - isOptional, isDefaultValueAvailable and getDefaultValue methods. +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +class ReflectTestClass { + public static function staticMethod($paramOne, $anotherParam = "bob", + &$thirdParam = "jack", $arrayParam = array('one')) { + echo "hello from test\n"; + echo "third is $thirdParam\n"; + return ++$theIncrement; + } + +} + +$jane = "jane"; +ReflectTestClass::staticMethod("bob", "jack"); + +$refMethod = new ReflectionMethod('ReflectTestClass', 'staticMethod'); +$refParameters = $refMethod->getParameters(); + +echo "parameter names from staticMethod method:\n\n"; +foreach($refParameters as $parameter) { + var_dump($parameter); + if($parameter->isOptional()) { + echo "this parameter is optional\n"; + } else { + echo "this parameter is not optional\n"; + } + + if($parameter->isDefaultValueAvailable()) { + echo "this parameter has a default value\n"; + } else { + echo "this parameter has no default value\n"; + } + + /* + $val = 0; + try { + $val = $parameter->getDefaultValue(); + var_dump($val); + } catch (ReflectionException $e) { + print $e->getMessage(); + echo "\n"; + } + */ + + echo "\n"; +} + +?> +--EXPECTF-- +hello from test +third is jack + +Notice: Undefined variable: theIncrement in %s on line 8 +parameter names from staticMethod method: + +object(ReflectionParameter)#%d (1) { + ["name"]=> + string(8) "paramOne" +} +this parameter is not optional +this parameter has no default value + +object(ReflectionParameter)#%d (1) { + ["name"]=> + string(12) "anotherParam" +} +this parameter is optional +this parameter has a default value + +object(ReflectionParameter)#%d (1) { + ["name"]=> + string(10) "thirdParam" +} +this parameter is optional +this parameter has a default value + +object(ReflectionParameter)#%d (1) { + ["name"]=> + string(10) "arrayParam" +} +this parameter is optional +this parameter has a default value diff --git a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt new file mode 100644 index 0000000..cdd00d2 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic1.phpt @@ -0,0 +1,52 @@ +--TEST-- +ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName() +--FILE-- +<?php + +define("CONST_TEST_1", "const1"); + +function ReflectionParameterTest($test1=array(), $test2 = CONST_TEST_1) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +foreach($reflect->getParameters() as $param) { + if($param->getName() == 'test1') { + var_dump($param->isDefaultValueConstant()); + } + if($param->getName() == 'test2') { + var_dump($param->isDefaultValueConstant()); + } + if($param->isDefaultValueAvailable() && $param->isDefaultValueConstant()) { + var_dump($param->getDefaultValueConstantName()); + } +} + +class Foo2 { + const bar = 'Foo2::bar'; +} + +class Foo { + const bar = 'Foo::bar'; + + public function baz($param1 = self::bar, $param2=Foo2::bar, $param3=CONST_TEST_1) { + } +} + +$method = new ReflectionMethod('Foo', 'baz'); +$params = $method->getParameters(); + +foreach ($params as $param) { + if ($param->isDefaultValueConstant()) { + var_dump($param->getDefaultValueConstantName()); + } +} +?> +==DONE== +--EXPECT-- +bool(false) +bool(true) +string(12) "CONST_TEST_1" +string(9) "self::bar" +string(9) "Foo2::bar" +string(12) "CONST_TEST_1" +==DONE== diff --git a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt new file mode 100644 index 0000000..1ee9e93 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_basic2.phpt @@ -0,0 +1,30 @@ +--TEST-- +ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName() for namespace +--FILE-- +<?php + +namespace ReflectionTestNamespace { + CONST TEST_CONST_1 = "Test Const 1"; + + class TestClass { + const TEST_CONST_2 = "Test Const 2 in class"; + } +} + +namespace { + function ReflectionParameterTest($test=ReflectionTestNamespace\TestClass::TEST_CONST_2, $test2 = ReflectionTestNamespace\CONST_TEST_1) { + echo $test; + } + $reflect = new ReflectionFunction('ReflectionParameterTest'); + foreach($reflect->getParameters() as $param) { + if($param->isDefaultValueAvailable() && $param->isDefaultValueConstant()) { + echo $param->getDefaultValueConstantName() . "\n"; + } + } + echo "==DONE=="; +} +?> +--EXPECT-- +ReflectionTestNamespace\TestClass::TEST_CONST_2 +ReflectionTestNamespace\CONST_TEST_1 +==DONE== diff --git a/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt new file mode 100644 index 0000000..a2c2d24 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_DefaultValueConstant_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionParameter::getDefaultValueConstant() should raise exception on non optional parameter +--FILE-- +<?php + +define("CONST_TEST_1", "const1"); + +function ReflectionParameterTest($test, $test2 = CONST_TEST_1) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +foreach($reflect->getParameters() as $param) { + try { + echo $param->getDefaultValueConstantName() . "\n"; + } + catch(ReflectionException $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +Internal error: Failed to retrieve the default value +CONST_TEST_1 diff --git a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt new file mode 100644 index 0000000..82c6200 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt @@ -0,0 +1,84 @@ +--TEST--
+ReflectionParameter class - canBePassedByValue() method.
+--FILE--
+<?php
+
+function aux($fun) {
+
+ $func = new ReflectionFunction($fun);
+ $parameters = $func->getParameters();
+ foreach($parameters as $parameter) {
+ echo "Name: ", $parameter->getName(), "\n";
+ echo "Is passed by reference: ", $parameter->isPassedByReference()?"yes":"no", "\n";
+ echo "Can be passed by value: ", $parameter->canBePassedByValue()?"yes":"no", "\n";
+ echo "\n";
+ }
+
+}
+
+echo "=> array_multisort:\n\n";
+
+aux('array_multisort');
+
+
+echo "=> sort:\n\n";
+
+aux('sort');
+
+echo "=> user function:\n\n";
+
+function ufunc(&$arg1, $arg2) {}
+
+aux('ufunc');
+
+echo "Done.\n";
+
+?>
+--EXPECTF--
+=> array_multisort:
+
+Name: arr1
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_ASC_or_SORT_DESC
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: arr2
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_ASC_or_SORT_DESC
+Is passed by reference: yes
+Can be passed by value: yes
+
+Name: SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING
+Is passed by reference: yes
+Can be passed by value: yes
+
+=> sort:
+
+Name: arg
+Is passed by reference: yes
+Can be passed by value: no
+
+Name: sort_flags
+Is passed by reference: no
+Can be passed by value: yes
+
+=> user function:
+
+Name: arg1
+Is passed by reference: yes
+Can be passed by value: no
+
+Name: arg2
+Is passed by reference: no
+Can be passed by value: yes
+
+Done.
diff --git a/ext/reflection/tests/ReflectionParameter_export_basic.phpt b/ext/reflection/tests/ReflectionParameter_export_basic.phpt new file mode 100644 index 0000000..74428cc --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_export_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +ReflectionParameter::export() +--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) { + echo ReflectionParameter::export('ReflectionParameterTest', $key); +} +?> +==DONE== +--EXPECT-- +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 new file mode 100644 index 0000000..31acfe1 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_export_error.phpt @@ -0,0 +1,21 @@ +--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 new file mode 100644 index 0000000..8bdbc6a --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_export_error2.phpt @@ -0,0 +1,31 @@ +--TEST-- +ReflectionParameter::export() with incorrect first parameter +--CREDITS-- +Stefan Koopmanschap <stefan@stefankoopmanschap.nl> +--FILE-- +<?php +function ReflectionParameterTest($test, $test2 = null) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +$params = $reflect->getParameters(); +try { + foreach($params as $key => $value) { + ReflectionParameter::export($reflect, $key); + } +} +catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} +try { + foreach($params as $key => $value) { + ReflectionParameter::export(42, $key); + } +} +catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +Method ReflectionFunction::__invoke() does not exist +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 new file mode 100644 index 0000000..2937853 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_export_error3.phpt @@ -0,0 +1,22 @@ +--TEST-- +ReflectionParameter::export() with incorrect second parameter +--CREDITS-- +Stefan Koopmanschap <stefan@stefankoopmanschap.nl> +--FILE-- +<?php +function ReflectionParameterTest($test, $test2 = null) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +$params = $reflect->getParameters(); +foreach($params as $key => $value) { + ReflectionParameter::export('ReflectionParameterTest', 'incorrect_parameter'); +} +--EXPECTF-- + +Fatal error: Uncaught exception 'ReflectionException' with message 'The parameter specified by its name could not be found' in %s.php:%d +Stack trace: +#0 [internal function]: ReflectionParameter->__construct('ReflectionParam...', 'incorrect_param...') +#1 %s.php(%d): ReflectionParameter::export('ReflectionParam...', 'incorrect_param...') +#2 {main} + thrown in %s.php on line %d diff --git a/ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt b/ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt new file mode 100644 index 0000000..59e15a7 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getDeclaringFunction_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +ReflectionParameter::getDeclaringFunction() +--CREDITS-- +Stefan Koopmanschap <stefan@stefankoopmanschap.nl> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php +function ReflectionParameterTest($test, $test2 = null) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +$params = $reflect->getParameters(); +foreach($params as $key => $value) { + echo $value->getDeclaringFunction() . "\n"; +} +?> +==DONE== +--EXPECTF-- +Function [ <user> function ReflectionParameterTest ] { + @@ %s.php %d - %d + + - Parameters [2] { + Parameter #0 [ <required> $test ] + Parameter #1 [ <optional> $test2 = NULL ] + } +} + +Function [ <user> function ReflectionParameterTest ] { + @@ %s.php %d - %d + + - Parameters [2] { + Parameter #0 [ <required> $test ] + Parameter #1 [ <optional> $test2 = NULL ] + } +} + +==DONE== diff --git a/ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt b/ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt new file mode 100644 index 0000000..2807bdf --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getPosition_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionParameter::getPosition() +--CREDITS-- +Stefan Koopmanschap <stefan@stefankoopmanschap.nl> +#testfest roosendaal on 2008-05-10 +--FILE-- +<?php +function ReflectionParameterTest($test, $test2 = null) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +$params = $reflect->getParameters(); +foreach($params as $key => $value) { + var_dump($value->getPosition()); +} +?> +==DONE== +--EXPECT-- +int(0) +int(1) +==DONE== diff --git a/ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt b/ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt new file mode 100644 index 0000000..3118c17 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_invalidMethodInConstructor.phpt @@ -0,0 +1,31 @@ +--TEST-- +ReflectionParameter::__construct(): Invalid method as constructor +--FILE-- +<?php + +// Invalid class name +try { + new ReflectionParameter (array ('A', 'b'), 0); +} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; } + +// Invalid class method +try { + new ReflectionParameter (array ('C', 'b'), 0); +} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; } + +// Invalid object method +try { + new ReflectionParameter (array (new C, 'b'), 0); +} catch (ReflectionException $e) { echo $e->getMessage ()."\n"; } + +echo "Done.\n"; + +class C { +} + +?> +--EXPECTF-- +Class A does not exist +Method C::b() does not exist +Method C::b() does not exist +Done. diff --git a/ext/reflection/tests/ReflectionParameter_isDefault.phpt b/ext/reflection/tests/ReflectionParameter_isDefault.phpt new file mode 100644 index 0000000..6570770 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_isDefault.phpt @@ -0,0 +1,34 @@ +--TEST--
+ReflectionParameter::isDefault()
+--FILE--
+<?php
+class A {
+public $defprop;
+}
+$a = new A;
+$a->myprop = null;
+
+$ro = new ReflectionObject($a);
+$props = $ro->getProperties();
+$prop1 = $props[0];
+var_dump($prop1->isDefault());
+$prop2 = $props[1];
+var_dump($prop2->isDefault());
+
+var_dump($ro->getProperty('defprop')->isDefault());
+var_dump($ro->getProperty('myprop')->isDefault());
+
+$prop1 = new ReflectionProperty($a, 'defprop');
+$prop2 = new ReflectionProperty($a, 'myprop');
+var_dump($prop1->isDefault());
+var_dump($prop2->isDefault());
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+==DONE==
diff --git a/ext/reflection/tests/ReflectionParameter_toString_basic.phpt b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt new file mode 100644 index 0000000..268ced1 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +ReflectionParameter::__toString() +--CREDITS-- +Stefan Koopmanschap <stefan@stefankoopmanschap.nl> +--FILE-- +<?php +function ReflectionParameterTest($test, $test2 = null) { + echo $test; +} +$reflect = new ReflectionFunction('ReflectionParameterTest'); +$params = $reflect->getParameters(); +foreach($params as $key => $value) { + echo $value->__toString() . "\n"; +} +?> +==DONE== +--EXPECT-- +Parameter #0 [ <required> $test ] +Parameter #1 [ <optional> $test2 = NULL ] +==DONE== diff --git a/ext/reflection/tests/ReflectionProperty_basic1.phpt b/ext/reflection/tests/ReflectionProperty_basic1.phpt new file mode 100644 index 0000000..63f9542 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_basic1.phpt @@ -0,0 +1,160 @@ +--TEST-- +Test usage of ReflectionProperty methods __toString(), export(), getName(), isPublic(), isPrivate(), isProtected(), isStatic(), getValue() and setValue(). +--FILE-- +<?php + +function reflectProperty($class, $property) { + $propInfo = new ReflectionProperty($class, $property); + echo "**********************************\n"; + echo "Reflecting on property $class::$property\n\n"; + echo "__toString():\n"; + var_dump($propInfo->__toString()); + echo "export():\n"; + var_dump(ReflectionProperty::export($class, $property, true)); + echo "export():\n"; + var_dump(ReflectionProperty::export($class, $property, false)); + echo "getName():\n"; + var_dump($propInfo->getName()); + echo "isPublic():\n"; + var_dump($propInfo->isPublic()); + echo "isPrivate():\n"; + var_dump($propInfo->isPrivate()); + echo "isProtected():\n"; + var_dump($propInfo->isProtected()); + echo "isStatic():\n"; + var_dump($propInfo->isStatic()); + $instance = new $class(); + if ($propInfo->isPublic()) { + echo "getValue():\n"; + var_dump($propInfo->getValue($instance)); + $propInfo->setValue($instance, "NewValue"); + echo "getValue() after a setValue():\n"; + var_dump($propInfo->getValue($instance)); + } + echo "\n**********************************\n"; +} + +class TestClass { + public $pub; + static public $stat = "static property"; + protected $prot = 4; + private $priv = "keepOut"; +} + +reflectProperty("TestClass", "pub"); +reflectProperty("TestClass", "stat"); +reflectProperty("TestClass", "prot"); +reflectProperty("TestClass", "priv"); + +?> +--EXPECT-- +********************************** +Reflecting on property TestClass::pub + +__toString(): +string(35) "Property [ <default> public $pub ] +" +export(): +string(35) "Property [ <default> public $pub ] +" +export(): +Property [ <default> public $pub ] + +NULL +getName(): +string(3) "pub" +isPublic(): +bool(true) +isPrivate(): +bool(false) +isProtected(): +bool(false) +isStatic(): +bool(false) +getValue(): +NULL +getValue() after a setValue(): +string(8) "NewValue" + +********************************** +********************************** +Reflecting on property TestClass::stat + +__toString(): +string(33) "Property [ public static $stat ] +" +export(): +string(33) "Property [ public static $stat ] +" +export(): +Property [ public static $stat ] + +NULL +getName(): +string(4) "stat" +isPublic(): +bool(true) +isPrivate(): +bool(false) +isProtected(): +bool(false) +isStatic(): +bool(true) +getValue(): +string(15) "static property" +getValue() after a setValue(): +string(8) "NewValue" + +********************************** +********************************** +Reflecting on property TestClass::prot + +__toString(): +string(39) "Property [ <default> protected $prot ] +" +export(): +string(39) "Property [ <default> protected $prot ] +" +export(): +Property [ <default> protected $prot ] + +NULL +getName(): +string(4) "prot" +isPublic(): +bool(false) +isPrivate(): +bool(false) +isProtected(): +bool(true) +isStatic(): +bool(false) + +********************************** +********************************** +Reflecting on property TestClass::priv + +__toString(): +string(37) "Property [ <default> private $priv ] +" +export(): +string(37) "Property [ <default> private $priv ] +" +export(): +Property [ <default> private $priv ] + +NULL +getName(): +string(4) "priv" +isPublic(): +bool(false) +isPrivate(): +bool(true) +isProtected(): +bool(false) +isStatic(): +bool(false) + +********************************** + + diff --git a/ext/reflection/tests/ReflectionProperty_basic2.phpt b/ext/reflection/tests/ReflectionProperty_basic2.phpt new file mode 100644 index 0000000..b7b2133 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_basic2.phpt @@ -0,0 +1,103 @@ +--TEST-- +Test usage of ReflectionProperty methods isDefault(), getModifiers(), getDeclaringClass() and getDocComment(). +--FILE-- +<?php + +function reflectProperty($class, $property) { + $propInfo = new ReflectionProperty($class, $property); + echo "**********************************\n"; + echo "Reflecting on property $class::$property\n\n"; + echo "isDefault():\n"; + var_dump($propInfo->isDefault()); + echo "getModifiers():\n"; + var_dump($propInfo->getModifiers()); + echo "getDeclaringClass():\n"; + var_dump($propInfo->getDeclaringClass()); + echo "getDocComment():\n"; + var_dump($propInfo->getDocComment()); + echo "\n**********************************\n"; +} + +class TestClass { + public $pub; + static public $stat = "static property"; + /** + * This property has a comment. + */ + protected $prot = 4; + private $priv = "keepOut"; +} + +reflectProperty("TestClass", "pub"); +reflectProperty("TestClass", "stat"); +reflectProperty("TestClass", "prot"); +reflectProperty("TestClass", "priv"); + +?> +--EXPECTF-- +********************************** +Reflecting on property TestClass::pub + +isDefault(): +bool(true) +getModifiers(): +int(256) +getDeclaringClass(): +object(ReflectionClass)#%d (1) { + ["name"]=> + string(9) "TestClass" +} +getDocComment(): +bool(false) + +********************************** +********************************** +Reflecting on property TestClass::stat + +isDefault(): +bool(true) +getModifiers(): +int(257) +getDeclaringClass(): +object(ReflectionClass)#%d (1) { + ["name"]=> + string(9) "TestClass" +} +getDocComment(): +bool(false) + +********************************** +********************************** +Reflecting on property TestClass::prot + +isDefault(): +bool(true) +getModifiers(): +int(512) +getDeclaringClass(): +object(ReflectionClass)#%d (1) { + ["name"]=> + string(9) "TestClass" +} +getDocComment(): +string(%d) "/** + * This property has a comment. + */" + +********************************** +********************************** +Reflecting on property TestClass::priv + +isDefault(): +bool(true) +getModifiers(): +int(1024) +getDeclaringClass(): +object(ReflectionClass)#%d (1) { + ["name"]=> + string(9) "TestClass" +} +getDocComment(): +bool(false) + +********************************** diff --git a/ext/reflection/tests/ReflectionProperty_constructor_error.phpt b/ext/reflection/tests/ReflectionProperty_constructor_error.phpt new file mode 100644 index 0000000..38a3468 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_constructor_error.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test ReflectionProperty class constructor errors. +--FILE-- +<?php + +class TestClass { +} + +$a = 5; + +echo "Non-existent class:\n"; +try { + $propInfo = new ReflectionProperty("NonExistentClass", "prop"); +} +catch(Exception $e) { + echo $e->getMessage(); +} + +echo "\n\nWrong property parameter type:\n"; +try { + $propInfo = new ReflectionProperty($a, 'TestClass'); +} +catch(ReflectionException $e) { + echo $e->getMessage(); +} + +echo "\n\nNon-existent property:\n"; +try { + $propInfo = new ReflectionProperty('TestClass', "nonExistentProperty"); +} +catch(Exception $e) { + echo $e->getMessage(); +} + +?> +--EXPECT-- +Non-existent class: +Class NonExistentClass does not exist + +Wrong property parameter type: +The parameter class is expected to be either a string or an object + +Non-existent property: +Property TestClass::$nonExistentProperty does not exist diff --git a/ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt b/ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt new file mode 100644 index 0000000..d614803 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_constructor_variation1.phpt @@ -0,0 +1,58 @@ +--TEST-- +ReflectionProperty::__construct(): ensure inherited private props can't be accessed through ReflectionProperty. +--FILE-- +<?php + +class C { + private $p = 1; + + static function testFromC() { + try { + $rp = new ReflectionProperty("D", "p"); + var_dump($rp); + } catch (Exception $e) { + echo $e->getMessage(); + } + } +} + +class D extends C{ + static function testFromD() { + try { + $rp = new ReflectionProperty("D", "p"); + var_dump($rp); + } catch (Exception $e) { + echo $e->getMessage(); + } + } +} + +echo "--> Reflect inherited private from global scope:\n"; +try { + $rp = new ReflectionProperty("D", "p"); + var_dump($rp); +} catch (Exception $e) { + echo $e->getMessage(); +} + +echo "\n\n--> Reflect inherited private from declaring scope:\n"; +C::testFromC(); + +echo "\n\n--> Reflect inherited private from declaring scope via subclass:\n"; +D::testFromC(); + +echo "\n\n--> Reflect inherited private from subclass:\n"; +D::testFromD(); +?> +--EXPECTF-- +--> Reflect inherited private from global scope: +Property D::$p does not exist + +--> Reflect inherited private from declaring scope: +Property D::$p does not exist + +--> Reflect inherited private from declaring scope via subclass: +Property D::$p does not exist + +--> Reflect inherited private from subclass: +Property D::$p does not exist
\ No newline at end of file diff --git a/ext/reflection/tests/ReflectionProperty_error.phpt b/ext/reflection/tests/ReflectionProperty_error.phpt new file mode 100644 index 0000000..56de6e1 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_error.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test ReflectionProperty class errors. +--FILE-- +<?php + +class C { + public static $p; +} + +var_dump(new ReflectionProperty()); +var_dump(new ReflectionProperty('C::p')); +var_dump(new ReflectionProperty('C', 'p', 'x')); +$rp = new ReflectionProperty('C', 'p'); +var_dump($rp->getName(1)); +var_dump($rp->isPrivate(1)); +var_dump($rp->isProtected(1)); +var_dump($rp->isPublic(1)); +var_dump($rp->isStatic(1)); +var_dump($rp->getModifiers(1)); +var_dump($rp->isDefault(1)); + +?> +--EXPECTF-- +Warning: ReflectionProperty::__construct() expects exactly 2 parameters, 0 given in %s on line %d +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(0) "" + ["class"]=> + string(0) "" +} + +Warning: ReflectionProperty::__construct() expects exactly 2 parameters, 1 given in %s on line %d +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(0) "" + ["class"]=> + string(0) "" +} + +Warning: ReflectionProperty::__construct() expects exactly 2 parameters, 3 given in %s on line %d +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(0) "" + ["class"]=> + string(0) "" +} + +Warning: ReflectionProperty::getName() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionProperty::isPrivate() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionProperty::isProtected() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionProperty::isPublic() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionProperty::isStatic() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionProperty::getModifiers() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: ReflectionProperty::isDefault() expects exactly 0 parameters, 1 given in %s on line %d +NULL diff --git a/ext/reflection/tests/ReflectionProperty_export_basic.phpt b/ext/reflection/tests/ReflectionProperty_export_basic.phpt new file mode 100644 index 0000000..e77a3b7 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_export_basic.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test ReflectionProperty::export() usage. +--FILE-- +<?php + +class TestClass { + public $proper = 5; +} + +var_dump(ReflectionProperty::export('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 new file mode 100644 index 0000000..ab09ed0 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_export_error.phpt @@ -0,0 +1,54 @@ +--TEST-- +Test ReflectionProperty::export() errors. +--FILE-- +<?php + +class TestClass { +} + +$a = 5; + +echo "Non-existent class:\n"; +try { + ReflectionProperty::export("NonExistentClass", "prop", true); +} +catch(Exception $e) { + echo $e->getMessage(); +} + +echo "\n\nWrong property parameter type:\n"; +try { + ReflectionProperty::export($a, 'TestClass', false); +} +catch(ReflectionException $e) { + echo $e->getMessage(); +} + +echo "\n\nNon-existent property:\n"; +try { + ReflectionProperty::export('TestClass', "nonExistentProperty", true); +} +catch(Exception $e) { + echo $e->getMessage(); +} + +echo "\n\nIncorrect number of args:\n"; +ReflectionProperty::export(); +ReflectionProperty::export('TestClass', "nonExistentProperty", true, false); + +?> +--EXPECTF-- +Non-existent class: +Class NonExistentClass does not exist + +Wrong property parameter type: +The parameter class is expected to be either a string or an object + +Non-existent property: +Property TestClass::$nonExistentProperty does not exist + +Incorrect number of args: + +Warning: ReflectionProperty::export() expects at least 2 parameters, 0 given 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_getDeclaringClass_variation1.phpt b/ext/reflection/tests/ReflectionProperty_getDeclaringClass_variation1.phpt new file mode 100644 index 0000000..bf525e1 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getDeclaringClass_variation1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test ReflectionProperty::getDeclaringClass() with inherited properties. +--FILE-- +<?php + +class A { + public $prop; +} + +class B extends A { +} + +$propInfo = new ReflectionProperty('B', 'prop'); +var_dump($propInfo->getDeclaringClass()); + +echo "Wrong number of params:\n"; +$propInfo->getDeclaringClass(1); + +?> +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "A" +} +Wrong number of params: + +Warning: ReflectionProperty::getDeclaringClass() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt new file mode 100644 index 0000000..2c4815a --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt @@ -0,0 +1,100 @@ +--TEST-- +Test ReflectionProperty::getDocComment() usage. +--FILE-- +<?php + +class A { + /** + * My Doc Comment for $a + * + */ + public $a = 2, $b, $c = 1; + /** + * My Doc Comment for $d + */ + var $d; + /**Not a doc comment */ + private $e; + /** + * Doc comment for $f + */ + static protected $f; +} + +class B extends A { + public $a = 2; + /** A doc comment for $b */ + var $b, $c = 1; + /** A doc comment for $e */ + var $e; +} + +foreach(array('A', 'B') as $class) { + $rc = new ReflectionClass($class); + $rps = $rc->getProperties(); + foreach($rps as $rp) { + echo "\n\n---> Doc comment for $class::$" . $rp->getName() . ":\n"; + var_dump($rp->getDocComment()); + } +} + +?> +--EXPECTF-- + +---> Doc comment for A::$a: +string(%d) "/** + * My Doc Comment for $a + * + */" + + +---> Doc comment for A::$b: +bool(false) + + +---> Doc comment for A::$c: +bool(false) + + +---> Doc comment for A::$d: +string(%d) "/** + * My Doc Comment for $d + */" + + +---> Doc comment for A::$e: +bool(false) + + +---> Doc comment for A::$f: +string(%d) "/** + * Doc comment for $f + */" + + +---> Doc comment for B::$a: +bool(false) + + +---> Doc comment for B::$b: +string(%d) "/** A doc comment for $b */" + + +---> Doc comment for B::$c: +bool(false) + + +---> Doc comment for B::$e: +string(%d) "/** A doc comment for $e */" + + +---> Doc comment for B::$d: +string(%d) "/** + * My Doc Comment for $d + */" + + +---> Doc comment for B::$f: +string(%d) "/** + * Doc comment for $f + */" diff --git a/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt b/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt new file mode 100644 index 0000000..dae7be2 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getDocComment_error.phpt @@ -0,0 +1,28 @@ +--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 new file mode 100644 index 0000000..fe888a8 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getModifiers.001.phpt @@ -0,0 +1,66 @@ +--TEST-- +ReflectionProperty::getModifiers() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--FILE-- +<?php + +function reflectProperty($class, $property) { + $propInfo = new ReflectionProperty($class, $property); + + echo "**********************************\n"; + echo "Reflecting on property $class::$property\n\n"; + + echo "getModifiers():\n"; + var_dump($propInfo->getModifiers()); + + echo "\n**********************************\n"; +} + +class TestClass +{ + public $pub; + static public $stat = "static property"; + /** + * This property has a comment. + */ + protected $prot = 4; + private $priv = "keepOut"; +} + +reflectProperty("TestClass", "pub"); +reflectProperty("TestClass", "stat"); +reflectProperty("TestClass", "prot"); +reflectProperty("TestClass", "priv"); + +?> +--EXPECT-- +********************************** +Reflecting on property TestClass::pub + +getModifiers(): +int(256) + +********************************** +********************************** +Reflecting on property TestClass::stat + +getModifiers(): +int(257) + +********************************** +********************************** +Reflecting on property TestClass::prot + +getModifiers(): +int(512) + +********************************** +********************************** +Reflecting on property TestClass::priv + +getModifiers(): +int(1024) + +********************************** diff --git a/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt new file mode 100644 index 0000000..0d1b6bd --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getModifiers_basic.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test ReflectionProperty::getModifiers() usage. +--FILE-- +<?php + +class C { + public $a1; + protected $a2; + private $a3; + static public $a4; + static protected $a5; + static private $a6; +} + +class D extends C { + public $a1; + protected $a2; + private $a3; + static public $a4; + static protected $a5; + static private $a6; +} + +for ($i = 1;$i <= 6;$i++) { + $rp = new ReflectionProperty("C", "a$i"); + echo "C::a$i: "; + var_dump($rp->getModifiers()); + $rp = new ReflectionProperty("D", "a$i"); + echo "D::a$i: "; + var_dump($rp->getModifiers()); +} + +?> +--EXPECTF-- +C::a1: int(256) +D::a1: int(256) +C::a2: int(512) +D::a2: int(512) +C::a3: int(1024) +D::a3: int(3072) +C::a4: int(257) +D::a4: int(257) +C::a5: int(513) +D::a5: int(513) +C::a6: int(1025) +D::a6: int(3073) diff --git a/ext/reflection/tests/ReflectionProperty_getValue_error.phpt b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt new file mode 100644 index 0000000..c2152e9 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt @@ -0,0 +1,81 @@ +--TEST-- +Test ReflectionProperty::getValue() errors. +--FILE-- +<?php + +class TestClass { + public $pub; + public $pub2 = 5; + static public $stat = "static property"; + protected $prot = 4; + private $priv = "keepOut"; +} + +class AnotherClass { +} + +$instance = new TestClass(); +$instanceWithNoProperties = new AnotherClass(); +$propInfo = new ReflectionProperty('TestClass', 'pub2'); + +echo "Too few args:\n"; +var_dump($propInfo->getValue()); + +echo "\nToo many args:\n"; +var_dump($propInfo->getValue($instance, true)); + +echo "\nWrong type of arg:\n"; +var_dump($propInfo->getValue(true)); + +echo "\nInstance without property:\n"; +$propInfo = new ReflectionProperty('TestClass', 'stat'); + +echo "\nStatic property / too many args:\n"; +var_dump($propInfo->getValue($instance, true)); + +echo "\nStatic property / wrong type of arg:\n"; +var_dump($propInfo->getValue(true)); + +echo "\nProtected property:\n"; +try { + $propInfo = new ReflectionProperty('TestClass', 'prot'); + var_dump($propInfo->getValue($instance)); +} +catch(Exception $exc) { + echo $exc->getMessage(); +} + +echo "\n\nInstance without property:\n"; +$propInfo = new ReflectionProperty('TestClass', 'pub2'); +var_dump($propInfo->getValue($instanceWithNoProperties)); + +?> +--EXPECTF-- +Too few args: + +Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +Too many args: + +Warning: ReflectionProperty::getValue() expects exactly 1 parameter, 2 given in %s on line %d +NULL + +Wrong type of arg: + +Warning: ReflectionProperty::getValue() expects parameter 1 to be object, boolean given in %s on line %d +NULL + +Instance without property: + +Static property / too many args: +string(15) "static property" + +Static property / wrong type of arg: +string(15) "static property" + +Protected property: +Cannot access non-public member TestClass::prot + +Instance without property: +NULL diff --git a/ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt b/ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt new file mode 100644 index 0000000..22ee117 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isDefault_basic.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test ReflectionProperty::isDefault() usage. +--FILE-- +<?php + +function reflectProperty($class, $property) { + $propInfo = new ReflectionProperty($class, $property); + echo "**********************************\n"; + echo "Reflecting on property $class::$property\n\n"; + echo "isDefault():\n"; + var_dump($propInfo->isDefault()); + echo "\n**********************************\n"; +} + +class TestClass { + public $pub; + static public $stat = "static property"; + protected $prot = 4; + private $priv = "keepOut"; +} + +reflectProperty("TestClass", "pub"); +reflectProperty("TestClass", "stat"); +reflectProperty("TestClass", "prot"); +reflectProperty("TestClass", "priv"); + +echo "Wrong number of params:\n"; +$propInfo = new ReflectionProperty('TestClass', 'pub'); +$propInfo->isDefault(1); + +?> +--EXPECTF-- +********************************** +Reflecting on property TestClass::pub + +isDefault(): +bool(true) + +********************************** +********************************** +Reflecting on property TestClass::stat + +isDefault(): +bool(true) + +********************************** +********************************** +Reflecting on property TestClass::prot + +isDefault(): +bool(true) + +********************************** +********************************** +Reflecting on property TestClass::priv + +isDefault(): +bool(true) + +********************************** +Wrong number of params: + +Warning: ReflectionProperty::isDefault() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt new file mode 100644 index 0000000..cc184c1 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt @@ -0,0 +1,139 @@ +--TEST-- +Test ReflectionProperty::setAccessible(). +--FILE-- +<?php +class A { + protected $protected = 'a'; + protected static $protectedStatic = 'b'; + private $private = 'c'; + private static $privateStatic = 'd'; +} + +class B extends A {} + +$a = new A; +$protected = new ReflectionProperty($a, 'protected'); +$protectedStatic = new ReflectionProperty('A', 'protectedStatic'); +$private = new ReflectionProperty($a, 'private'); +$privateStatic = new ReflectionProperty('A', 'privateStatic'); + +try { + var_dump($protected->getValue($a)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + var_dump($protectedStatic->getValue()); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + var_dump($private->getValue($a)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + var_dump($privateStatic->getValue()); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +$protected->setAccessible(TRUE); +$protectedStatic->setAccessible(TRUE); +$private->setAccessible(TRUE); +$privateStatic->setAccessible(TRUE); + +var_dump($protected->getValue($a)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($a)); +var_dump($privateStatic->getValue()); + +$protected->setValue($a, 'e'); +$protectedStatic->setValue('f'); +$private->setValue($a, 'g'); +$privateStatic->setValue('h'); + +var_dump($protected->getValue($a)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($a)); +var_dump($privateStatic->getValue()); + +$a = new A; +$b = new B; +$protected = new ReflectionProperty($b, 'protected'); +$protectedStatic = new ReflectionProperty('B', 'protectedStatic'); +$private = new ReflectionProperty($a, 'private'); + +try { + var_dump($protected->getValue($b)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + var_dump($protectedStatic->getValue()); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + var_dump($private->getValue($b)); +} + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +$protected->setAccessible(TRUE); +$protectedStatic->setAccessible(TRUE); +$private->setAccessible(TRUE); + +var_dump($protected->getValue($b)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($b)); + +$protected->setValue($b, 'e'); +$protectedStatic->setValue('f'); +$private->setValue($b, 'g'); + +var_dump($protected->getValue($b)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($b)); +?> +--EXPECT-- +string(44) "Cannot access non-public member A::protected" +string(50) "Cannot access non-public member A::protectedStatic" +string(42) "Cannot access non-public member A::private" +string(48) "Cannot access non-public member A::privateStatic" +string(1) "a" +string(1) "b" +string(1) "c" +string(1) "d" +string(1) "e" +string(1) "f" +string(1) "g" +string(1) "h" +string(44) "Cannot access non-public member B::protected" +string(50) "Cannot access non-public member B::protectedStatic" +string(42) "Cannot access non-public member A::private" +string(1) "a" +string(1) "f" +string(1) "c" +string(1) "e" +string(1) "f" +string(1) "g" diff --git a/ext/reflection/tests/ReflectionProperty_setValue_error.phpt b/ext/reflection/tests/ReflectionProperty_setValue_error.phpt new file mode 100644 index 0000000..7161c53 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_setValue_error.phpt @@ -0,0 +1,100 @@ +--TEST-- +Test ReflectionProperty::setValue() error cases. +--FILE-- +<?php + +class TestClass { + public $pub; + public $pub2 = 5; + static public $stat = "static property"; + protected $prot = 4; + private $priv = "keepOut"; +} + +class AnotherClass { +} + +$instance = new TestClass(); +$instanceWithNoProperties = new AnotherClass(); +$propInfo = new ReflectionProperty('TestClass', 'pub2'); + +echo "Too few args:\n"; +var_dump($propInfo->setValue()); +var_dump($propInfo->setValue($instance)); + +echo "\nToo many args:\n"; +var_dump($propInfo->setValue($instance, "NewValue", true)); + +echo "\nWrong type of arg:\n"; +var_dump($propInfo->setValue(true, "NewValue")); +$propInfo = new ReflectionProperty('TestClass', 'stat'); + +echo "\nStatic property / too many args:\n"; +var_dump($propInfo->setValue($instance, "NewValue", true)); + +echo "\nStatic property / too few args:\n"; +var_dump($propInfo->setValue("A new value")); +var_dump(TestClass::$stat); +var_dump($propInfo->setValue()); +var_dump(TestClass::$stat); + +echo "\nStatic property / wrong type of arg:\n"; +var_dump($propInfo->setValue(true, "Another new value")); +var_dump(TestClass::$stat); + +echo "\nProtected property:\n"; +try { + $propInfo = new ReflectionProperty('TestClass', 'prot'); + var_dump($propInfo->setValue($instance, "NewValue")); +} +catch(Exception $exc) { + echo $exc->getMessage(); +} + +echo "\n\nInstance without property:\n"; +$propInfo = new ReflectionProperty('TestClass', 'pub2'); +var_dump($propInfo->setValue($instanceWithNoProperties, "NewValue")); +var_dump($instanceWithNoProperties->pub2); +?> +--EXPECTF-- +Too few args: + +Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 0 given in %s on line %d +NULL + +Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Too many args: + +Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Wrong type of arg: + +Warning: ReflectionProperty::setValue() expects parameter 1 to be object, boolean given in %s on line %d +NULL + +Static property / too many args: + +Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Static property / too few args: +NULL +string(11) "A new value" + +Warning: ReflectionProperty::setValue() expects exactly 2 parameters, 0 given in %s on line %d +NULL +string(11) "A new value" + +Static property / wrong type of arg: +NULL +string(17) "Another new value" + +Protected property: +Cannot access non-public member TestClass::prot + +Instance without property: +NULL +string(8) "NewValue" diff --git a/ext/reflection/tests/bug26640.phpt b/ext/reflection/tests/bug26640.phpt new file mode 100644 index 0000000..e375fd4 --- /dev/null +++ b/ext/reflection/tests/bug26640.phpt @@ -0,0 +1,25 @@ +--TEST-- +Reflection Bug #26640 (__autoload() not invoked by Reflection classes) +--FILE-- +<?php + +function __autoload($c) +{ + class autoload_class + { + public function __construct() + { + print "autoload success\n"; + } + } +} + +$a = new ReflectionClass('autoload_class'); + +if (is_object($a)) { + echo "OK\n"; +} + +?> +--EXPECT-- +OK diff --git a/ext/reflection/tests/bug26695.phpt b/ext/reflection/tests/bug26695.phpt new file mode 100644 index 0000000..e429f76 --- /dev/null +++ b/ext/reflection/tests/bug26695.phpt @@ -0,0 +1,25 @@ +--TEST-- +Reflection Bug #26695 (Reflection API does not recognize mixed-case class hints) +--FILE-- +<?php + +class Foo { +} + +class Bar { + function demo(foo $f) { + } +} + +$class = new ReflectionClass('bar'); +$methods = $class->getMethods(); +$params = $methods[0]->getParameters(); + +$class = $params[0]->getClass(); + +var_dump($class->getName()); +?> +===DONE=== +--EXPECT-- +string(3) "Foo" +===DONE=== diff --git a/ext/reflection/tests/bug29268.phpt b/ext/reflection/tests/bug29268.phpt new file mode 100644 index 0000000..d8efc0b --- /dev/null +++ b/ext/reflection/tests/bug29268.phpt @@ -0,0 +1,27 @@ +--TEST-- +Reflection Bug #29268 (__autoload() not called with reflectionProperty->getClass()) +--FILE-- +<?php +function __autoload($classname) { + echo "__autoload($classname)\n"; + eval("class $classname {}"); +} + +class B{ + public function doit(A $a){ + } +} + +$ref = new reflectionMethod('B','doit'); +$parameters = $ref->getParameters(); +foreach($parameters as $parameter) +{ + $class = $parameter->getClass(); + echo $class->name."\n"; +} +echo "ok\n"; +?> +--EXPECT-- +__autoload(A) +A +ok diff --git a/ext/reflection/tests/bug29523.phpt b/ext/reflection/tests/bug29523.phpt new file mode 100644 index 0000000..e74403c --- /dev/null +++ b/ext/reflection/tests/bug29523.phpt @@ -0,0 +1,38 @@ +--TEST-- +Reflection Bug #29523 (ReflectionParameter::isOptional() is incorrect) +--FILE-- +<?php + +class TestClass +{ +} + +function optionalTest(TestClass $a, TestClass $b, $c = 3) +{ +} + +$function = new ReflectionFunction('optionalTest'); +$numberOfNotOptionalParameters = 0; +$numberOfOptionalParameters = 0; +foreach($function->getParameters() as $parameter) +{ + var_dump($parameter->isOptional()); + if ($parameter->isOptional()) + { + ++$numberOfOptionalParameters; + } + else + { + ++$numberOfNotOptionalParameters; + } +} +var_dump($function->getNumberOfRequiredParameters()); +var_dump($numberOfNotOptionalParameters); + +?> +--EXPECT-- +bool(false) +bool(false) +bool(true) +int(2) +int(2) diff --git a/ext/reflection/tests/bug29828.phpt b/ext/reflection/tests/bug29828.phpt new file mode 100644 index 0000000..43e32d2 --- /dev/null +++ b/ext/reflection/tests/bug29828.phpt @@ -0,0 +1,35 @@ +--TEST-- +Reflection Bug #29828 (Interfaces no longer work) +--FILE-- +<?php + +interface Bla +{ + function bla(); +} + +class BlaMore implements Bla +{ + function bla() + { + echo "Hello\n"; + } +} + +$r = new ReflectionClass('BlaMore'); + +var_dump(count($r->getMethods())); +var_dump($r->getMethod('bla')->isConstructor()); +var_dump($r->getMethod('bla')->isAbstract()); + +$o=new BlaMore; +$o->bla(); + +?> +===DONE=== +--EXPECT-- +int(1) +bool(false) +bool(false) +Hello +===DONE=== diff --git a/ext/reflection/tests/bug29986.phpt b/ext/reflection/tests/bug29986.phpt new file mode 100644 index 0000000..d30b3a6 --- /dev/null +++ b/ext/reflection/tests/bug29986.phpt @@ -0,0 +1,41 @@ +--TEST-- +Reflection Bug #29986 (Class constants won't work with predefined constants when using ReflectionClass) +--INI-- +precision=14 +--FILE-- +<?php +class just_constants +{ + const BOOLEAN_CONSTANT = true; + const NULL_CONSTANT = null; + const STRING_CONSTANT = 'This is a string'; + const INTEGER_CONSTANT = 1000; + const FLOAT_CONSTANT = 3.14159265; +} + +Reflection::export(new ReflectionClass('just_constants')); +?> +--EXPECTF-- +Class [ <user> class just_constants ] { + @@ %s %d-%d + + - Constants [5] { + Constant [ boolean BOOLEAN_CONSTANT ] { 1 } + Constant [ null NULL_CONSTANT ] { } + Constant [ string STRING_CONSTANT ] { This is a string } + Constant [ integer INTEGER_CONSTANT ] { 1000 } + Constant [ double FLOAT_CONSTANT ] { 3.14159265 } + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/bug30146.phpt b/ext/reflection/tests/bug30146.phpt new file mode 100644 index 0000000..3f62141 --- /dev/null +++ b/ext/reflection/tests/bug30146.phpt @@ -0,0 +1,23 @@ +--TEST-- +Reflection Bug #30146 (ReflectionProperty->getValue() requires instance for static property) +--FILE-- +<?php +class test { + static public $a = 1; +} + +$r = new ReflectionProperty('test', 'a'); +var_dump($r->getValue(null)); + +$r->setValue(NULL, 2); +var_dump($r->getValue()); + +$r->setValue(3); +var_dump($r->getValue()); +?> +===DONE=== +--EXPECT-- +int(1) +int(2) +int(3) +===DONE=== diff --git a/ext/reflection/tests/bug30148.phpt b/ext/reflection/tests/bug30148.phpt new file mode 100644 index 0000000..aa5841e --- /dev/null +++ b/ext/reflection/tests/bug30148.phpt @@ -0,0 +1,35 @@ +--TEST-- +Reflection Bug #30148 (ReflectionMethod->isConstructor() fails for inherited classes) +--FILE-- +<?php + +class Root +{ + function Root() {} +} +class Base extends Root +{ + function __construct() {} +} +class Derived extends Base +{ +} +$a = new ReflectionMethod('Root','Root'); +$b = new ReflectionMethod('Base','Root'); +$c = new ReflectionMethod('Base','__construct'); +$d = new ReflectionMethod('Derived','Root'); +$e = new ReflectionMethod('Derived','__construct'); +var_dump($a->isConstructor()); +var_dump($b->isConstructor()); +var_dump($c->isConstructor()); +var_dump($d->isConstructor()); +var_dump($e->isConstructor()); +?> +===DONE=== +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +===DONE=== diff --git a/ext/reflection/tests/bug30209.phpt b/ext/reflection/tests/bug30209.phpt new file mode 100644 index 0000000..2735a74 --- /dev/null +++ b/ext/reflection/tests/bug30209.phpt @@ -0,0 +1,31 @@ +--TEST-- +Reflection Bug #30209 (ReflectionClass::getMethod() lowercases attribute) +--FILE-- +<?php + +class Foo +{ + private $name = 'testBAR'; + + public function testBAR() + { + try + { + $class = new ReflectionClass($this); + var_dump($this->name); + $method = $class->getMethod($this->name); + var_dump($this->name); + } + + catch (Exception $e) {} + } +} + +$foo = new Foo; +$foo->testBAR(); +?> +===DONE=== +--EXPECTF-- +string(7) "testBAR" +string(7) "testBAR" +===DONE=== diff --git a/ext/reflection/tests/bug30856.phpt b/ext/reflection/tests/bug30856.phpt new file mode 100644 index 0000000..39fc110 --- /dev/null +++ b/ext/reflection/tests/bug30856.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reflection Bug #30856 (ReflectionClass::getStaticProperties segfaults) +--FILE-- +<?php +class bogus { + const C = 'test'; + static $a = bogus::C; +} + +$class = new ReflectionClass('bogus'); + +var_dump($class->getStaticProperties()); +?> +===DONE=== +--EXPECT-- +array(1) { + ["a"]=> + string(4) "test" +} +===DONE=== diff --git a/ext/reflection/tests/bug30961.phpt b/ext/reflection/tests/bug30961.phpt new file mode 100644 index 0000000..a61c992 --- /dev/null +++ b/ext/reflection/tests/bug30961.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reflection Bug #30961 (Wrong linenumber in ReflectionClass getStartLine()) +--FILE-- +<?php + class a + { + } + + class b extends a + { + } + + $ref1 = new ReflectionClass('a'); + $ref2 = new ReflectionClass('b'); + echo $ref1->getStartLine() . "\n"; + echo $ref2->getStartLine() . "\n"; +?> +--EXPECT-- +2 +6 diff --git a/ext/reflection/tests/bug31651.phpt b/ext/reflection/tests/bug31651.phpt new file mode 100644 index 0000000..59f19ea --- /dev/null +++ b/ext/reflection/tests/bug31651.phpt @@ -0,0 +1,24 @@ +--TEST-- +Reflection Bug #31651 (ReflectionClass::getDefaultProperties segfaults with arrays.) +--FILE-- +<?php + +class Test +{ + public $a = array('a' => 1); +} + +$ref = new ReflectionClass('Test'); + +print_r($ref->getDefaultProperties()); + +?> +--EXPECT-- +Array +( + [a] => Array + ( + [a] => 1 + ) + +) diff --git a/ext/reflection/tests/bug32981.phpt b/ext/reflection/tests/bug32981.phpt new file mode 100644 index 0000000..5735674 --- /dev/null +++ b/ext/reflection/tests/bug32981.phpt @@ -0,0 +1,34 @@ +--TEST-- +Reflection Bug #32981 (ReflectionMethod::getStaticVariables() causes apache2.0.54 seg fault) +--FILE-- +<?php + +class TestClass +{ + static function test() + { + static $enabled = true; + } +} + +$class = new ReflectionClass('TestClass'); +foreach ($class->getMethods() as $method) +{ + var_dump($method->getName()); + $arr_static_vars[] = $method->getStaticVariables(); +} + +var_dump($arr_static_vars); + +?> +===DONE=== +--EXPECT-- +string(4) "test" +array(1) { + [0]=> + array(1) { + ["enabled"]=> + bool(true) + } +} +===DONE=== diff --git a/ext/reflection/tests/bug33312.phpt b/ext/reflection/tests/bug33312.phpt new file mode 100644 index 0000000..ffa9180 --- /dev/null +++ b/ext/reflection/tests/bug33312.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reflection Bug #33312 (ReflectionParameter methods do not work correctly) +--FILE-- +<?php +class Foo { + public function bar(Foo $foo, $bar = 'bar') { + } +} + +$class = new ReflectionClass('Foo'); +$method = $class->getMethod('bar'); + +foreach ($method->getParameters() as $parameter) { + if ($parameter->isDefaultValueAvailable()) { + print $parameter->getDefaultValue()."\n"; + } +} +?> +--EXPECT-- +bar diff --git a/ext/reflection/tests/bug33389.phpt b/ext/reflection/tests/bug33389.phpt new file mode 100644 index 0000000..f1997a3 --- /dev/null +++ b/ext/reflection/tests/bug33389.phpt @@ -0,0 +1,97 @@ +--TEST-- +Reflection Bug #33389 (double free() when exporting a ReflectionClass) +--FILE-- +<?php +define ('foobar', 1); +class Test { + function foo1($arg=foobar) { + } + function foo2($arg=null) { + } + function foo3($arg=false) { + } + function foo4($arg='foo') { + } + function foo5($arg=1) { + } + function bar($arg) { + } + function foo() { + } +} +Reflection::export(new ReflectionClass('Test')); +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +Class [ <user> class Test ] { + @@ %sbug33389.php 3-18 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [7] { + Method [ <user> public method foo1 ] { + @@ %sbug33389.php 4 - 5 + + - Parameters [1] { + Parameter #0 [ <optional> $arg = 1 ] + } + } + + Method [ <user> public method foo2 ] { + @@ %sbug33389.php 6 - 7 + + - Parameters [1] { + Parameter #0 [ <optional> $arg = NULL ] + } + } + + Method [ <user> public method foo3 ] { + @@ %sbug33389.php 8 - 9 + + - Parameters [1] { + Parameter #0 [ <optional> $arg = false ] + } + } + + Method [ <user> public method foo4 ] { + @@ %sbug33389.php 10 - 11 + + - Parameters [1] { + Parameter #0 [ <optional> $arg = 'foo' ] + } + } + + Method [ <user> public method foo5 ] { + @@ %sbug33389.php 12 - 13 + + - Parameters [1] { + Parameter #0 [ <optional> $arg = 1 ] + } + } + + Method [ <user> public method bar ] { + @@ %sbug33389.php 14 - 15 + + - Parameters [1] { + Parameter #0 [ <required> $arg ] + } + } + + Method [ <user> public method foo ] { + @@ %sbug33389.php 16 - 17 + } + } +} + +===DONE=== diff --git a/ext/reflection/tests/bug36308.phpt b/ext/reflection/tests/bug36308.phpt new file mode 100644 index 0000000..79aa5f8 --- /dev/null +++ b/ext/reflection/tests/bug36308.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reflection Bug #36308 (ReflectionProperty::getDocComment() does not reflect extended class commentary) +--FILE-- +<?php +class Base { + /** Base comment block */ + public $foo = 'bar'; +} + +class Extended extends Base { + /** Extended commentary */ + public $foo = 'zim'; +} + +$reflect = new ReflectionClass('Extended'); +$props = $reflect->getProperties(); +echo $props[0]->getDocComment(); +?> +--EXPECT-- +/** Extended commentary */ diff --git a/ext/reflection/tests/bug36337.phpt b/ext/reflection/tests/bug36337.phpt new file mode 100644 index 0000000..369d5be --- /dev/null +++ b/ext/reflection/tests/bug36337.phpt @@ -0,0 +1,28 @@ +--TEST-- +Reflection Bug #36337 (ReflectionProperty fails to return correct visibility) +--FILE-- +<?php + +abstract class enum { + protected $_values; + + public function __construct() { + $property = new ReflectionProperty(get_class($this),'_values'); + var_dump($property->isProtected()); + } + +} + +final class myEnum extends enum { + public $_values = array( + 0 => 'No value', + ); +} + +$x = new myEnum(); + +echo "Done\n"; +?> +--EXPECT-- +bool(false) +Done diff --git a/ext/reflection/tests/bug36434.phpt b/ext/reflection/tests/bug36434.phpt new file mode 100644 index 0000000..218055d --- /dev/null +++ b/ext/reflection/tests/bug36434.phpt @@ -0,0 +1,31 @@ +--TEST-- +Reflection Bug #36434 (Properties from parent class fail to indetify their true origin) +--FILE-- +<?php +class ancester +{ +public $ancester = 0; + function ancester() + { + return $this->ancester; + } +} +class foo extends ancester +{ +public $bar = "1"; + function foo() + { + return $this->bar; + } +} + +$r = new ReflectionClass('foo'); +foreach ($r->GetProperties() as $p) +{ + echo $p->getName(). " ". $p->getDeclaringClass()->getName()."\n"; +} + +?> +--EXPECT-- +bar foo +ancester ancester diff --git a/ext/reflection/tests/bug37816.phpt b/ext/reflection/tests/bug37816.phpt new file mode 100644 index 0000000..18a4904 --- /dev/null +++ b/ext/reflection/tests/bug37816.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #37816 (ReflectionProperty does not throw exception when accessing protected attribute) +--FILE-- +<?php + +class TestClass +{ + protected $p = 2; +} + +$o = new TestClass; + +$r = new ReflectionProperty($o, 'p'); + +try +{ + $x = $r->getValue($o); +} +catch (Exception $e) +{ + echo 'Caught: ' . $e->getMessage() . "\n"; +} + +?> +===DONE=== +--EXPECTF-- +Caught: Cannot access non-public member TestClass::p +===DONE=== diff --git a/ext/reflection/tests/bug37964.phpt b/ext/reflection/tests/bug37964.phpt new file mode 100644 index 0000000..9351193 --- /dev/null +++ b/ext/reflection/tests/bug37964.phpt @@ -0,0 +1,50 @@ +--TEST-- +Reflection Bug #37964 (Reflection shows private methods of parent class) +--FILE-- +<?php + +abstract class foobar { + private function test2() { + } +} +class foo extends foobar { + private $foo = 1; + private function test() { + } + protected function test3() { + } +} +class bar extends foo { + private function foobar() { + } +} + +Reflection::export(new ReflectionClass(new bar)); + +?> +--EXPECTF-- +Class [ <user> class bar extends foo ] { + @@ %s %s + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [2] { + Method [ <user> private method foobar ] { + @@ %s %d - %d + } + + Method [ <user, inherits foo> protected method test3 ] { + @@ %s %d - %d + } + } +} diff --git a/ext/reflection/tests/bug38132.phpt b/ext/reflection/tests/bug38132.phpt new file mode 100644 index 0000000..16e5641 --- /dev/null +++ b/ext/reflection/tests/bug38132.phpt @@ -0,0 +1,32 @@ +--TEST-- +Reflection Bug #38132 (ReflectionClass::getStaticProperties() retains \0 in key names) +--FILE-- +<?php +class foo { + static protected $bar = 'baz'; + static public $a = 'a'; +} + +$class = new ReflectionClass('foo'); +$properties = $class->getStaticProperties(); +var_dump($properties, array_keys($properties)); +var_dump(isset($properties['*bar'])); +var_dump(isset($properties["\0*\0bar"])); +var_dump(isset($properties["bar"])); +?> +--EXPECT-- +array(2) { + ["bar"]=> + string(3) "baz" + ["a"]=> + string(1) "a" +} +array(2) { + [0]=> + string(3) "bar" + [1]=> + string(1) "a" +} +bool(false) +bool(false) +bool(true) diff --git a/ext/reflection/tests/bug38194.phpt b/ext/reflection/tests/bug38194.phpt new file mode 100644 index 0000000..d12f4e4 --- /dev/null +++ b/ext/reflection/tests/bug38194.phpt @@ -0,0 +1,11 @@ +--TEST-- +Reflection Bug #38194 (ReflectionClass::isSubclassOf() returns TRUE for the class itself) +--FILE-- +<?php +class Object { } + +$objectClass= new ReflectionClass('Object'); +var_dump($objectClass->isSubclassOf($objectClass)); +?> +--EXPECT-- +bool(false) diff --git a/ext/reflection/tests/bug38217.phpt b/ext/reflection/tests/bug38217.phpt new file mode 100644 index 0000000..cf007d9 --- /dev/null +++ b/ext/reflection/tests/bug38217.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #38217 (ReflectionClass::newInstanceArgs() tries to allocate too much memory) +--FILE-- +<?php + +class Object { + public function __construct() { + } +} + +$class= new ReflectionClass('Object'); +var_dump($class->newInstanceArgs()); + +class Object1 { + public function __construct($var) { + var_dump($var); + } +} + +$class= new ReflectionClass('Object1'); +var_dump($class->newInstanceArgs()); +var_dump($class->newInstanceArgs(array('test'))); + + +echo "Done\n"; +?> +--EXPECTF-- +object(Object)#%d (0) { +} + +Warning: Missing argument 1 for Object1::__construct() in %s on line %d + +Notice: Undefined variable: var in %s on line %d +NULL +object(Object1)#%d (0) { +} +string(4) "test" +object(Object1)#%d (0) { +} +Done diff --git a/ext/reflection/tests/bug38465.phpt b/ext/reflection/tests/bug38465.phpt new file mode 100644 index 0000000..f40d487 --- /dev/null +++ b/ext/reflection/tests/bug38465.phpt @@ -0,0 +1,64 @@ +--TEST-- +Bug #38465 (ReflectionParameter fails on access to self::) +--FILE-- +<?php +class Baz { + const B = 3; +} + +class Foo { + const X = 1; + public function x($a = self::X, $b = Baz::B, $c = 99) {} +} + +class Bar extends Foo { + const Y = 2; + public function y($a = self::Y, $b = Baz::B, $c = 99) {} +} + + +echo "From global scope:\n"; + +$clazz = new ReflectionClass('Bar'); +foreach ($clazz->getMethods() as $method) { + foreach ($method->getParameters() as $param) { + if ($param->isDefaultValueAvailable()) { + echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n"; + } + } +} + +echo "\nFrom class context:\n"; + +class Test { + function __construct() { + $clazz = new ReflectionClass('Bar'); + foreach ($clazz->getMethods() as $method) { + foreach ($method->getParameters() as $param) { + if ($param->isDefaultValueAvailable()) { + echo $method->getDeclaringClass()->getName(), '::', $method->getName(), '($', $param->getName(), ' = ', $param->getDefaultValue(), ")\n"; + } + } + } + } +} + +new Test(); + +?> +--EXPECT-- +From global scope: +Bar::y($a = 2) +Bar::y($b = 3) +Bar::y($c = 99) +Foo::x($a = 1) +Foo::x($b = 3) +Foo::x($c = 99) + +From class context: +Bar::y($a = 2) +Bar::y($b = 3) +Bar::y($c = 99) +Foo::x($a = 1) +Foo::x($b = 3) +Foo::x($c = 99) diff --git a/ext/reflection/tests/bug38653.phpt b/ext/reflection/tests/bug38653.phpt new file mode 100644 index 0000000..68781d2 --- /dev/null +++ b/ext/reflection/tests/bug38653.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #38653 (memory leak in ReflectionClass::getConstant()) +--FILE-- +<?php + +class foo { + const cons = 10; + const cons1 = ""; + const cons2 = "test"; +} + +class bar extends foo { +} + +$foo = new ReflectionClass("foo"); +var_dump($foo->getConstant("cons")); +var_dump($foo->getConstant("cons1")); +var_dump($foo->getConstant("cons2")); +var_dump($foo->getConstant("no such const")); + +echo "Done\n"; +?> +--EXPECTF-- +int(10) +string(0) "" +string(4) "test" +bool(false) +Done diff --git a/ext/reflection/tests/bug38942.phpt b/ext/reflection/tests/bug38942.phpt new file mode 100644 index 0000000..817190c --- /dev/null +++ b/ext/reflection/tests/bug38942.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #38942 (Double old-style-ctor inheritance) +--FILE-- +<?php +class foo { + public function foo() {} +} + +class bar extends foo { +} +ReflectionClass::export("bar"); +?> +--EXPECTF-- +Class [ <user> class bar extends foo ] { + @@ %sbug38942.php 6-7 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user, inherits foo, ctor> public method foo ] { + @@ %sbug38942.php 3 - 3 + } + } +} diff --git a/ext/reflection/tests/bug39001.phpt b/ext/reflection/tests/bug39001.phpt new file mode 100644 index 0000000..1ed675f --- /dev/null +++ b/ext/reflection/tests/bug39001.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #39001 (ReflectionProperty returns incorrect declaring class for protected properties) +--FILE-- +<?php + +class Meta { +} + +class CParent extends Meta { + public $publicVar; + protected $protectedVar; +} + +class Child extends CParent { +} + +$r = new ReflectionClass('Child'); + +var_dump($r->getProperty('publicVar')->getDeclaringClass()->getName()); +var_dump($r->getProperty('protectedVar')->getDeclaringClass()->getName()); + +echo "Done\n"; +?> +--EXPECTF-- +string(7) "CParent" +string(7) "CParent" +Done diff --git a/ext/reflection/tests/bug39067.phpt b/ext/reflection/tests/bug39067.phpt new file mode 100644 index 0000000..8a7a604 --- /dev/null +++ b/ext/reflection/tests/bug39067.phpt @@ -0,0 +1,45 @@ +--TEST-- +Bug #39067 (getDeclaringClass() and private properties) +--FILE-- +<?php + +class A { + private $x; +} + +class B extends A { + private $x; +} + +class C extends B { + private $x; +} + +$rc = new ReflectionClass('C'); +var_dump($rc->getProperty('x')->getDeclaringClass()->getName()); + +$rc = new ReflectionClass('B'); +var_dump($rc->getProperty('x')->getDeclaringClass()->getName()); + +$rc = new ReflectionClass('A'); +var_dump($rc->getProperty('x')->getDeclaringClass()->getName()); + +class Test { + private $x; +} + +class Test2 extends Test { + public $x; +} + +$rc = new ReflectionClass('Test2'); +var_dump($rc->getProperty('x')->getDeclaringClass()->getName()); + +echo "Done\n"; +?> +--EXPECTF-- +string(1) "C" +string(1) "B" +string(1) "A" +string(5) "Test2" +Done diff --git a/ext/reflection/tests/bug39884.phpt b/ext/reflection/tests/bug39884.phpt new file mode 100644 index 0000000..dbc57ee --- /dev/null +++ b/ext/reflection/tests/bug39884.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #39884 (ReflectionParameter::getClass() throws exception for type hint self) +--FILE-- +<?php +class stubParamTest +{ + function paramTest(self $param) + { + // nothing to do + } +} +$test1 = new stubParamTest(); +$test2 = new stubParamTest(); +$test1->paramTest($test2); +$refParam = new ReflectionParameter(array('stubParamTest', 'paramTest'), 'param'); +var_dump($refParam->getClass()); +?> +--EXPECT-- +object(ReflectionClass)#4 (1) { + ["name"]=> + string(13) "stubParamTest" +} diff --git a/ext/reflection/tests/bug40431.phpt b/ext/reflection/tests/bug40431.phpt new file mode 100644 index 0000000..863df7a --- /dev/null +++ b/ext/reflection/tests/bug40431.phpt @@ -0,0 +1,136 @@ +--TEST-- +Bug #40431 (dynamic properties may cause crash in ReflectionProperty methods) +--FILE-- +<?php + +echo "=== 1st test ===\n"; +$Obj = new stdClass; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "=== 2nd test ===\n"; + +class test1 { +} + +class test2 extends test1{ +} + +$Obj = new test2; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "=== 3rd test ===\n"; + +class test3 { +} + +$Obj = new test3; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "=== 4th test ===\n"; + +class test5 { + private $value = 1; +} + +class test4 extends test5{ +} + +$Obj = new test4; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "Done\n"; +?> +--EXPECTF-- +=== 1st test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(8) "stdClass" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +=== 2nd test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(5) "test2" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +=== 3rd test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(5) "test3" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +=== 4th test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(5) "test4" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +Done diff --git a/ext/reflection/tests/bug40794.phpt b/ext/reflection/tests/bug40794.phpt new file mode 100644 index 0000000..bb93b91 --- /dev/null +++ b/ext/reflection/tests/bug40794.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #40794 (ReflectionObject::getValues() may crash when used with dynamic properties) +--FILE-- +<?php + +$obj = new stdClass(); +$obj->prop1 = '1'; +$obj->prop2 = '2'; +$obj->prop3 = '3'; + +$reflect = new ReflectionObject($obj); + +$array = array(); +foreach($reflect->getProperties() as $prop) +{ + $array[$prop->getName()] = $prop->getValue($obj); +} + +var_dump($array); + +echo "Done\n"; +?> +--EXPECTF-- +array(3) { + ["prop1"]=> + string(1) "1" + ["prop2"]=> + string(1) "2" + ["prop3"]=> + string(1) "3" +} +Done diff --git a/ext/reflection/tests/bug41061.phpt b/ext/reflection/tests/bug41061.phpt new file mode 100644 index 0000000..771cd40 --- /dev/null +++ b/ext/reflection/tests/bug41061.phpt @@ -0,0 +1,28 @@ +--TEST-- +Reflection Bug #41061 ("visibility error" in ReflectionFunction::export()) +--FILE-- +<?php + +function foo() { +} + +class bar { + private function foo() { + } +} + +Reflection::export(new ReflectionFunction('foo')); +Reflection::export(new ReflectionMethod('bar', 'foo')); +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +Function [ <user> function foo ] { + @@ %sbug41061.php 3 - 4 +} + +Method [ <user> private method foo ] { + @@ %sbug41061.php 7 - 8 +} + +===DONE=== diff --git a/ext/reflection/tests/bug41884.phpt b/ext/reflection/tests/bug41884.phpt new file mode 100644 index 0000000..f8c0a0a --- /dev/null +++ b/ext/reflection/tests/bug41884.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #41884 (ReflectionClass::getDefaultProperties() does not handle static attributes) +--FILE-- +<?php + +class Foo +{ + protected static $fooStatic = 'foo'; + protected $foo = 'foo'; +} + +$class = new ReflectionClass('Foo'); + +var_dump($class->getDefaultProperties()); + +echo "Done\n"; +?> +--EXPECTF-- +array(2) { + ["fooStatic"]=> + string(3) "foo" + ["foo"]=> + string(3) "foo" +} +Done diff --git a/ext/reflection/tests/bug42976.phpt b/ext/reflection/tests/bug42976.phpt new file mode 100644 index 0000000..2e4ade2 --- /dev/null +++ b/ext/reflection/tests/bug42976.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #42976 (Crash when constructor for newInstance() or newInstanceArgs() fails) +--FILE-- +<?php + +Class C { + function __construct(&$x) { + $x = "x.changed"; + } +} + +$x = "x.original"; +new C($x); // OK +var_dump($x); + +$rc = new ReflectionClass('C'); +$x = "x.original"; +$rc->newInstance($x); // causes crash +var_dump($x); +$x = "x.original"; +$rc->newInstanceArgs(array($x)); // causes crash +var_dump($x); + +echo "Done\n"; +?> +--EXPECTF-- +string(9) "x.changed" + +Warning: Parameter 1 to C::__construct() expected to be a reference, value given in %sbug42976.php on line 15 + +Warning: ReflectionClass::newInstance(): Invocation of C's constructor failed in %sbug42976.php on line 15 +string(10) "x.original" + +Warning: Parameter 1 to C::__construct() expected to be a reference, value given in %sbug42976.php on line 18 + +Warning: ReflectionClass::newInstanceArgs(): Invocation of C's constructor failed in %sbug42976.php on line 18 +string(10) "x.original" +Done diff --git a/ext/reflection/tests/bug43926.phpt b/ext/reflection/tests/bug43926.phpt new file mode 100644 index 0000000..95bdb9e --- /dev/null +++ b/ext/reflection/tests/bug43926.phpt @@ -0,0 +1,67 @@ +--TEST-- +Bug #43926 (isInstance() isn't equivalent to instanceof operator) +--FILE-- +<?php + +class E { +} +class D extends E { +} + +class A extends D { +} + +class C extends A { +} + +$ra = new ReflectionClass('A'); +$rc = new ReflectionClass('C'); +$rd = new ReflectionClass('D'); +$re = new ReflectionClass('E'); + +$ca = $ra->newInstance(); +$cc = $rc->newInstance(); +$cd = $rd->newInstance(); +$ce = $re->newInstance(); + +print("Is? A ". ($ra->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof A) ? 'true' : 'false') ."\n"); +print("Is? C ". ($rc->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof C) ? 'true' : 'false') ."\n"); +print("Is? D ". ($rd->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof D) ? 'true' : 'false') ."\n"); +print("Is? E ". ($re->isInstance($ca) ? 'true' : 'false') .", instanceof: ". (($ca instanceof E) ? 'true' : 'false') ."\n"); +print "-\n"; +print("Is? A ". ($ra->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof A) ? 'true' : 'false') ."\n"); +print("Is? C ". ($rc->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof C) ? 'true' : 'false') ."\n"); +print("Is? D ". ($rd->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof D) ? 'true' : 'false') ."\n"); +print("Is? E ". ($re->isInstance($cc) ? 'true' : 'false') .", instanceof: ". (($cc instanceof E) ? 'true' : 'false') ."\n"); +print "-\n"; +print("Is? A ". ($ra->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof A) ? 'true' : 'false') ."\n"); +print("Is? C ". ($rc->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof C) ? 'true' : 'false') ."\n"); +print("Is? D ". ($rd->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof D) ? 'true' : 'false') ."\n"); +print("Is? E ". ($re->isInstance($cd) ? 'true' : 'false') .", instanceof: ". (($cd instanceof E) ? 'true' : 'false') ."\n"); +print "-\n"; +print("Is? A ". ($ra->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof A) ? 'true' : 'false') ."\n"); +print("Is? C ". ($rc->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof C) ? 'true' : 'false') ."\n"); +print("Is? D ". ($rd->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof D) ? 'true' : 'false') ."\n"); +print("Is? E ". ($re->isInstance($ce) ? 'true' : 'false') .", instanceof: ". (($ce instanceof E) ? 'true' : 'false') ."\n"); + +?> +--EXPECT-- +Is? A true, instanceof: true +Is? C false, instanceof: false +Is? D true, instanceof: true +Is? E true, instanceof: true +- +Is? A true, instanceof: true +Is? C true, instanceof: true +Is? D true, instanceof: true +Is? E true, instanceof: true +- +Is? A false, instanceof: false +Is? C false, instanceof: false +Is? D true, instanceof: true +Is? E true, instanceof: true +- +Is? A false, instanceof: false +Is? C false, instanceof: false +Is? D false, instanceof: false +Is? E true, instanceof: true diff --git a/ext/reflection/tests/bug45139.phpt b/ext/reflection/tests/bug45139.phpt new file mode 100644 index 0000000..6aa8426 --- /dev/null +++ b/ext/reflection/tests/bug45139.phpt @@ -0,0 +1,58 @@ +--TEST-- +Bug #45139 (ReflectionProperty returns incorrect declaring class) +--FILE-- +<?php + +class A { + private $foo; +} + +class B extends A { + protected $bar; + private $baz; + private $quux; +} + +class C extends B { + public $foo; + private $baz; + protected $quux; +} + +$rc = new ReflectionClass('C'); +$rp = $rc->getProperty('foo'); +var_dump($rp->getDeclaringClass()->getName()); // c + +$rc = new ReflectionClass('A'); +$rp = $rc->getProperty('foo'); +var_dump($rp->getDeclaringClass()->getName()); // A + +$rc = new ReflectionClass('B'); +$rp = $rc->getProperty('bar'); +var_dump($rp->getDeclaringClass()->getName()); // B + +$rc = new ReflectionClass('C'); +$rp = $rc->getProperty('bar'); +var_dump($rp->getDeclaringClass()->getName()); // B + +$rc = new ReflectionClass('C'); +$rp = $rc->getProperty('baz'); +var_dump($rp->getDeclaringClass()->getName()); // C + +$rc = new ReflectionClass('B'); +$rp = $rc->getProperty('baz'); +var_dump($rp->getDeclaringClass()->getName()); // B + +$rc = new ReflectionClass('C'); +$rp = $rc->getProperty('quux'); +var_dump($rp->getDeclaringClass()->getName()); // C + +?> +--EXPECT-- +string(1) "C" +string(1) "A" +string(1) "B" +string(1) "B" +string(1) "C" +string(1) "B" +string(1) "C" diff --git a/ext/reflection/tests/bug45571.phpt b/ext/reflection/tests/bug45571.phpt new file mode 100644 index 0000000..4df542e --- /dev/null +++ b/ext/reflection/tests/bug45571.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #45571 (ReflectionClass::export() shows superclasses' private static methods.) +--FILE-- +<?php + +Class A { + static private $a = 0; + static protected $b = 1; + static public $c = 2; + + private function f() {} + private static function sf() {} +} + +Class C extends A { } + +ReflectionClass::export("C"); + +?> +--EXPECTF-- +Class [ <user> class C extends A ] { + @@ %s 12-12 + + - Constants [0] { + } + + - Static properties [2] { + Property [ protected static $b ] + Property [ public static $c ] + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/bug45765.phpt b/ext/reflection/tests/bug45765.phpt new file mode 100644 index 0000000..b0c1be2 --- /dev/null +++ b/ext/reflection/tests/bug45765.phpt @@ -0,0 +1,82 @@ +--TEST-- +Fixed bug #45765 (ReflectionObject with default parameters of self::xxx cause an error) +--FILE-- +<?php + +class foo2 { + const BAR = 'foobar'; +} + +class foo extends foo2 { + const BAR = "foo's bar"; + + function test($a = self::BAR) { + } + + function test2($a = parent::BAR) { + } + + function test3($a = foo::BAR) { + } + + function test4($a = foo2::BAR) { + } +} + +ReflectionObject::export(new foo); + +?> +--EXPECTF-- +Object of class [ <user> class foo extends foo2 ] { + @@ %s 7-21 + + - Constants [1] { + Constant [ string BAR ] { foo's bar } + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Dynamic properties [0] { + } + + - Methods [4] { + Method [ <user> public method test ] { + @@ %s 10 - 11 + + - Parameters [1] { + Parameter #0 [ <optional> $a = 'foo's bar' ] + } + } + + Method [ <user> public method test2 ] { + @@ %s 13 - 14 + + - Parameters [1] { + Parameter #0 [ <optional> $a = 'foobar' ] + } + } + + Method [ <user> public method test3 ] { + @@ %s 16 - 17 + + - Parameters [1] { + Parameter #0 [ <optional> $a = 'foo's bar' ] + } + } + + Method [ <user> public method test4 ] { + @@ %s 19 - 20 + + - Parameters [1] { + Parameter #0 [ <optional> $a = 'foobar' ] + } + } + } +} diff --git a/ext/reflection/tests/bug46064.phpt b/ext/reflection/tests/bug46064.phpt new file mode 100644 index 0000000..510e71b --- /dev/null +++ b/ext/reflection/tests/bug46064.phpt @@ -0,0 +1,76 @@ +--TEST-- +Bug #46064 (Exception when creating ReflectionProperty object on dynamicly created property) +--FILE-- +<?php + +class x { + public $zzz = 2; +} + +$o = new x; +$o->z = 1000; +$o->zzz = 3; + +var_dump($h = new reflectionproperty($o, 'z')); +var_dump($h->isDefault()); +var_dump($h->isPublic()); +var_dump($h->isStatic()); +var_dump($h->getName()); +var_dump(Reflection::getModifierNames($h->getModifiers())); +var_dump($h->getValue($o)); + +print "---------------------------\n"; +try { + var_dump(new reflectionproperty($o, 'zz')); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +var_dump(new reflectionproperty($o, 'zzz')); + +class test { + protected $a = 1; +} + +class bar extends test { + public function __construct() { + $this->foobar = 2; + $this->a = 200; + + $p = new reflectionproperty($this, 'foobar'); + var_dump($p->getValue($this), $p->isDefault(), $p->isPublic()); + } +} + +new bar; + +?> +===DONE=== +--EXPECTF-- +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(1) "z" + ["class"]=> + string(1) "x" +} +bool(false) +bool(true) +bool(false) +string(1) "z" +array(1) { + [0]=> + string(6) "public" +} +int(1000) +--------------------------- +string(30) "Property x::$zz does not exist" +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(3) "zzz" + ["class"]=> + string(1) "x" +} +int(2) +bool(false) +bool(true) +===DONE=== diff --git a/ext/reflection/tests/bug46064_2.phpt b/ext/reflection/tests/bug46064_2.phpt new file mode 100644 index 0000000..da14148 --- /dev/null +++ b/ext/reflection/tests/bug46064_2.phpt @@ -0,0 +1,74 @@ +--TEST-- +Bug #46064.2 (Exception when creating ReflectionProperty object on dynamicly created property) +--FILE-- +<?php + +class foo { +} + +$x = new foo; +$x->test = 2000; + + +$p = new ReflectionObject($x); +var_dump($p->getProperty('test')); + + +class bar { + public function __construct() { + $this->a = 1; + } +} + +class test extends bar { + private $b = 2; + + public function __construct() { + parent::__construct(); + + $p = new reflectionobject($this); + var_dump($h = $p->getProperty('a')); + var_dump($h->isDefault(), $h->isProtected(), $h->isPrivate(), $h->isPublic(), $h->isStatic()); + var_dump($p->getProperties()); + } +} + +new test; + +?> +===DONE=== +--EXPECTF-- +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(4) "test" + ["class"]=> + string(3) "foo" +} +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(1) "a" + ["class"]=> + string(4) "test" +} +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +array(2) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(1) "b" + ["class"]=> + string(4) "test" + } + [1]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(1) "a" + ["class"]=> + string(4) "test" + } +} +===DONE===
\ No newline at end of file diff --git a/ext/reflection/tests/bug46205.phpt b/ext/reflection/tests/bug46205.phpt new file mode 100644 index 0000000..ef7a692 --- /dev/null +++ b/ext/reflection/tests/bug46205.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #46205 (Closure - Memory leaks when ReflectionException is thrown) +--FILE-- +<?php +$x = new reflectionmethod('reflectionparameter', 'export'); +$y = function() { }; + +try { + $x->invokeArgs(new reflectionparameter('trim', 'str'), array($y, 1)); +} catch (Exception $e) { } +?> +ok +--EXPECT-- +ok diff --git a/ext/reflection/tests/bug47254.phpt b/ext/reflection/tests/bug47254.phpt new file mode 100644 index 0000000..83593a4 --- /dev/null +++ b/ext/reflection/tests/bug47254.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #47254 +--CREDITS-- +Sebastian Schürmann +sebs@php.net +Testfest 2009 Munich +--FILE-- +<?php +class A +{ + protected function a() {} + +} + +class B extends A +{ + public function b() {} +} + +$B = new B(); +$R = new ReflectionObject($B); +$m = $R->getMethods(); +print_r($m); + +?> +--EXPECT-- +Array +( + [0] => ReflectionMethod Object + ( + [name] => b + [class] => B + ) + + [1] => ReflectionMethod Object + ( + [name] => a + [class] => A + ) + +) diff --git a/ext/reflection/tests/bug48336.phpt b/ext/reflection/tests/bug48336.phpt new file mode 100644 index 0000000..ee90675 --- /dev/null +++ b/ext/reflection/tests/bug48336.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #48286 (ReflectionProperty::getDeclaringClass() does not work with redeclared properties) +--FILE-- +<?php +class A { +} + +class B extends A { + static protected $prop; +} + +class C extends B { + static protected $prop; +} + +class D extends C { +} + +class E extends D { +} + +class F extends E { + static protected $prop; +} + +$class = 'A'; +for($class = 'A'; $class <= 'F'; $class ++) { + print($class.' => '); + try { + $rp = new ReflectionProperty($class, 'prop'); + print($rp->getDeclaringClass()->getName()); + } catch(Exception $e) { + print('N/A'); + } + print("\n"); +} +?> +--EXPECT-- +A => N/A +B => B +C => C +D => C +E => C +F => F diff --git a/ext/reflection/tests/bug48757.phpt b/ext/reflection/tests/bug48757.phpt new file mode 100644 index 0000000..a5ced91 --- /dev/null +++ b/ext/reflection/tests/bug48757.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #48757 (ReflectionFunction::invoke() parameter issues) +--FILE-- +<?php +function test() { + echo "Hello World\n"; +} + +function another_test($parameter) { + var_dump($parameter); +} + +$func = new ReflectionFunction('test'); +$func->invoke(); + +$func = new ReflectionFunction('another_test'); +$func->invoke('testing'); +?> +--EXPECT-- +Hello World +string(7) "testing" diff --git a/ext/reflection/tests/bug49074.phpt b/ext/reflection/tests/bug49074.phpt new file mode 100644 index 0000000..7ce23b4 --- /dev/null +++ b/ext/reflection/tests/bug49074.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #49074 (private class static fields can be modified by using reflection) +--FILE-- +<?php +class Test { + private static $data1 = 1; + private static $data4 = 4; +} + +class Test2 extends Test { + private static $data2 = 2; + public static $data3 = 3; +} + +$r = new ReflectionClass('Test2'); +$m = $r->getStaticProperties(); + +$m['data1'] = 100; +$m['data2'] = 200; +$m['data3'] = 300; +$m['data4'] = 400; + +var_dump($r->getStaticProperties()); +?> +--EXPECT-- +array(2) { + ["data2"]=> + int(2) + ["data3"]=> + int(3) +} diff --git a/ext/reflection/tests/bug49092.phpt b/ext/reflection/tests/bug49092.phpt new file mode 100644 index 0000000..460a131 --- /dev/null +++ b/ext/reflection/tests/bug49092.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #49092 (ReflectionFunction fails to work with functions in fully qualified namespaces) +--FILE-- +<?php +namespace ns; +function func(){} +new \ReflectionFunction('ns\func'); +new \ReflectionFunction('\ns\func'); +echo "Ok\n" +?> +--EXPECT-- +Ok diff --git a/ext/reflection/tests/bug49719.phpt b/ext/reflection/tests/bug49719.phpt new file mode 100644 index 0000000..215140a --- /dev/null +++ b/ext/reflection/tests/bug49719.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #49719 (ReflectionClass::hasProperty returns true for a private property in base class) +--FILE-- +<?php + +class A { + private $a; +} +class B extends A { + private $b; +} + +try { + $b = new B; + $ref = new ReflectionClass($b); + + var_dump(property_exists('b', 'a')); + var_dump(property_exists($b, 'a')); + var_dump($ref->hasProperty('a')); + var_dump($ref->getProperty('a')); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +class A2 { + private $a = 1; +} + +class B2 extends A2 { + private $a = 2; +} + +$b2 = new ReflectionClass('B2'); +$prop = $b2->getProperty('a'); +$prop->setAccessible(true); +var_dump($prop->getValue(new b2)); + +?> +--EXPECTF-- +bool(false) +bool(false) +bool(false) +%string|unicode%(25) "Property a does not exist" +int(2) diff --git a/ext/reflection/tests/bug51905.phpt b/ext/reflection/tests/bug51905.phpt new file mode 100644 index 0000000..8969924 --- /dev/null +++ b/ext/reflection/tests/bug51905.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #51905 (ReflectionParameter fails if default value is an array with an access to self::) +--FILE-- +<?php + +class Bar { + const Y = 20; +} + +class Foo extends Bar { + const X = 12; + public function x($x = 1, $y = array(self::X), $z = parent::Y) {} +} + +$clazz = new ReflectionClass('Foo'); +$method = $clazz->getMethod('x'); +foreach ($method->getParameters() as $param) { + if ( $param->isDefaultValueAvailable()) + echo '$', $param->getName(), ' : ', var_export($param->getDefaultValue(), 1), "\n"; +} + +?> +--EXPECT-- +$x : 1 +$y : array ( + 0 => 12, +) +$z : 20 diff --git a/ext/reflection/tests/bug51911.phpt b/ext/reflection/tests/bug51911.phpt new file mode 100644 index 0000000..12eb459 --- /dev/null +++ b/ext/reflection/tests/bug51911.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #51911 (ReflectionParameter::getDefaultValue() memory leaks with constant array) +--FILE-- +<?php + +class Foo { + const X = 1; + public function x($x = array(1)) {} +} + +$clazz = new ReflectionClass('Foo'); +$method = $clazz->getMethod('x'); +foreach ($method->getParameters() as $param) { + if ( $param->isDefaultValueAvailable()) + echo '$', $param->getName(), ' : ', var_export($param->getDefaultValue(), 1), "\n"; +} + +?> +--EXPECT-- +$x : array ( + 0 => 1, +) diff --git a/ext/reflection/tests/bug52057.phpt b/ext/reflection/tests/bug52057.phpt new file mode 100644 index 0000000..b807035 --- /dev/null +++ b/ext/reflection/tests/bug52057.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #52057 (ReflectionClass fails on Closure class) +--FILE-- +<?php + +$closure = function($a) { echo $a; }; + +$reflection = new ReflectionClass('closure'); +var_dump($reflection->hasMethod('__invoke')); // true + +$reflection = new ReflectionClass($closure); +var_dump($reflection->hasMethod('__invoke')); // true + +$reflection = new ReflectionObject($closure); +var_dump($reflection->hasMethod('__invoke')); // true + +$reflection = new ReflectionClass('closure'); +var_dump($h = $reflection->getMethod('__invoke')); // true +var_dump($h->class.'::'.$h->getName()); + +$reflection = new ReflectionClass($closure); +var_dump($h = $reflection->getMethod('__invoke')); // true +var_dump($h->class.'::'.$h->getName()); + +$reflection = new ReflectionObject($closure); +var_dump($h = $reflection->getMethod('__invoke')); // true +var_dump($h->class.'::'.$h->getName()); + +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +object(ReflectionMethod)#%d (2) { + ["name"]=> + string(8) "__invoke" + ["class"]=> + string(7) "Closure" +} +string(17) "Closure::__invoke" +object(ReflectionMethod)#%d (2) { + ["name"]=> + string(8) "__invoke" + ["class"]=> + string(7) "Closure" +} +string(17) "Closure::__invoke" +object(ReflectionMethod)#%d (2) { + ["name"]=> + string(8) "__invoke" + ["class"]=> + string(7) "Closure" +} +string(17) "Closure::__invoke" diff --git a/ext/reflection/tests/bug52854.phpt b/ext/reflection/tests/bug52854.phpt new file mode 100644 index 0000000..255522d --- /dev/null +++ b/ext/reflection/tests/bug52854.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #52854: ReflectionClass::newInstanceArgs does not work for classes without constructors +--FILE-- +<?php +class Test { +} +$c = new ReflectionClass('Test'); +var_dump(new Test); +var_dump(new Test()); +var_dump($c->newInstance()); +var_dump($c->newInstanceArgs(array())); + +try { + var_dump($c->newInstanceArgs(array(1))); +} catch(ReflectionException $e) { + echo $e->getMessage()."\n"; +} +?> +--EXPECTF-- +object(Test)#%d (0) { +} +object(Test)#%d (0) { +} +object(Test)#%d (0) { +} +object(Test)#%d (0) { +} +Class Test does not have a constructor, so you cannot pass any constructor arguments diff --git a/ext/reflection/tests/bug53366.phpt b/ext/reflection/tests/bug53366.phpt new file mode 100644 index 0000000..5fb119d --- /dev/null +++ b/ext/reflection/tests/bug53366.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #53366 (Reflection doesnt get dynamic property value from getProperty()) +--FILE-- +<?php + +class UserClass { +} + +$myClass = new UserClass; +$myClass->id = 1000; + +$reflect = new ReflectionObject($myClass); + +var_dump($reflect->getProperty('id')); +var_dump($reflect->getProperty('id')->getValue($myClass)); + +?> +--EXPECTF-- +object(ReflectionProperty)#%d (2) { + ["name"]=> + string(2) "id" + ["class"]=> + string(9) "UserClass" +} +int(1000) diff --git a/ext/reflection/tests/bug53915.phpt b/ext/reflection/tests/bug53915.phpt new file mode 100644 index 0000000..f2f2ae5 --- /dev/null +++ b/ext/reflection/tests/bug53915.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #53915 - ReflectionClass::getConstant(s) emits fatal error on selfreferencing constants +--FILE-- +<?php +Class Foo +{ + const A = 1; + const B = self::A; +} + +$rc = new ReflectionClass('Foo'); +print_r($rc->getConstants()); + +Class Foo2 +{ + const A = 1; + const B = self::A; +} + +$rc = new ReflectionClass('Foo2'); +print_r($rc->getConstant('B')); +--EXPECT-- +Array +( + [A] => 1 + [B] => 1 +) +1 diff --git a/ext/reflection/tests/bug60357.phpt b/ext/reflection/tests/bug60357.phpt new file mode 100644 index 0000000..a5ddd40 --- /dev/null +++ b/ext/reflection/tests/bug60357.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #60357 (__toString() method triggers E_NOTICE "Array to string conversion") +--FILE-- +<?php +function foo( array $x = array( 'a', 'b' ) ) {} +$r = new ReflectionParameter( 'foo', 0 ); +echo $r->__toString(); +?> +--EXPECTF-- +Parameter #0 [ <optional> array $x = Array ] diff --git a/ext/reflection/tests/bug60367.phpt b/ext/reflection/tests/bug60367.phpt new file mode 100644 index 0000000..5c4a098 --- /dev/null +++ b/ext/reflection/tests/bug60367.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #60367 (Reflection and Late Static Binding) +--FILE-- +<?php +abstract class A { + + const WHAT = 'A'; + + public static function call() { + echo static::WHAT; + } + +} + +class B extends A { + + const WHAT = 'B'; + +} + +$method = new ReflectionMethod("b::call"); +$method->invoke(null); +$method->invokeArgs(null, array()); +$method = new ReflectionMethod("A::call"); +$method->invoke(null); +$method->invokeArgs(null, array()); +--EXPECTF-- +BBAA diff --git a/ext/reflection/tests/bug61388.phpt b/ext/reflection/tests/bug61388.phpt new file mode 100644 index 0000000..75c0300 --- /dev/null +++ b/ext/reflection/tests/bug61388.phpt @@ -0,0 +1,32 @@ +--TEST-- +ReflectionObject:getProperties() issues invalid reads when it get_properties returns a hash table with (inaccessible) dynamic numeric properties +--FILE-- +<?php +$x = new ArrayObject(); +$x[0] = 'test string 2'; +$x['test'] = 'test string 3'; +$reflObj = new ReflectionObject($x); +print_r($reflObj->getProperties(ReflectionProperty::IS_PUBLIC)); + +$x = (object)array("a", "oo" => "b"); +$reflObj = new ReflectionObject($x); +print_r($reflObj->getProperties(ReflectionProperty::IS_PUBLIC)); +--EXPECT-- +Array +( + [0] => ReflectionProperty Object + ( + [name] => test + [class] => ArrayObject + ) + +) +Array +( + [0] => ReflectionProperty Object + ( + [name] => oo + [class] => stdClass + ) + +) diff --git a/ext/reflection/tests/bug62384.phpt b/ext/reflection/tests/bug62384.phpt new file mode 100644 index 0000000..90a871f --- /dev/null +++ b/ext/reflection/tests/bug62384.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #62384 (Attempting to invoke a Closure more than once causes segfaul) +--FILE-- +<?php + +$closure1 = function($val){ return $val; }; +$closure2 = function($val){ return $val; }; + +$reflection_class = new ReflectionClass($closure1); +$reflection_method = $reflection_class->getMethod('__invoke'); + +$arguments1 = array('hello'); +$arguments2 = array('world'); + +var_dump($reflection_method->invokeArgs($closure1, $arguments1)); +var_dump($reflection_method->invokeArgs($closure2, $arguments2)); + +?> +--EXPECT-- +string(5) "hello" +string(5) "world" diff --git a/ext/reflection/tests/bug62715.phpt b/ext/reflection/tests/bug62715.phpt new file mode 100644 index 0000000..feb67f6 --- /dev/null +++ b/ext/reflection/tests/bug62715.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #62715 (ReflectionParameter::isDefaultValueAvailable() wrong result) +--FILE-- +<?php + +function test(PDO $a = null, $b = 0, array $c) {} +$r = new ReflectionFunction('test'); + +foreach ($r->getParameters() as $p) { + var_dump($p->isDefaultValueAvailable()); +} + +foreach ($r->getParameters() as $p) { + if ($p->isDefaultValueAvailable()) { + var_dump($p->getDefaultValue()); + } +} +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +NULL +int(0) diff --git a/ext/reflection/tests/bug63399.phpt b/ext/reflection/tests/bug63399.phpt new file mode 100644 index 0000000..393b861 --- /dev/null +++ b/ext/reflection/tests/bug63399.phpt @@ -0,0 +1,49 @@ +--TEST-- +Bug #63399 (ReflectionClass::getTraitAliases() incorrectly resolves traitnames) +--FILE-- +<?php +trait Trait1 { + public function run() {} + public function say() {} +} + +trait Trait2 { + public function run() {} + public function say() {} +} + +class MyClass +{ + use Trait1, Trait2 { + Trait1::run as execute; + Trait1::say insteadof Trait2; + Trait2::run insteadof Trait1; + Trait2::say as talk; + } +} + +$ref = new ReflectionClass('MyClass'); + +print_r($ref->getTraitAliases()); +print_r($ref->getTraits()); + +?> +--EXPECT-- +Array +( + [execute] => Trait1::run + [talk] => Trait2::say +) +Array +( + [Trait1] => ReflectionClass Object + ( + [name] => Trait1 + ) + + [Trait2] => ReflectionClass Object + ( + [name] => Trait2 + ) + +) diff --git a/ext/reflection/tests/bug63614.phpt b/ext/reflection/tests/bug63614.phpt new file mode 100644 index 0000000..c13ff4b --- /dev/null +++ b/ext/reflection/tests/bug63614.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #63614 (Fatal error on Reflection) +--FILE-- +<?php +function dummy() { + static $a = array(); +} + +class Test +{ + const A = 0; + + public function func() + { + static $a = array( + self::A => 'a' + ); + } +} + +$reflect = new ReflectionFunction("dummy"); +print_r($reflect->getStaticVariables()); +$reflect = new ReflectionMethod('Test', 'func'); +print_r($reflect->getStaticVariables()); +?> +--EXPECT-- +Array +( + [a] => Array + ( + ) + +) +Array +( + [a] => Array + ( + [0] => a + ) + +) diff --git a/ext/reflection/tests/closures_001.phpt b/ext/reflection/tests/closures_001.phpt new file mode 100644 index 0000000..6cc7e67 --- /dev/null +++ b/ext/reflection/tests/closures_001.phpt @@ -0,0 +1,70 @@ +--TEST-- +Reflection on closures +--FILE-- +<?php + +$closure = function($a, $b = 0) { }; + +$ro = new ReflectionObject($closure); +$rm = $ro->getMethod('__invoke'); +var_dump($rm->getNumberOfParameters()); +var_dump($rm->getNumberOfRequiredParameters()); +$rms = $ro->getMethods(); +foreach($rms as $rm) { + if ($rm->getName() == '__invoke') { + var_dump($rm->getNumberOfParameters()); + var_dump($rm->getNumberOfRequiredParameters()); + } +} + +echo "---\n"; + +$rm = new ReflectionMethod($closure, '__invoke'); +var_dump($rm->getName()); +var_dump($rm->getNumberOfParameters()); +var_dump($rm->getNumberOfRequiredParameters()); + +echo "---\n"; + +$rp = new ReflectionParameter(array($closure, '__invoke'), 0); +var_dump($rp->isOptional()); +$rp = new ReflectionParameter(array($closure, '__invoke'), 1); +var_dump($rp->isOptional()); +$rp = new ReflectionParameter(array($closure, '__invoke'), 'a'); +var_dump($rp->isOptional()); +$rp = new ReflectionParameter(array($closure, '__invoke'), 'b'); +var_dump($rp->isOptional()); + +echo "---\n"; + +$rp = new ReflectionParameter($closure, 0); +var_dump($rp->isOptional()); +$rp = new ReflectionParameter($closure, 1); +var_dump($rp->isOptional()); +$rp = new ReflectionParameter($closure, 'a'); +var_dump($rp->isOptional()); +$rp = new ReflectionParameter($closure, 'b'); +var_dump($rp->isOptional()); + +?> +===DONE=== +--EXPECTF-- +int(2) +int(1) +int(2) +int(1) +--- +string(8) "__invoke" +int(2) +int(1) +--- +bool(false) +bool(true) +bool(false) +bool(true) +--- +bool(false) +bool(true) +bool(false) +bool(true) +===DONE=== diff --git a/ext/reflection/tests/closures_002.phpt b/ext/reflection/tests/closures_002.phpt new file mode 100644 index 0000000..e8b080f --- /dev/null +++ b/ext/reflection/tests/closures_002.phpt @@ -0,0 +1,29 @@ +--TEST-- +Reflection on invokable objects +--FILE-- +<?php + +class Test { + function __invoke($a, $b = 0) { } +} + +$rm = new ReflectionMethod(new Test, '__invoke'); +var_dump($rm->getName()); +var_dump($rm->getNumberOfParameters()); +var_dump($rm->getNumberOfRequiredParameters()); + +$rp = new ReflectionParameter(array(new Test, '__invoke'), 0); +var_dump($rp->isOptional()); + +$rp = new ReflectionParameter(array(new Test, '__invoke'), 1); +var_dump($rp->isOptional()); + +?> +===DONE=== +--EXPECTF-- +string(8) "__invoke" +int(2) +int(1) +bool(false) +bool(true) +===DONE=== diff --git a/ext/reflection/tests/closures_003.phpt b/ext/reflection/tests/closures_003.phpt new file mode 100644 index 0000000..4483dc0 --- /dev/null +++ b/ext/reflection/tests/closures_003.phpt @@ -0,0 +1,25 @@ +--TEST-- +Reflection on closures: Segfaults with getParameters() and getDeclaringFunction() +--FILE-- +<?php + +$closure = function($a, $b = 0) { }; + +$method = new ReflectionMethod ($closure, '__invoke'); +$params = $method->getParameters (); +unset ($method); +$method = $params[0]->getDeclaringFunction (); +unset ($params); +echo $method->getName ()."\n"; + +$parameter = new ReflectionParameter (array ($closure, '__invoke'), 'b'); +$method = $parameter->getDeclaringFunction (); +unset ($parameter); +echo $method->getName ()."\n"; + +?> +===DONE=== +--EXPECTF-- +__invoke +__invoke +===DONE=== diff --git a/ext/reflection/tests/closures_003_v1.phpt b/ext/reflection/tests/closures_003_v1.phpt new file mode 100644 index 0000000..1b8e1c4 --- /dev/null +++ b/ext/reflection/tests/closures_003_v1.phpt @@ -0,0 +1,25 @@ +--TEST-- +Reflection on closures: Segfaults with getParameters() and getDeclaringFunction() +--FILE-- +<?php + +$closure = function($a, $b = 0) { }; + +$method = new ReflectionFunction ($closure); +$params = $method->getParameters (); +unset ($method); +$method = $params[0]->getDeclaringFunction (); +unset ($params); +echo $method->getName ()."\n"; + +$parameter = new ReflectionParameter ($closure, 'b'); +$method = $parameter->getDeclaringFunction (); +unset ($parameter); +echo $method->getName ()."\n"; + +?> +===DONE=== +--EXPECTF-- +{closure} +{closure} +===DONE=== diff --git a/ext/reflection/tests/closures_004.phpt b/ext/reflection/tests/closures_004.phpt new file mode 100644 index 0000000..807aea1 --- /dev/null +++ b/ext/reflection/tests/closures_004.phpt @@ -0,0 +1,43 @@ +--TEST-- +Reflection on closures: Segfault with getClosure() on closure itself +--FILE-- +<?php +$closure = function() { echo "Invoked!\n"; }; + +$method = new ReflectionFunction ($closure); + +$closure2 = $method->getClosure (); + +$closure2 (); +$closure2->__invoke (); + +unset ($closure); + +$closure2 (); +$closure2->__invoke (); + +$closure = function() { echo "Invoked!\n"; }; + +$method = new ReflectionMethod ($closure, '__invoke'); +$closure2 = $method->getClosure ($closure); + +$closure2 (); +$closure2->__invoke (); + +unset ($closure); + +$closure2 (); +$closure2->__invoke (); + +?> +===DONE=== +--EXPECTF-- +Invoked! +Invoked! +Invoked! +Invoked! +Invoked! +Invoked! +Invoked! +Invoked! +===DONE=== diff --git a/ext/reflection/tests/exception.inc b/ext/reflection/tests/exception.inc new file mode 100644 index 0000000..e403339 --- /dev/null +++ b/ext/reflection/tests/exception.inc @@ -0,0 +1,16 @@ +<?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/included4.inc b/ext/reflection/tests/included4.inc new file mode 100644 index 0000000..8894725 --- /dev/null +++ b/ext/reflection/tests/included4.inc @@ -0,0 +1,9 @@ +<?php +echo __FILE__ . "\n"; +echo __LINE__ . "\n"; + +function g() { + echo __FILE__ . "\n"; + echo __LINE__ . "\n"; +} +?>
\ No newline at end of file diff --git a/ext/reflection/tests/parameters_001.phpt b/ext/reflection/tests/parameters_001.phpt new file mode 100644 index 0000000..972b97c --- /dev/null +++ b/ext/reflection/tests/parameters_001.phpt @@ -0,0 +1,38 @@ +--TEST-- +ReflectionParameter Check for parameter being optional +--FILE-- +<?php + +class Test { + function func($x, $y = NULL){ + } +} + + +$f = new ReflectionMethod('Test', 'func'); +var_dump($f->getNumberOfParameters()); +var_dump($f->getNumberOfRequiredParameters()); + +$p = new ReflectionParameter(array('Test', 'func'), 'x'); +var_dump($p->isOptional()); + +$p = new ReflectionParameter(array('Test', 'func'), 'y'); +var_dump($p->isOptional()); + +try { + $p = new ReflectionParameter(array('Test', 'func'), 'z'); + var_dump($p->isOptional()); +} +catch (Exception $e) { + var_dump($e->getMessage()); +} + +?> +===DONE=== +--EXPECT-- +int(2) +int(1) +bool(false) +bool(true) +string(54) "The parameter specified by its name could not be found" +===DONE=== diff --git a/ext/reflection/tests/parameters_002.phpt b/ext/reflection/tests/parameters_002.phpt new file mode 100644 index 0000000..a861910 --- /dev/null +++ b/ext/reflection/tests/parameters_002.phpt @@ -0,0 +1,207 @@ +--TEST-- +ReflectionParameter::getClass(), getDeclaringClass(), getDeclaringFunction() +--FILE-- +<?php + +function test($nix, Array $ar, &$ref, stdClass $std, NonExistingClass $na, stdClass &$opt = NULL, $def = "FooBar") +{ +} + +class test +{ + function test($nix, Array $ar, &$ref, stdClass $std, NonExistingClass $na, stdClass $opt = NULL, $def = "FooBar") + { + } +} + +function check_params_decl_func($r, $f) +{ + $c = $r->$f(); + echo $f . ': ' . ($c ? ($c instanceof ReflectionMethod ? $c->class . '::' : '') . $c->name : 'NULL') . "()\n"; +} + +function check_params_decl_class($r, $f) +{ + $c = $r->$f(); + echo $f . ': ' . ($c ? $c->name : 'NULL') . "\n"; +} + +function check_params_func($r, $f) +{ + echo $f . ': '; + $v = $r->$f(); + var_dump($v); +} + +function check_params($r) +{ + echo "#####" . ($r instanceof ReflectionMethod ? $r->class . '::' : '') . $r->name . "()#####\n"; + $i = 0; + foreach($r->getParameters() as $p) + { + echo "===" . $i . "===\n"; + $i++; + check_params_func($p, 'getName'); + check_params_func($p, 'isPassedByReference'); + try + { + check_params_decl_class($p, 'getClass'); + } + catch(ReflectionException $e) + { + echo $e->getMessage() . "\n"; + } + check_params_decl_class($p, 'getDeclaringClass'); +// check_params_decl_func($p, 'getDeclaringFunction'); + check_params_func($p, 'isArray'); + check_params_func($p, 'allowsNull'); + check_params_func($p, 'isOptional'); + check_params_func($p, 'isDefaultValueAvailable'); + if ($p->isOptional()) + { + check_params_func($p, 'getDefaultValue'); + } + } +} + +check_params(new ReflectionFunction('test')); + +check_params(new ReflectionMethod('test::test')); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECT-- +#####test()##### +===0=== +getName: string(3) "nix" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===1=== +getName: string(2) "ar" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +isArray: bool(true) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===2=== +getName: string(3) "ref" +isPassedByReference: bool(true) +getClass: NULL +getDeclaringClass: NULL +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===3=== +getName: string(3) "std" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: NULL +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===4=== +getName: string(2) "na" +isPassedByReference: bool(false) +Class NonExistingClass does not exist +getDeclaringClass: NULL +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===5=== +getName: string(3) "opt" +isPassedByReference: bool(true) +getClass: stdClass +getDeclaringClass: NULL +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: NULL +===6=== +getName: string(3) "def" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: NULL +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: string(6) "FooBar" +#####test::test()##### +===0=== +getName: string(3) "nix" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===1=== +getName: string(2) "ar" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +isArray: bool(true) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===2=== +getName: string(3) "ref" +isPassedByReference: bool(true) +getClass: NULL +getDeclaringClass: test +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===3=== +getName: string(3) "std" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: test +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===4=== +getName: string(2) "na" +isPassedByReference: bool(false) +Class NonExistingClass does not exist +getDeclaringClass: test +isArray: bool(false) +allowsNull: bool(false) +isOptional: bool(false) +isDefaultValueAvailable: bool(false) +===5=== +getName: string(3) "opt" +isPassedByReference: bool(false) +getClass: stdClass +getDeclaringClass: test +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: NULL +===6=== +getName: string(3) "def" +isPassedByReference: bool(false) +getClass: NULL +getDeclaringClass: test +isArray: bool(false) +allowsNull: bool(true) +isOptional: bool(true) +isDefaultValueAvailable: bool(true) +getDefaultValue: string(6) "FooBar" +===DONE=== diff --git a/ext/reflection/tests/property_exists.phpt b/ext/reflection/tests/property_exists.phpt new file mode 100644 index 0000000..c74b775 --- /dev/null +++ b/ext/reflection/tests/property_exists.phpt @@ -0,0 +1,222 @@ +--TEST-- +Reflection and property_exists() +--FILE-- +<?php + +class A +{ + public $a = 1; + protected $b = 2; + private $c = 3; + + public $empty; + public $init = 1; + + function __toString() + { + return 'obj(' . get_class($this) . ')'; + } + + static function test($oc, $props) + { + echo '===' . __CLASS__ . "===\n"; + foreach($props as $p2) { + echo $oc, '::$' , $p2, "\n"; + var_dump(property_exists($oc, $p2)); + } + } +} + +class B extends A +{ + private $c = 4; + + static function test($oc, $props) + { + echo '===' . __CLASS__ . "===\n"; + foreach($props as $p2) { + echo $oc, '::$' , $p2, "\n"; + var_dump(property_exists($oc, $p2)); + } + } +} + +class C extends B +{ + private $d = 5; + + static function test($oc, $props) + { + echo '===' . __CLASS__ . "===\n"; + foreach($props as $p2) { + echo $oc, '::$' , $p2, "\n"; + var_dump(property_exists($oc, $p2)); + } + } +} + +$oA = new A; +$oA->e = 6; + +$oC = new C; + +$pc = array($oA, 'A', 'B', 'C', $oC); +$pr = array('a', 'b', 'c', 'd', 'e'); + +foreach($pc as $p1) { + if (is_object($p1)) { + $p1->test($p1, $pr); + } else { + $r = new ReflectionMethod($p1, 'test'); + $r->invoke(NULL, $p1, $pr); + } + echo "===GLOBAL===\n"; + foreach($pr as $p2) { + echo $p1, '::$' , $p2, "\n"; + var_dump(property_exists($p1, $p2)); + } +} + +echo "===PROBLEMS===\n"; +var_dump(property_exists(NULL, 'empty')); +var_dump(property_exists(25,'empty')); +var_dump(property_exists('','')); +var_dump(property_exists('A','')); +var_dump(property_exists('A','123')); +var_dump(property_exists('A','init')); +var_dump(property_exists('A','empty')); +var_dump(property_exists(new A, '')); +var_dump(property_exists(new A, '123')); +var_dump(property_exists(new A, 'init')); +var_dump(property_exists(new A, 'empty')); +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +===A=== +obj(A)::$a +bool(true) +obj(A)::$b +bool(true) +obj(A)::$c +bool(true) +obj(A)::$d +bool(false) +obj(A)::$e +bool(true) +===GLOBAL=== +obj(A)::$a +bool(true) +obj(A)::$b +bool(true) +obj(A)::$c +bool(true) +obj(A)::$d +bool(false) +obj(A)::$e +bool(true) +===A=== +A::$a +bool(true) +A::$b +bool(true) +A::$c +bool(true) +A::$d +bool(false) +A::$e +bool(false) +===GLOBAL=== +A::$a +bool(true) +A::$b +bool(true) +A::$c +bool(true) +A::$d +bool(false) +A::$e +bool(false) +===B=== +B::$a +bool(true) +B::$b +bool(true) +B::$c +bool(true) +B::$d +bool(false) +B::$e +bool(false) +===GLOBAL=== +B::$a +bool(true) +B::$b +bool(true) +B::$c +bool(true) +B::$d +bool(false) +B::$e +bool(false) +===C=== +C::$a +bool(true) +C::$b +bool(true) +C::$c +bool(false) +C::$d +bool(true) +C::$e +bool(false) +===GLOBAL=== +C::$a +bool(true) +C::$b +bool(true) +C::$c +bool(false) +C::$d +bool(true) +C::$e +bool(false) +===C=== +obj(C)::$a +bool(true) +obj(C)::$b +bool(true) +obj(C)::$c +bool(false) +obj(C)::$d +bool(true) +obj(C)::$e +bool(false) +===GLOBAL=== +obj(C)::$a +bool(true) +obj(C)::$b +bool(true) +obj(C)::$c +bool(false) +obj(C)::$d +bool(true) +obj(C)::$e +bool(false) +===PROBLEMS=== + +Warning: First parameter must either be an object or the name of an existing class in %sproperty_exists.php on line %d +NULL + +Warning: First parameter must either be an object or the name of an existing class in %sproperty_exists.php on line %d +NULL +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +===DONE=== diff --git a/ext/reflection/tests/static_properties_002.phpt b/ext/reflection/tests/static_properties_002.phpt new file mode 100644 index 0000000..218c629 --- /dev/null +++ b/ext/reflection/tests/static_properties_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +Reflection and inheriting static properties +--FILE-- +<?php + +class base { + static protected $prop = 2; + + static function show() { + echo __METHOD__ . '(' . self::$prop . ")\n"; + } + + static function inc() { + base::$prop++; + echo __METHOD__ . "()\n"; + } +} + +class derived extends base { + static public $prop = 2; + + static function show() { + echo __METHOD__ . '(' . self::$prop . ")\n"; + } + + static function inc() { + derived::$prop++; + echo __METHOD__ . "()\n"; + } +} + +base::show(); +derived::show(); + +base::inc(); + +base::show(); +derived::show(); + +derived::inc(); + +base::show(); +derived::show(); + +$r = new ReflectionClass('derived'); +echo 'Number of properties: '. count($r->getStaticProperties()) . "\n"; + +echo "Done\n"; +?> +--EXPECTF-- +base::show(2) +derived::show(2) +base::inc() +base::show(3) +derived::show(2) +derived::inc() +base::show(3) +derived::show(3) +Number of properties: 1 +Done diff --git a/ext/reflection/tests/traits001.phpt b/ext/reflection/tests/traits001.phpt new file mode 100644 index 0000000..4e36cee --- /dev/null +++ b/ext/reflection/tests/traits001.phpt @@ -0,0 +1,70 @@ +--TEST-- +ReflectionClass and Traits +--FILE-- +<?php +trait Foo { + public function someMethod() { } +} + +class Bar { + use Foo; + + public function someOtherMethod() { } +} + +$rFoo = new ReflectionClass('Foo'); +$rBar = new ReflectionClass('Bar'); + +var_dump($rFoo->isTrait()); +var_dump($rBar->isTrait()); +echo $rFoo; +echo $rBar; +--EXPECTF-- +bool(true) +bool(false) +Trait [ <user> trait Foo ] { + @@ %straits001.php 2-4 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ <user> public method someMethod ] { + @@ %straits001.php 3 - 3 + } + } +} +Class [ <user> class Bar ] { + @@ %straits001.php 6-10 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [2] { + Method [ <user> public method someOtherMethod ] { + @@ %straits001.php 9 - 9 + } + + Method [ <user> public method someMethod ] { + @@ %straits001.php 3 - 3 + } + } +} diff --git a/ext/reflection/tests/traits002.phpt b/ext/reflection/tests/traits002.phpt new file mode 100644 index 0000000..b55b288 --- /dev/null +++ b/ext/reflection/tests/traits002.phpt @@ -0,0 +1,54 @@ +--TEST-- +ReflectionClass and Traits +--FILE-- +<?php + +abstract class foo { +} + +trait bar { + +} + +reflectionclass::export('foo'); +reflectionclass::export('bar'); + +?> +--EXPECTF-- +Class [ <user> abstract class foo ] { + @@ %s 3-4 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +Trait [ <user> trait bar ] { + @@ %s 6-8 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/traits003.phpt b/ext/reflection/tests/traits003.phpt new file mode 100644 index 0000000..c569a8e --- /dev/null +++ b/ext/reflection/tests/traits003.phpt @@ -0,0 +1,30 @@ +--TEST-- +Reflection and Traits +--FILE-- +<?php + +abstract class foo { +} + +trait bar { + +} + +final class baz { + +} + +$x = new ReflectionClass('foo'); +var_dump($x->isTrait()); + +$x = new ReflectionClass('bar'); +var_dump($x->isTrait()); + +$x = new ReflectionClass('baz'); +var_dump($x->isTrait()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(false) diff --git a/ext/reflection/tests/traits004.phpt b/ext/reflection/tests/traits004.phpt new file mode 100644 index 0000000..c9367c1 --- /dev/null +++ b/ext/reflection/tests/traits004.phpt @@ -0,0 +1,58 @@ +--TEST-- +ReflectionClass::getTraits() and ReflectionClass::getTraitNames +--FILE-- +<?php +trait T1 { } +trait T2 { } + +class C1 { } +class C2 { use T1; } +class C3 { use T1; use T2; } + +for ($c = "C1"; $c <= "C3"; $c++) { + echo "class $c:\n"; + $r = new ReflectionClass($c); + var_dump($r->getTraitNames()); + var_dump($r->getTraits()); + echo "\n"; +} +--EXPECT-- +class C1: +array(0) { +} +array(0) { +} + +class C2: +array(1) { + [0]=> + string(2) "T1" +} +array(1) { + ["T1"]=> + &object(ReflectionClass)#1 (1) { + ["name"]=> + string(2) "T1" + } +} + +class C3: +array(2) { + [0]=> + string(2) "T1" + [1]=> + string(2) "T2" +} +array(2) { + ["T1"]=> + &object(ReflectionClass)#2 (1) { + ["name"]=> + string(2) "T1" + } + ["T2"]=> + &object(ReflectionClass)#3 (1) { + ["name"]=> + string(2) "T2" + } +} + diff --git a/ext/reflection/tests/traits005.phpt b/ext/reflection/tests/traits005.phpt new file mode 100644 index 0000000..4cfa6c0 --- /dev/null +++ b/ext/reflection/tests/traits005.phpt @@ -0,0 +1,41 @@ +--TEST-- +ReflectionClass::getTraitAlias +--FILE-- +<?php +trait T1 { function m1() { } function m2() { } } + +class C1 { } +class C2 { use T1; } +class C3 { use T1 { m1 as a1; } } +class C4 { use T1 { m1 as a1; m2 as a2; } } + +for ($c = "C1"; $c <= "C4"; $c++) { + echo "class $c:\n"; + $r = new ReflectionClass($c); + var_dump($r->getTraitAliases()); + echo "\n"; +} +?> +--EXPECT-- +class C1: +array(0) { +} + +class C2: +array(0) { +} + +class C3: +array(1) { + ["a1"]=> + string(6) "T1::m1" +} + +class C4: +array(2) { + ["a1"]=> + string(6) "T1::m1" + ["a2"]=> + string(6) "T1::m2" +} + |