Annotation of embedaddon/php/ext/reflection/php_reflection.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Authors: Timm Friebe <thekid@thekid.de> |
! 16: | George Schlossnagle <george@omniti.com> |
! 17: | Andrei Zmievski <andrei@gravitonic.com> |
! 18: | Marcus Boerger <helly@php.net> |
! 19: | Johannes Schlueter <johannes@php.net> |
! 20: +----------------------------------------------------------------------+
! 21: */
! 22:
! 23: /* $Id: php_reflection.c 321634 2012-01-01 13:15:04Z felipe $ */
! 24:
! 25: #ifdef HAVE_CONFIG_H
! 26: #include "config.h"
! 27: #endif
! 28:
! 29: #include "php.h"
! 30: #include "php_ini.h"
! 31: #include "php_reflection.h"
! 32: #include "ext/standard/info.h"
! 33:
! 34: #include "zend.h"
! 35: #include "zend_API.h"
! 36: #include "zend_exceptions.h"
! 37: #include "zend_operators.h"
! 38: #include "zend_constants.h"
! 39: #include "zend_ini.h"
! 40: #include "zend_interfaces.h"
! 41: #include "zend_closures.h"
! 42:
! 43: /* Undefine "getParameters" macro defined in "main/php3_compat.h" */
! 44: #ifdef getParameters
! 45: # undef getParameters
! 46: #endif
! 47:
! 48: /* Class entry pointers */
! 49: PHPAPI zend_class_entry *reflector_ptr;
! 50: PHPAPI zend_class_entry *reflection_exception_ptr;
! 51: PHPAPI zend_class_entry *reflection_ptr;
! 52: PHPAPI zend_class_entry *reflection_function_abstract_ptr;
! 53: PHPAPI zend_class_entry *reflection_function_ptr;
! 54: PHPAPI zend_class_entry *reflection_parameter_ptr;
! 55: PHPAPI zend_class_entry *reflection_class_ptr;
! 56: PHPAPI zend_class_entry *reflection_object_ptr;
! 57: PHPAPI zend_class_entry *reflection_method_ptr;
! 58: PHPAPI zend_class_entry *reflection_property_ptr;
! 59: PHPAPI zend_class_entry *reflection_extension_ptr;
! 60:
! 61: #if MBO_0
! 62: ZEND_BEGIN_MODULE_GLOBALS(reflection)
! 63: int dummy;
! 64: ZEND_END_MODULE_GLOBALS(reflection)
! 65:
! 66: #ifdef ZTS
! 67: # define REFLECTION_G(v) \
! 68: TSRMG(reflection_globals_id, zend_reflection_globals*, v)
! 69: extern int reflection_globals_id;
! 70: #else
! 71: # define REFLECTION_G(v) (reflection_globals.v)
! 72: extern zend_reflection_globals reflectionglobals;
! 73: #endif
! 74:
! 75: ZEND_DECLARE_MODULE_GLOBALS(reflection)
! 76: #endif /* MBO_0 */
! 77:
! 78: /* Method macros */
! 79:
! 80: #define METHOD_NOTSTATIC(ce) \
! 81: if (!this_ptr || !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) { \
! 82: php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \
! 83: return; \
! 84: } \
! 85:
! 86: /* Exception throwing macro */
! 87: #define _DO_THROW(msg) \
! 88: zend_throw_exception(reflection_exception_ptr, msg, 0 TSRMLS_CC); \
! 89: return; \
! 90:
! 91: #define RETURN_ON_EXCEPTION \
! 92: if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) { \
! 93: return; \
! 94: }
! 95:
! 96: #define GET_REFLECTION_OBJECT_PTR(target) \
! 97: intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); \
! 98: if (intern == NULL || intern->ptr == NULL) { \
! 99: RETURN_ON_EXCEPTION \
! 100: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \
! 101: } \
! 102: target = intern->ptr; \
! 103:
! 104: /* Class constants */
! 105: #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \
! 106: zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
! 107:
! 108: /* {{{ Smart string functions */
! 109: typedef struct _string {
! 110: char *string;
! 111: int len;
! 112: int alloced;
! 113: } string;
! 114:
! 115: static void string_init(string *str)
! 116: {
! 117: str->string = (char *) emalloc(1024);
! 118: str->len = 1;
! 119: str->alloced = 1024;
! 120: *str->string = '\0';
! 121: }
! 122:
! 123: static string *string_printf(string *str, const char *format, ...)
! 124: {
! 125: int len;
! 126: va_list arg;
! 127: char *s_tmp;
! 128:
! 129: va_start(arg, format);
! 130: len = zend_vspprintf(&s_tmp, 0, format, arg);
! 131: if (len) {
! 132: register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
! 133: if (str->alloced < nlen) {
! 134: str->alloced = nlen;
! 135: str->string = erealloc(str->string, str->alloced);
! 136: }
! 137: memcpy(str->string + str->len - 1, s_tmp, len + 1);
! 138: str->len += len;
! 139: }
! 140: efree(s_tmp);
! 141: va_end(arg);
! 142: return str;
! 143: }
! 144:
! 145: static string *string_write(string *str, char *buf, int len)
! 146: {
! 147: register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
! 148: if (str->alloced < nlen) {
! 149: str->alloced = nlen;
! 150: str->string = erealloc(str->string, str->alloced);
! 151: }
! 152: memcpy(str->string + str->len - 1, buf, len);
! 153: str->len += len;
! 154: str->string[str->len - 1] = '\0';
! 155: return str;
! 156: }
! 157:
! 158: static string *string_append(string *str, string *append)
! 159: {
! 160: if (append->len > 1) {
! 161: string_write(str, append->string, append->len - 1);
! 162: }
! 163: return str;
! 164: }
! 165:
! 166: static void string_free(string *str)
! 167: {
! 168: efree(str->string);
! 169: str->len = 0;
! 170: str->alloced = 0;
! 171: str->string = NULL;
! 172: }
! 173: /* }}} */
! 174:
! 175: /* Struct for properties */
! 176: typedef struct _property_reference {
! 177: zend_class_entry *ce;
! 178: zend_property_info prop;
! 179: } property_reference;
! 180:
! 181: /* Struct for parameters */
! 182: typedef struct _parameter_reference {
! 183: zend_uint offset;
! 184: zend_uint required;
! 185: struct _zend_arg_info *arg_info;
! 186: zend_function *fptr;
! 187: } parameter_reference;
! 188:
! 189: typedef enum {
! 190: REF_TYPE_OTHER, /* Must be 0 */
! 191: REF_TYPE_FUNCTION,
! 192: REF_TYPE_PARAMETER,
! 193: REF_TYPE_PROPERTY,
! 194: REF_TYPE_DYNAMIC_PROPERTY
! 195: } reflection_type_t;
! 196:
! 197: /* Struct for reflection objects */
! 198: typedef struct {
! 199: zend_object zo;
! 200: void *ptr;
! 201: reflection_type_t ref_type;
! 202: zval *obj;
! 203: zend_class_entry *ce;
! 204: unsigned int ignore_visibility:1;
! 205: } reflection_object;
! 206:
! 207: static zend_object_handlers reflection_object_handlers;
! 208:
! 209: static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC)
! 210: {
! 211: zval **value;
! 212:
! 213: if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
! 214: RETURN_FALSE;
! 215: }
! 216:
! 217: MAKE_COPY_ZVAL(value, return_value);
! 218: }
! 219:
! 220: #ifdef ilia_0
! 221: static void _default_lookup_entry(zval *object, char *name, int name_len, zval **return_value TSRMLS_DC) /* {{{ */
! 222: {
! 223: zval **value;
! 224:
! 225: if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
! 226: *return_value = NULL;
! 227: } else {
! 228: *return_value = *value;
! 229: }
! 230: }
! 231: /* }}} */
! 232: #endif
! 233:
! 234: static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC)
! 235: {
! 236: zend_uint num_interfaces = ++class_entry->num_interfaces;
! 237:
! 238: class_entry->interfaces = (zend_class_entry **) realloc(class_entry->interfaces, sizeof(zend_class_entry *) * num_interfaces);
! 239: class_entry->interfaces[num_interfaces - 1] = interface_entry;
! 240: }
! 241:
! 242: static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */
! 243: {
! 244: if (fptr
! 245: && fptr->type == ZEND_INTERNAL_FUNCTION
! 246: && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
! 247: {
! 248: zend_function *copy_fptr;
! 249: copy_fptr = emalloc(sizeof(zend_function));
! 250: memcpy(copy_fptr, fptr, sizeof(zend_function));
! 251: copy_fptr->internal_function.function_name = estrdup(fptr->internal_function.function_name);
! 252: return copy_fptr;
! 253: } else {
! 254: /* no copy needed */
! 255: return fptr;
! 256: }
! 257: }
! 258: /* }}} */
! 259:
! 260: static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */
! 261: {
! 262: if (fptr
! 263: && fptr->type == ZEND_INTERNAL_FUNCTION
! 264: && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
! 265: {
! 266: efree(fptr->internal_function.function_name);
! 267: efree(fptr);
! 268: }
! 269: }
! 270: /* }}} */
! 271:
! 272: static void reflection_free_objects_storage(void *object TSRMLS_DC)
! 273: {
! 274: reflection_object *intern = (reflection_object *) object;
! 275: parameter_reference *reference;
! 276: property_reference *prop_reference;
! 277:
! 278: if (intern->ptr) {
! 279: switch (intern->ref_type) {
! 280: case REF_TYPE_PARAMETER:
! 281: reference = (parameter_reference*)intern->ptr;
! 282: _free_function(reference->fptr TSRMLS_CC);
! 283: efree(intern->ptr);
! 284: break;
! 285: case REF_TYPE_FUNCTION:
! 286: _free_function(intern->ptr TSRMLS_CC);
! 287: break;
! 288: case REF_TYPE_PROPERTY:
! 289: efree(intern->ptr);
! 290: break;
! 291: case REF_TYPE_DYNAMIC_PROPERTY:
! 292: prop_reference = (property_reference*)intern->ptr;
! 293: efree(prop_reference->prop.name);
! 294: efree(intern->ptr);
! 295: break;
! 296: case REF_TYPE_OTHER:
! 297: break;
! 298: }
! 299: }
! 300: intern->ptr = NULL;
! 301: if (intern->obj) {
! 302: zval_ptr_dtor(&intern->obj);
! 303: }
! 304: zend_objects_free_object_storage(object TSRMLS_CC);
! 305: }
! 306:
! 307: static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC)
! 308: {
! 309: zval tmp;
! 310: zend_object_value retval;
! 311: reflection_object *intern;
! 312:
! 313: intern = ecalloc(1, sizeof(reflection_object));
! 314: intern->zo.ce = class_type;
! 315:
! 316: zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
! 317: zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
! 318: retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, NULL TSRMLS_CC);
! 319: retval.handlers = &reflection_object_handlers;
! 320: return retval;
! 321: }
! 322:
! 323: static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
! 324: {
! 325: if (!object) {
! 326: ALLOC_ZVAL(object);
! 327: }
! 328: Z_TYPE_P(object) = IS_OBJECT;
! 329: object_init_ex(object, pce);
! 330: Z_SET_REFCOUNT_P(object, 1);
! 331: Z_SET_ISREF_P(object);
! 332: return object;
! 333: }
! 334:
! 335: static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
! 336: static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char *indent TSRMLS_DC);
! 337: static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
! 338: static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
! 339: static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
! 340:
! 341: /* {{{ _class_string */
! 342: static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC)
! 343: {
! 344: int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
! 345: string sub_indent;
! 346:
! 347: string_init(&sub_indent);
! 348: string_printf(&sub_indent, "%s ", indent);
! 349:
! 350: /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */
! 351: if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
! 352: string_printf(str, "%s%s", indent, ce->doc_comment);
! 353: string_write(str, "\n", 1);
! 354: }
! 355:
! 356: if (obj) {
! 357: string_printf(str, "%sObject of class [ ", indent);
! 358: } else {
! 359: string_printf(str, "%s%s [ ", indent, (ce->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : "Class");
! 360: }
! 361: string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
! 362: if (ce->module) {
! 363: string_printf(str, ":%s", ce->module->name);
! 364: }
! 365: string_printf(str, "> ");
! 366: if (ce->get_iterator != NULL) {
! 367: string_printf(str, "<iterateable> ");
! 368: }
! 369: if (ce->ce_flags & ZEND_ACC_INTERFACE) {
! 370: string_printf(str, "interface ");
! 371: } else {
! 372: if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
! 373: string_printf(str, "abstract ");
! 374: }
! 375: if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
! 376: string_printf(str, "final ");
! 377: }
! 378: string_printf(str, "class ");
! 379: }
! 380: string_printf(str, "%s", ce->name);
! 381: if (ce->parent) {
! 382: string_printf(str, " extends %s", ce->parent->name);
! 383: }
! 384:
! 385: if (ce->num_interfaces) {
! 386: zend_uint i;
! 387:
! 388: if (ce->ce_flags & ZEND_ACC_INTERFACE) {
! 389: string_printf(str, " extends %s", ce->interfaces[0]->name);
! 390: } else {
! 391: string_printf(str, " implements %s", ce->interfaces[0]->name);
! 392: }
! 393: for (i = 1; i < ce->num_interfaces; ++i) {
! 394: string_printf(str, ", %s", ce->interfaces[i]->name);
! 395: }
! 396: }
! 397: string_printf(str, " ] {\n");
! 398:
! 399: /* The information where a class is declared is only available for user classes */
! 400: if (ce->type == ZEND_USER_CLASS) {
! 401: string_printf(str, "%s @@ %s %d-%d\n", indent, ce->filename,
! 402: ce->line_start, ce->line_end);
! 403: }
! 404:
! 405: /* Constants */
! 406: if (&ce->constants_table) {
! 407: zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
! 408: string_printf(str, "\n");
! 409: count = zend_hash_num_elements(&ce->constants_table);
! 410: string_printf(str, "%s - Constants [%d] {\n", indent, count);
! 411: if (count > 0) {
! 412: HashPosition pos;
! 413: zval **value;
! 414: char *key;
! 415: uint key_len;
! 416: ulong num_index;
! 417:
! 418: zend_hash_internal_pointer_reset_ex(&ce->constants_table, &pos);
! 419:
! 420: while (zend_hash_get_current_data_ex(&ce->constants_table, (void **) &value, &pos) == SUCCESS) {
! 421: zend_hash_get_current_key_ex(&ce->constants_table, &key, &key_len, &num_index, 0, &pos);
! 422:
! 423: _const_string(str, key, *value, indent TSRMLS_CC);
! 424: zend_hash_move_forward_ex(&ce->constants_table, &pos);
! 425: }
! 426: }
! 427: string_printf(str, "%s }\n", indent);
! 428: }
! 429:
! 430: /* Static properties */
! 431: if (&ce->properties_info) {
! 432: /* counting static properties */
! 433: count = zend_hash_num_elements(&ce->properties_info);
! 434: if (count > 0) {
! 435: HashPosition pos;
! 436: zend_property_info *prop;
! 437:
! 438: zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
! 439:
! 440: while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
! 441: if(prop->flags & ZEND_ACC_SHADOW) {
! 442: count_shadow_props++;
! 443: } else if (prop->flags & ZEND_ACC_STATIC) {
! 444: count_static_props++;
! 445: }
! 446: zend_hash_move_forward_ex(&ce->properties_info, &pos);
! 447: }
! 448: }
! 449:
! 450: /* static properties */
! 451: string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props);
! 452: if (count_static_props > 0) {
! 453: HashPosition pos;
! 454: zend_property_info *prop;
! 455:
! 456: zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
! 457:
! 458: while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
! 459: if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
! 460: _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
! 461: }
! 462:
! 463: zend_hash_move_forward_ex(&ce->properties_info, &pos);
! 464: }
! 465: }
! 466: string_printf(str, "%s }\n", indent);
! 467: }
! 468:
! 469: /* Static methods */
! 470: if (&ce->function_table) {
! 471: /* counting static methods */
! 472: count = zend_hash_num_elements(&ce->function_table);
! 473: if (count > 0) {
! 474: HashPosition pos;
! 475: zend_function *mptr;
! 476:
! 477: zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
! 478:
! 479: while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
! 480: if (mptr->common.fn_flags & ZEND_ACC_STATIC
! 481: && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
! 482: {
! 483: count_static_funcs++;
! 484: }
! 485: zend_hash_move_forward_ex(&ce->function_table, &pos);
! 486: }
! 487: }
! 488:
! 489: /* static methods */
! 490: string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs);
! 491: if (count_static_funcs > 0) {
! 492: HashPosition pos;
! 493: zend_function *mptr;
! 494:
! 495: zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
! 496:
! 497: while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
! 498: if (mptr->common.fn_flags & ZEND_ACC_STATIC
! 499: && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
! 500: {
! 501: string_printf(str, "\n");
! 502: _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
! 503: }
! 504: zend_hash_move_forward_ex(&ce->function_table, &pos);
! 505: }
! 506: } else {
! 507: string_printf(str, "\n");
! 508: }
! 509: string_printf(str, "%s }\n", indent);
! 510: }
! 511:
! 512: /* Default/Implicit properties */
! 513: if (&ce->properties_info) {
! 514: count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
! 515: string_printf(str, "\n%s - Properties [%d] {\n", indent, count);
! 516: if (count > 0) {
! 517: HashPosition pos;
! 518: zend_property_info *prop;
! 519:
! 520: zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
! 521:
! 522: while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
! 523: if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
! 524: _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
! 525: }
! 526: zend_hash_move_forward_ex(&ce->properties_info, &pos);
! 527: }
! 528: }
! 529: string_printf(str, "%s }\n", indent);
! 530: }
! 531:
! 532: if (obj && Z_OBJ_HT_P(obj)->get_properties) {
! 533: string dyn;
! 534: HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
! 535: HashPosition pos;
! 536: zval **prop;
! 537:
! 538: string_init(&dyn);
! 539: count = 0;
! 540:
! 541: if (properties && zend_hash_num_elements(properties)) {
! 542: zend_hash_internal_pointer_reset_ex(properties, &pos);
! 543:
! 544: while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
! 545: char *prop_name;
! 546: uint prop_name_size;
! 547: ulong index;
! 548:
! 549: if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
! 550: if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
! 551: if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
! 552: count++;
! 553: _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);
! 554: }
! 555: }
! 556: efree(prop_name);
! 557: }
! 558: zend_hash_move_forward_ex(properties, &pos);
! 559: }
! 560: }
! 561:
! 562: string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count);
! 563: string_append(str, &dyn);
! 564: string_printf(str, "%s }\n", indent);
! 565: string_free(&dyn);
! 566: }
! 567:
! 568: /* Non static methods */
! 569: if (&ce->function_table) {
! 570: count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
! 571: if (count > 0) {
! 572: HashPosition pos;
! 573: zend_function *mptr;
! 574: string dyn;
! 575:
! 576: count = 0;
! 577: string_init(&dyn);
! 578: zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
! 579:
! 580: while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
! 581: if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0
! 582: && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
! 583: {
! 584: char *key;
! 585: uint key_len;
! 586: ulong num_index;
! 587: uint len = strlen(mptr->common.function_name);
! 588:
! 589: /* Do not display old-style inherited constructors */
! 590: if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0
! 591: || mptr->common.scope == ce
! 592: || zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING
! 593: || zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0)
! 594: {
! 595: zend_function *closure;
! 596: /* see if this is a closure */
! 597: if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 598: && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
! 599: && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
! 600: {
! 601: mptr = closure;
! 602: } else {
! 603: closure = NULL;
! 604: }
! 605: string_printf(&dyn, "\n");
! 606: _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
! 607: count++;
! 608: _free_function(closure TSRMLS_CC);
! 609: }
! 610: }
! 611: zend_hash_move_forward_ex(&ce->function_table, &pos);
! 612: }
! 613: string_printf(str, "\n%s - Methods [%d] {", indent, count);
! 614: if (!count) {
! 615: string_printf(str, "\n");
! 616: }
! 617: string_append(str, &dyn);
! 618: string_free(&dyn);
! 619: } else {
! 620: string_printf(str, "\n%s - Methods [0] {\n", indent);
! 621: }
! 622: string_printf(str, "%s }\n", indent);
! 623: }
! 624:
! 625: string_printf(str, "%s}\n", indent);
! 626: string_free(&sub_indent);
! 627: }
! 628: /* }}} */
! 629:
! 630: /* {{{ _const_string */
! 631: static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC)
! 632: {
! 633: char *type;
! 634: zval value_copy;
! 635: int use_copy;
! 636:
! 637: type = zend_zval_type_name(value);
! 638:
! 639: zend_make_printable_zval(value, &value_copy, &use_copy);
! 640: if (use_copy) {
! 641: value = &value_copy;
! 642: }
! 643:
! 644: string_printf(str, "%s Constant [ %s %s ] { %s }\n",
! 645: indent, type, name, Z_STRVAL_P(value));
! 646:
! 647: if (use_copy) {
! 648: zval_dtor(value);
! 649: }
! 650: }
! 651: /* }}} */
! 652:
! 653: /* {{{ _get_recv_opcode */
! 654: static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset)
! 655: {
! 656: zend_op *op = op_array->opcodes;
! 657: zend_op *end = op + op_array->last;
! 658:
! 659: ++offset;
! 660: while (op < end) {
! 661: if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
! 662: && op->op1.u.constant.value.lval == (long)offset)
! 663: {
! 664: return op;
! 665: }
! 666: ++op;
! 667: }
! 668: return NULL;
! 669: }
! 670: /* }}} */
! 671:
! 672: /* {{{ _parameter_string */
! 673: 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)
! 674: {
! 675: string_printf(str, "Parameter #%d [ ", offset);
! 676: if (offset >= required) {
! 677: string_printf(str, "<optional> ");
! 678: } else {
! 679: string_printf(str, "<required> ");
! 680: }
! 681: if (arg_info->class_name) {
! 682: string_printf(str, "%s ", arg_info->class_name);
! 683: if (arg_info->allow_null) {
! 684: string_printf(str, "or NULL ");
! 685: }
! 686: } else if (arg_info->array_type_hint) {
! 687: string_printf(str, "array ");
! 688: if (arg_info->allow_null) {
! 689: string_printf(str, "or NULL ");
! 690: }
! 691: }
! 692: if (arg_info->pass_by_reference) {
! 693: string_write(str, "&", sizeof("&")-1);
! 694: }
! 695: if (arg_info->name) {
! 696: string_printf(str, "$%s", arg_info->name);
! 697: } else {
! 698: string_printf(str, "$param%d", offset);
! 699: }
! 700: if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
! 701: zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
! 702: if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) {
! 703: zval *zv, zv_copy;
! 704: int use_copy;
! 705: string_write(str, " = ", sizeof(" = ")-1);
! 706: ALLOC_ZVAL(zv);
! 707: *zv = precv->op2.u.constant;
! 708: zval_copy_ctor(zv);
! 709: INIT_PZVAL(zv);
! 710: zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC);
! 711: if (Z_TYPE_P(zv) == IS_BOOL) {
! 712: if (Z_LVAL_P(zv)) {
! 713: string_write(str, "true", sizeof("true")-1);
! 714: } else {
! 715: string_write(str, "false", sizeof("false")-1);
! 716: }
! 717: } else if (Z_TYPE_P(zv) == IS_NULL) {
! 718: string_write(str, "NULL", sizeof("NULL")-1);
! 719: } else if (Z_TYPE_P(zv) == IS_STRING) {
! 720: string_write(str, "'", sizeof("'")-1);
! 721: string_write(str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 15));
! 722: if (Z_STRLEN_P(zv) > 15) {
! 723: string_write(str, "...", sizeof("...")-1);
! 724: }
! 725: string_write(str, "'", sizeof("'")-1);
! 726: } else {
! 727: zend_make_printable_zval(zv, &zv_copy, &use_copy);
! 728: string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
! 729: if (use_copy) {
! 730: zval_dtor(&zv_copy);
! 731: }
! 732: }
! 733: zval_ptr_dtor(&zv);
! 734: }
! 735: }
! 736: string_write(str, " ]", sizeof(" ]")-1);
! 737: }
! 738: /* }}} */
! 739:
! 740: /* {{{ _function_parameter_string */
! 741: static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
! 742: {
! 743: struct _zend_arg_info *arg_info = fptr->common.arg_info;
! 744: zend_uint i, required = fptr->common.required_num_args;
! 745:
! 746: if (!arg_info) {
! 747: return;
! 748: }
! 749:
! 750: string_printf(str, "\n");
! 751: string_printf(str, "%s- Parameters [%d] {\n", indent, fptr->common.num_args);
! 752: for (i = 0; i < fptr->common.num_args; i++) {
! 753: string_printf(str, "%s ", indent);
! 754: _parameter_string(str, fptr, arg_info, i, required, indent TSRMLS_CC);
! 755: string_write(str, "\n", sizeof("\n")-1);
! 756: arg_info++;
! 757: }
! 758: string_printf(str, "%s}\n", indent);
! 759: }
! 760: /* }}} */
! 761:
! 762: /* {{{ _function_closure_string */
! 763: static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
! 764: {
! 765: zend_uint i, count;
! 766: ulong num_index;
! 767: char *key;
! 768: uint key_len;
! 769: HashTable *static_variables;
! 770: HashPosition pos;
! 771:
! 772: if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
! 773: return;
! 774: }
! 775:
! 776: static_variables = fptr->op_array.static_variables;
! 777: count = zend_hash_num_elements(static_variables);
! 778:
! 779: if (!count) {
! 780: return;
! 781: }
! 782:
! 783: string_printf(str, "\n");
! 784: string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
! 785: zend_hash_internal_pointer_reset_ex(static_variables, &pos);
! 786: i = 0;
! 787: while (i < count) {
! 788: zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
! 789: string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, key);
! 790: zend_hash_move_forward_ex(static_variables, &pos);
! 791: }
! 792: string_printf(str, "%s}\n", indent);
! 793: }
! 794: /* }}} */
! 795:
! 796: /* {{{ _function_string */
! 797: static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
! 798: {
! 799: string param_indent;
! 800: zend_function *overwrites;
! 801: char *lc_name;
! 802: unsigned int lc_name_len;
! 803:
! 804: /* TBD: Repair indenting of doc comment (or is this to be done in the parser?)
! 805: * What's "wrong" is that any whitespace before the doc comment start is
! 806: * swallowed, leading to an unaligned comment.
! 807: */
! 808: if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
! 809: string_printf(str, "%s%s\n", indent, fptr->op_array.doc_comment);
! 810: }
! 811:
! 812: string_write(str, indent, strlen(indent));
! 813: string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
! 814: string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
! 815: if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
! 816: string_printf(str, ", deprecated");
! 817: }
! 818: if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
! 819: string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
! 820: }
! 821:
! 822: if (scope && fptr->common.scope) {
! 823: if (fptr->common.scope != scope) {
! 824: string_printf(str, ", inherits %s", fptr->common.scope->name);
! 825: } else if (fptr->common.scope->parent) {
! 826: lc_name_len = strlen(fptr->common.function_name);
! 827: lc_name = zend_str_tolower_dup(fptr->common.function_name, lc_name_len);
! 828: if (zend_hash_find(&fptr->common.scope->parent->function_table, lc_name, lc_name_len + 1, (void**) &overwrites) == SUCCESS) {
! 829: if (fptr->common.scope != overwrites->common.scope) {
! 830: string_printf(str, ", overwrites %s", overwrites->common.scope->name);
! 831: }
! 832: }
! 833: efree(lc_name);
! 834: }
! 835: }
! 836: if (fptr->common.prototype && fptr->common.prototype->common.scope) {
! 837: string_printf(str, ", prototype %s", fptr->common.prototype->common.scope->name);
! 838: }
! 839: if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
! 840: string_printf(str, ", ctor");
! 841: }
! 842: if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
! 843: string_printf(str, ", dtor");
! 844: }
! 845: string_printf(str, "> ");
! 846:
! 847: if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
! 848: string_printf(str, "abstract ");
! 849: }
! 850: if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
! 851: string_printf(str, "final ");
! 852: }
! 853: if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
! 854: string_printf(str, "static ");
! 855: }
! 856:
! 857: if (fptr->common.scope) {
! 858: /* These are mutually exclusive */
! 859: switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
! 860: case ZEND_ACC_PUBLIC:
! 861: string_printf(str, "public ");
! 862: break;
! 863: case ZEND_ACC_PRIVATE:
! 864: string_printf(str, "private ");
! 865: break;
! 866: case ZEND_ACC_PROTECTED:
! 867: string_printf(str, "protected ");
! 868: break;
! 869: default:
! 870: string_printf(str, "<visibility error> ");
! 871: break;
! 872: }
! 873: string_printf(str, "method ");
! 874: } else {
! 875: string_printf(str, "function ");
! 876: }
! 877:
! 878: if (fptr->op_array.return_reference) {
! 879: string_printf(str, "&");
! 880: }
! 881: string_printf(str, "%s ] {\n", fptr->common.function_name);
! 882: /* The information where a function is declared is only available for user classes */
! 883: if (fptr->type == ZEND_USER_FUNCTION) {
! 884: string_printf(str, "%s @@ %s %d - %d\n", indent,
! 885: fptr->op_array.filename,
! 886: fptr->op_array.line_start,
! 887: fptr->op_array.line_end);
! 888: }
! 889: string_init(¶m_indent);
! 890: string_printf(¶m_indent, "%s ", indent);
! 891: if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
! 892: _function_closure_string(str, fptr, param_indent.string TSRMLS_CC);
! 893: }
! 894: _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
! 895: string_free(¶m_indent);
! 896: string_printf(str, "%s}\n", indent);
! 897: }
! 898: /* }}} */
! 899:
! 900: /* {{{ _property_string */
! 901: static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC)
! 902: {
! 903: char *class_name;
! 904:
! 905: string_printf(str, "%sProperty [ ", indent);
! 906: if (!prop) {
! 907: string_printf(str, "<dynamic> public $%s", prop_name);
! 908: } else {
! 909: if (!(prop->flags & ZEND_ACC_STATIC)) {
! 910: if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
! 911: string_write(str, "<implicit> ", sizeof("<implicit> ") - 1);
! 912: } else {
! 913: string_write(str, "<default> ", sizeof("<default> ") - 1);
! 914: }
! 915: }
! 916:
! 917: /* These are mutually exclusive */
! 918: switch (prop->flags & ZEND_ACC_PPP_MASK) {
! 919: case ZEND_ACC_PUBLIC:
! 920: string_printf(str, "public ");
! 921: break;
! 922: case ZEND_ACC_PRIVATE:
! 923: string_printf(str, "private ");
! 924: break;
! 925: case ZEND_ACC_PROTECTED:
! 926: string_printf(str, "protected ");
! 927: break;
! 928: }
! 929: if(prop->flags & ZEND_ACC_STATIC) {
! 930: string_printf(str, "static ");
! 931: }
! 932:
! 933: zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
! 934: string_printf(str, "$%s", prop_name);
! 935: }
! 936:
! 937: string_printf(str, " ]\n");
! 938: }
! 939: /* }}} */
! 940:
! 941: static int _extension_ini_string(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 942: {
! 943: string *str = va_arg(args, string *);
! 944: char *indent = va_arg(args, char *);
! 945: int number = va_arg(args, int);
! 946: char *comma = "";
! 947:
! 948: if (number == ini_entry->module_number) {
! 949: string_printf(str, " %sEntry [ %s <", indent, ini_entry->name);
! 950: if (ini_entry->modifiable == ZEND_INI_ALL) {
! 951: string_printf(str, "ALL");
! 952: } else {
! 953: if (ini_entry->modifiable & ZEND_INI_USER) {
! 954: string_printf(str, "USER");
! 955: comma = ",";
! 956: }
! 957: if (ini_entry->modifiable & ZEND_INI_PERDIR) {
! 958: string_printf(str, "%sPERDIR", comma);
! 959: comma = ",";
! 960: }
! 961: if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
! 962: string_printf(str, "%sSYSTEM", comma);
! 963: }
! 964: }
! 965:
! 966: string_printf(str, "> ]\n");
! 967: string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ini_entry->value : "");
! 968: if (ini_entry->modified) {
! 969: string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ini_entry->orig_value : "");
! 970: }
! 971: string_printf(str, " %s}\n", indent);
! 972: }
! 973: return ZEND_HASH_APPLY_KEEP;
! 974: }
! 975:
! 976: static int _extension_class_string(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 977: {
! 978: string *str = va_arg(args, string *);
! 979: char *indent = va_arg(args, char *);
! 980: struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
! 981: int *num_classes = va_arg(args, int*);
! 982:
! 983: if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
! 984: string_printf(str, "\n");
! 985: _class_string(str, *pce, NULL, indent TSRMLS_CC);
! 986: (*num_classes)++;
! 987: }
! 988: return ZEND_HASH_APPLY_KEEP;
! 989: }
! 990:
! 991: static int _extension_const_string(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 992: {
! 993: string *str = va_arg(args, string *);
! 994: char *indent = va_arg(args, char *);
! 995: struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
! 996: int *num_classes = va_arg(args, int*);
! 997:
! 998: if (constant->module_number == module->module_number) {
! 999: _const_string(str, constant->name, &constant->value, indent TSRMLS_CC);
! 1000: (*num_classes)++;
! 1001: }
! 1002: return ZEND_HASH_APPLY_KEEP;
! 1003: }
! 1004:
! 1005: /* {{{ _extension_string */
! 1006: static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC)
! 1007: {
! 1008: string_printf(str, "%sExtension [ ", indent);
! 1009: if (module->type == MODULE_PERSISTENT) {
! 1010: string_printf(str, "<persistent>");
! 1011: }
! 1012: if (module->type == MODULE_TEMPORARY) {
! 1013: string_printf(str, "<temporary>" );
! 1014: }
! 1015: string_printf(str, " extension #%d %s version %s ] {\n",
! 1016: module->module_number, module->name,
! 1017: (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
! 1018:
! 1019: if (module->deps) {
! 1020: const zend_module_dep* dep = module->deps;
! 1021:
! 1022: string_printf(str, "\n - Dependencies {\n");
! 1023:
! 1024: while(dep->name) {
! 1025: string_printf(str, "%s Dependency [ %s (", indent, dep->name);
! 1026:
! 1027: switch(dep->type) {
! 1028: case MODULE_DEP_REQUIRED:
! 1029: string_write(str, "Required", sizeof("Required") - 1);
! 1030: break;
! 1031: case MODULE_DEP_CONFLICTS:
! 1032: string_write(str, "Conflicts", sizeof("Conflicts") - 1);
! 1033: break;
! 1034: case MODULE_DEP_OPTIONAL:
! 1035: string_write(str, "Optional", sizeof("Optional") - 1);
! 1036: break;
! 1037: default:
! 1038: string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */
! 1039: break;
! 1040: }
! 1041:
! 1042: if (dep->rel) {
! 1043: string_printf(str, " %s", dep->rel);
! 1044: }
! 1045: if (dep->version) {
! 1046: string_printf(str, " %s", dep->version);
! 1047: }
! 1048: string_write(str, ") ]\n", sizeof(") ]\n") - 1);
! 1049: dep++;
! 1050: }
! 1051: string_printf(str, "%s }\n", indent);
! 1052: }
! 1053:
! 1054: {
! 1055: string str_ini;
! 1056: string_init(&str_ini);
! 1057: zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
! 1058: if (str_ini.len > 1) {
! 1059: string_printf(str, "\n - INI {\n");
! 1060: string_append(str, &str_ini);
! 1061: string_printf(str, "%s }\n", indent);
! 1062: }
! 1063: string_free(&str_ini);
! 1064: }
! 1065:
! 1066: {
! 1067: string str_constants;
! 1068: int num_constants = 0;
! 1069:
! 1070: string_init(&str_constants);
! 1071: zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants);
! 1072: if (num_constants) {
! 1073: string_printf(str, "\n - Constants [%d] {\n", num_constants);
! 1074: string_append(str, &str_constants);
! 1075: string_printf(str, "%s }\n", indent);
! 1076: }
! 1077: string_free(&str_constants);
! 1078: }
! 1079:
! 1080: if (module->functions && module->functions->fname) {
! 1081: zend_function *fptr;
! 1082: const zend_function_entry *func = module->functions;
! 1083:
! 1084: string_printf(str, "\n - Functions {\n");
! 1085:
! 1086: /* Is there a better way of doing this? */
! 1087: while (func->fname) {
! 1088: int fname_len = strlen(func->fname);
! 1089: char *lc_name = zend_str_tolower_dup(func->fname, fname_len);
! 1090:
! 1091: if (zend_hash_find(EG(function_table), lc_name, fname_len+1, (void**) &fptr) == FAILURE) {
! 1092: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
! 1093: func++;
! 1094: efree(lc_name);
! 1095: continue;
! 1096: }
! 1097:
! 1098: _function_string(str, fptr, NULL, " " TSRMLS_CC);
! 1099: efree(lc_name);
! 1100: func++;
! 1101: }
! 1102: string_printf(str, "%s }\n", indent);
! 1103: }
! 1104:
! 1105: {
! 1106: string str_classes;
! 1107: string sub_indent;
! 1108: int num_classes = 0;
! 1109:
! 1110: string_init(&sub_indent);
! 1111: string_printf(&sub_indent, "%s ", indent);
! 1112: string_init(&str_classes);
! 1113: 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);
! 1114: if (num_classes) {
! 1115: string_printf(str, "\n - Classes [%d] {", num_classes);
! 1116: string_append(str, &str_classes);
! 1117: string_printf(str, "%s }\n", indent);
! 1118: }
! 1119: string_free(&str_classes);
! 1120: string_free(&sub_indent);
! 1121: }
! 1122:
! 1123: string_printf(str, "%s}\n", indent);
! 1124: }
! 1125: /* }}} */
! 1126:
! 1127: /* {{{ _function_check_flag */
! 1128: static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
! 1129: {
! 1130: reflection_object *intern;
! 1131: zend_function *mptr;
! 1132:
! 1133: if (zend_parse_parameters_none() == FAILURE) {
! 1134: return;
! 1135: }
! 1136: GET_REFLECTION_OBJECT_PTR(mptr);
! 1137: RETURN_BOOL(mptr->common.fn_flags & mask);
! 1138: }
! 1139: /* }}} */
! 1140:
! 1141: /* {{{ zend_reflection_class_factory */
! 1142: PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC)
! 1143: {
! 1144: reflection_object *intern;
! 1145: zval *name;
! 1146:
! 1147: MAKE_STD_ZVAL(name);
! 1148: ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
! 1149: reflection_instantiate(reflection_class_ptr, object TSRMLS_CC);
! 1150: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1151: intern->ptr = ce;
! 1152: intern->ref_type = REF_TYPE_OTHER;
! 1153: intern->ce = ce;
! 1154: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1155: }
! 1156: /* }}} */
! 1157:
! 1158: /* {{{ reflection_extension_factory */
! 1159: static void reflection_extension_factory(zval *object, const char *name_str TSRMLS_DC)
! 1160: {
! 1161: reflection_object *intern;
! 1162: zval *name;
! 1163: int name_len = strlen(name_str);
! 1164: char *lcname;
! 1165: struct _zend_module_entry *module;
! 1166: ALLOCA_FLAG(use_heap)
! 1167:
! 1168: lcname = do_alloca(name_len + 1, use_heap);
! 1169: zend_str_tolower_copy(lcname, name_str, name_len);
! 1170: if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
! 1171: free_alloca(lcname, use_heap);
! 1172: return;
! 1173: }
! 1174: free_alloca(lcname, use_heap);
! 1175:
! 1176: reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC);
! 1177: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1178: MAKE_STD_ZVAL(name);
! 1179: ZVAL_STRINGL(name, module->name, name_len, 1);
! 1180: intern->ptr = module;
! 1181: intern->ref_type = REF_TYPE_OTHER;
! 1182: intern->ce = NULL;
! 1183: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1184: }
! 1185: /* }}} */
! 1186:
! 1187: /* {{{ reflection_parameter_factory */
! 1188: 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)
! 1189: {
! 1190: reflection_object *intern;
! 1191: parameter_reference *reference;
! 1192: zval *name;
! 1193:
! 1194: if (closure_object) {
! 1195: Z_ADDREF_P(closure_object);
! 1196: }
! 1197: MAKE_STD_ZVAL(name);
! 1198: if (arg_info->name) {
! 1199: ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
! 1200: } else {
! 1201: ZVAL_NULL(name);
! 1202: }
! 1203: reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC);
! 1204: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1205: reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
! 1206: reference->arg_info = arg_info;
! 1207: reference->offset = offset;
! 1208: reference->required = required;
! 1209: reference->fptr = fptr;
! 1210: intern->ptr = reference;
! 1211: intern->ref_type = REF_TYPE_PARAMETER;
! 1212: intern->ce = fptr->common.scope;
! 1213: intern->obj = closure_object;
! 1214: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1215: }
! 1216: /* }}} */
! 1217:
! 1218: /* {{{ reflection_function_factory */
! 1219: static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC)
! 1220: {
! 1221: reflection_object *intern;
! 1222: zval *name;
! 1223:
! 1224: if (closure_object) {
! 1225: Z_ADDREF_P(closure_object);
! 1226: }
! 1227: MAKE_STD_ZVAL(name);
! 1228: ZVAL_STRING(name, function->common.function_name, 1);
! 1229:
! 1230: reflection_instantiate(reflection_function_ptr, object TSRMLS_CC);
! 1231: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1232: intern->ptr = function;
! 1233: intern->ref_type = REF_TYPE_FUNCTION;
! 1234: intern->ce = NULL;
! 1235: intern->obj = closure_object;
! 1236: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1237: }
! 1238: /* }}} */
! 1239:
! 1240: /* {{{ reflection_method_factory */
! 1241: static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC)
! 1242: {
! 1243: reflection_object *intern;
! 1244: zval *name;
! 1245: zval *classname;
! 1246:
! 1247: if (closure_object) {
! 1248: Z_ADDREF_P(closure_object);
! 1249: }
! 1250: MAKE_STD_ZVAL(name);
! 1251: MAKE_STD_ZVAL(classname);
! 1252: ZVAL_STRING(name, method->common.function_name, 1);
! 1253: ZVAL_STRINGL(classname, method->common.scope->name, method->common.scope->name_length, 1);
! 1254: reflection_instantiate(reflection_method_ptr, object TSRMLS_CC);
! 1255: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1256: intern->ptr = method;
! 1257: intern->ref_type = REF_TYPE_FUNCTION;
! 1258: intern->ce = ce;
! 1259: intern->obj = closure_object;
! 1260: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1261: zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
! 1262: }
! 1263: /* }}} */
! 1264:
! 1265: /* {{{ reflection_property_factory */
! 1266: static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object TSRMLS_DC)
! 1267: {
! 1268: reflection_object *intern;
! 1269: zval *name;
! 1270: zval *classname;
! 1271: property_reference *reference;
! 1272: char *class_name, *prop_name;
! 1273:
! 1274: zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
! 1275:
! 1276: if (!(prop->flags & ZEND_ACC_PRIVATE)) {
! 1277: /* we have to search the class hierarchy for this (implicit) public or protected property */
! 1278: zend_class_entry *tmp_ce = ce, *store_ce = ce;
! 1279: zend_property_info *tmp_info = NULL;
! 1280:
! 1281: while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) {
! 1282: ce = tmp_ce;
! 1283: tmp_ce = tmp_ce->parent;
! 1284: }
! 1285:
! 1286: if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
! 1287: prop = tmp_info;
! 1288: } else { /* not found, use initial value */
! 1289: ce = store_ce;
! 1290: }
! 1291: }
! 1292:
! 1293: MAKE_STD_ZVAL(name);
! 1294: MAKE_STD_ZVAL(classname);
! 1295: ZVAL_STRING(name, prop_name, 1);
! 1296: ZVAL_STRINGL(classname, prop->ce->name, prop->ce->name_length, 1);
! 1297:
! 1298: reflection_instantiate(reflection_property_ptr, object TSRMLS_CC);
! 1299: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1300: reference = (property_reference*) emalloc(sizeof(property_reference));
! 1301: reference->ce = ce;
! 1302: reference->prop = *prop;
! 1303: intern->ptr = reference;
! 1304: intern->ref_type = REF_TYPE_PROPERTY;
! 1305: intern->ce = ce;
! 1306: intern->ignore_visibility = 0;
! 1307: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1308: zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
! 1309: }
! 1310: /* }}} */
! 1311:
! 1312: /* {{{ _reflection_export */
! 1313: static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
! 1314: {
! 1315: zval *reflector_ptr;
! 1316: zval output, *output_ptr = &output;
! 1317: zval *argument_ptr, *argument2_ptr;
! 1318: zval *retval_ptr, **params[2];
! 1319: int result;
! 1320: int return_output = 0;
! 1321: zend_fcall_info fci;
! 1322: zend_fcall_info_cache fcc;
! 1323: zval fname;
! 1324:
! 1325: if (ctor_argc == 1) {
! 1326: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &argument_ptr, &return_output) == FAILURE) {
! 1327: return;
! 1328: }
! 1329: } else {
! 1330: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
! 1331: return;
! 1332: }
! 1333: }
! 1334:
! 1335: INIT_PZVAL(&output);
! 1336:
! 1337: /* Create object */
! 1338: MAKE_STD_ZVAL(reflector_ptr);
! 1339: if (object_and_properties_init(reflector_ptr, ce_ptr, NULL) == FAILURE) {
! 1340: _DO_THROW("Could not create reflector");
! 1341: }
! 1342:
! 1343: /* Call __construct() */
! 1344: params[0] = &argument_ptr;
! 1345: params[1] = &argument2_ptr;
! 1346:
! 1347: fci.size = sizeof(fci);
! 1348: fci.function_table = NULL;
! 1349: fci.function_name = NULL;
! 1350: fci.symbol_table = NULL;
! 1351: fci.object_ptr = reflector_ptr;
! 1352: fci.retval_ptr_ptr = &retval_ptr;
! 1353: fci.param_count = ctor_argc;
! 1354: fci.params = params;
! 1355: fci.no_separation = 1;
! 1356:
! 1357: fcc.initialized = 1;
! 1358: fcc.function_handler = ce_ptr->constructor;
! 1359: fcc.calling_scope = ce_ptr;
! 1360: fcc.called_scope = Z_OBJCE_P(reflector_ptr);
! 1361: fcc.object_ptr = reflector_ptr;
! 1362:
! 1363: result = zend_call_function(&fci, &fcc TSRMLS_CC);
! 1364:
! 1365: if (retval_ptr) {
! 1366: zval_ptr_dtor(&retval_ptr);
! 1367: }
! 1368:
! 1369: if (EG(exception)) {
! 1370: zval_ptr_dtor(&reflector_ptr);
! 1371: return;
! 1372: }
! 1373: if (result == FAILURE) {
! 1374: zval_ptr_dtor(&reflector_ptr);
! 1375: _DO_THROW("Could not create reflector");
! 1376: }
! 1377:
! 1378: /* Call static reflection::export */
! 1379: ZVAL_BOOL(&output, return_output);
! 1380: params[0] = &reflector_ptr;
! 1381: params[1] = &output_ptr;
! 1382:
! 1383: ZVAL_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 0);
! 1384: fci.function_table = &reflection_ptr->function_table;
! 1385: fci.function_name = &fname;
! 1386: fci.object_ptr = NULL;
! 1387: fci.retval_ptr_ptr = &retval_ptr;
! 1388: fci.param_count = 2;
! 1389: fci.params = params;
! 1390: fci.no_separation = 1;
! 1391:
! 1392: result = zend_call_function(&fci, NULL TSRMLS_CC);
! 1393:
! 1394: if (result == FAILURE && EG(exception) == NULL) {
! 1395: zval_ptr_dtor(&reflector_ptr);
! 1396: zval_ptr_dtor(&retval_ptr);
! 1397: _DO_THROW("Could not execute reflection::export()");
! 1398: }
! 1399:
! 1400: if (return_output) {
! 1401: COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
! 1402: } else {
! 1403: zval_ptr_dtor(&retval_ptr);
! 1404: }
! 1405:
! 1406: /* Destruct reflector which is no longer needed */
! 1407: zval_ptr_dtor(&reflector_ptr);
! 1408: }
! 1409: /* }}} */
! 1410:
! 1411: /* {{{ Preventing __clone from being called */
! 1412: ZEND_METHOD(reflection, __clone)
! 1413: {
! 1414: /* Should never be executable */
! 1415: _DO_THROW("Cannot clone object using __clone()");
! 1416: }
! 1417: /* }}} */
! 1418:
! 1419: /* {{{ proto public static mixed Reflection::export(Reflector r [, bool return])
! 1420: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 1421: ZEND_METHOD(reflection, export)
! 1422: {
! 1423: zval *object, fname, *retval_ptr;
! 1424: int result;
! 1425: zend_bool return_output = 0;
! 1426:
! 1427: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &object, reflector_ptr, &return_output) == FAILURE) {
! 1428: return;
! 1429: }
! 1430:
! 1431: /* Invoke the __toString() method */
! 1432: ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1);
! 1433: result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC);
! 1434: zval_dtor(&fname);
! 1435:
! 1436: if (result == FAILURE) {
! 1437: _DO_THROW("Invocation of method __toString() failed");
! 1438: /* Returns from this function */
! 1439: }
! 1440:
! 1441: if (!retval_ptr) {
! 1442: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
! 1443: RETURN_FALSE;
! 1444: }
! 1445:
! 1446: if (return_output) {
! 1447: COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
! 1448: } else {
! 1449: /* No need for _r variant, return of __toString should always be a string */
! 1450: zend_print_zval(retval_ptr, 0);
! 1451: zend_printf("\n");
! 1452: zval_ptr_dtor(&retval_ptr);
! 1453: }
! 1454: }
! 1455: /* }}} */
! 1456:
! 1457: /* {{{ proto public static array Reflection::getModifierNames(int modifiers)
! 1458: Returns an array of modifier names */
! 1459: ZEND_METHOD(reflection, getModifierNames)
! 1460: {
! 1461: long modifiers;
! 1462:
! 1463: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &modifiers) == FAILURE) {
! 1464: return;
! 1465: }
! 1466:
! 1467: array_init(return_value);
! 1468:
! 1469: if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
! 1470: add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1, 1);
! 1471: }
! 1472: if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) {
! 1473: add_next_index_stringl(return_value, "final", sizeof("final")-1, 1);
! 1474: }
! 1475: if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) {
! 1476: add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
! 1477: }
! 1478:
! 1479: /* These are mutually exclusive */
! 1480: switch (modifiers & ZEND_ACC_PPP_MASK) {
! 1481: case ZEND_ACC_PUBLIC:
! 1482: add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
! 1483: break;
! 1484: case ZEND_ACC_PRIVATE:
! 1485: add_next_index_stringl(return_value, "private", sizeof("private")-1, 1);
! 1486: break;
! 1487: case ZEND_ACC_PROTECTED:
! 1488: add_next_index_stringl(return_value, "protected", sizeof("protected")-1, 1);
! 1489: break;
! 1490: }
! 1491:
! 1492: if (modifiers & ZEND_ACC_STATIC) {
! 1493: add_next_index_stringl(return_value, "static", sizeof("static")-1, 1);
! 1494: }
! 1495: }
! 1496: /* }}} */
! 1497:
! 1498: /* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return])
! 1499: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 1500: ZEND_METHOD(reflection_function, export)
! 1501: {
! 1502: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
! 1503: }
! 1504: /* }}} */
! 1505:
! 1506: /* {{{ proto public void ReflectionFunction::__construct(string name)
! 1507: Constructor. Throws an Exception in case the given function does not exist */
! 1508: ZEND_METHOD(reflection_function, __construct)
! 1509: {
! 1510: zval *name;
! 1511: zval *object;
! 1512: zval *closure = NULL;
! 1513: char *lcname;
! 1514: reflection_object *intern;
! 1515: zend_function *fptr;
! 1516: char *name_str;
! 1517: int name_len;
! 1518:
! 1519: object = getThis();
! 1520: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 1521: if (intern == NULL) {
! 1522: return;
! 1523: }
! 1524:
! 1525: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "O", &closure, zend_ce_closure) == SUCCESS) {
! 1526: fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC);
! 1527: Z_ADDREF_P(closure);
! 1528: } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) {
! 1529: char *nsname;
! 1530:
! 1531: lcname = zend_str_tolower_dup(name_str, name_len);
! 1532:
! 1533: /* Ignore leading "\" */
! 1534: nsname = lcname;
! 1535: if (lcname[0] == '\\') {
! 1536: nsname = &lcname[1];
! 1537: name_len--;
! 1538: }
! 1539:
! 1540: if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) {
! 1541: efree(lcname);
! 1542: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 1543: "Function %s() does not exist", name_str);
! 1544: return;
! 1545: }
! 1546: efree(lcname);
! 1547: } else {
! 1548: return;
! 1549: }
! 1550:
! 1551: MAKE_STD_ZVAL(name);
! 1552: ZVAL_STRING(name, fptr->common.function_name, 1);
! 1553: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 1554: intern->ptr = fptr;
! 1555: intern->ref_type = REF_TYPE_FUNCTION;
! 1556: intern->obj = closure;
! 1557: intern->ce = NULL;
! 1558: }
! 1559: /* }}} */
! 1560:
! 1561: /* {{{ proto public string ReflectionFunction::__toString()
! 1562: Returns a string representation */
! 1563: ZEND_METHOD(reflection_function, __toString)
! 1564: {
! 1565: reflection_object *intern;
! 1566: zend_function *fptr;
! 1567: string str;
! 1568:
! 1569: if (zend_parse_parameters_none() == FAILURE) {
! 1570: return;
! 1571: }
! 1572: GET_REFLECTION_OBJECT_PTR(fptr);
! 1573: string_init(&str);
! 1574: _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
! 1575: RETURN_STRINGL(str.string, str.len - 1, 0);
! 1576: }
! 1577: /* }}} */
! 1578:
! 1579: /* {{{ proto public string ReflectionFunction::getName()
! 1580: Returns this function's name */
! 1581: ZEND_METHOD(reflection_function, getName)
! 1582: {
! 1583: if (zend_parse_parameters_none() == FAILURE) {
! 1584: return;
! 1585: }
! 1586: _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
! 1587: }
! 1588: /* }}} */
! 1589:
! 1590: /* {{{ proto public bool ReflectionFunction::isClosure()
! 1591: Returns whether this is a closure */
! 1592: ZEND_METHOD(reflection_function, isClosure)
! 1593: {
! 1594: reflection_object *intern;
! 1595: zend_function *fptr;
! 1596:
! 1597: if (zend_parse_parameters_none() == FAILURE) {
! 1598: return;
! 1599: }
! 1600: GET_REFLECTION_OBJECT_PTR(fptr);
! 1601: RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
! 1602: }
! 1603: /* }}} */
! 1604:
! 1605: /* {{{ proto public bool ReflectionFunction::isInternal()
! 1606: Returns whether this is an internal function */
! 1607: ZEND_METHOD(reflection_function, isInternal)
! 1608: {
! 1609: reflection_object *intern;
! 1610: zend_function *fptr;
! 1611:
! 1612: if (zend_parse_parameters_none() == FAILURE) {
! 1613: return;
! 1614: }
! 1615: GET_REFLECTION_OBJECT_PTR(fptr);
! 1616: RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION);
! 1617: }
! 1618: /* }}} */
! 1619:
! 1620: /* {{{ proto public bool ReflectionFunction::isUserDefined()
! 1621: Returns whether this is an user-defined function */
! 1622: ZEND_METHOD(reflection_function, isUserDefined)
! 1623: {
! 1624: reflection_object *intern;
! 1625: zend_function *fptr;
! 1626:
! 1627: if (zend_parse_parameters_none() == FAILURE) {
! 1628: return;
! 1629: }
! 1630: GET_REFLECTION_OBJECT_PTR(fptr);
! 1631: RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION);
! 1632: }
! 1633: /* }}} */
! 1634:
! 1635: /* {{{ proto public bool ReflectionFunction::isDisabled()
! 1636: Returns whether this function has been disabled or not */
! 1637: ZEND_METHOD(reflection_function, isDisabled)
! 1638: {
! 1639: reflection_object *intern;
! 1640: zend_function *fptr;
! 1641:
! 1642: METHOD_NOTSTATIC(reflection_function_ptr);
! 1643: GET_REFLECTION_OBJECT_PTR(fptr);
! 1644: RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
! 1645: }
! 1646: /* }}} */
! 1647:
! 1648: /* {{{ proto public string ReflectionFunction::getFileName()
! 1649: Returns the filename of the file this function was declared in */
! 1650: ZEND_METHOD(reflection_function, getFileName)
! 1651: {
! 1652: reflection_object *intern;
! 1653: zend_function *fptr;
! 1654:
! 1655: if (zend_parse_parameters_none() == FAILURE) {
! 1656: return;
! 1657: }
! 1658: GET_REFLECTION_OBJECT_PTR(fptr);
! 1659: if (fptr->type == ZEND_USER_FUNCTION) {
! 1660: RETURN_STRING(fptr->op_array.filename, 1);
! 1661: }
! 1662: RETURN_FALSE;
! 1663: }
! 1664: /* }}} */
! 1665:
! 1666: /* {{{ proto public int ReflectionFunction::getStartLine()
! 1667: Returns the line this function's declaration starts at */
! 1668: ZEND_METHOD(reflection_function, getStartLine)
! 1669: {
! 1670: reflection_object *intern;
! 1671: zend_function *fptr;
! 1672:
! 1673: if (zend_parse_parameters_none() == FAILURE) {
! 1674: return;
! 1675: }
! 1676: GET_REFLECTION_OBJECT_PTR(fptr);
! 1677: if (fptr->type == ZEND_USER_FUNCTION) {
! 1678: RETURN_LONG(fptr->op_array.line_start);
! 1679: }
! 1680: RETURN_FALSE;
! 1681: }
! 1682: /* }}} */
! 1683:
! 1684: /* {{{ proto public int ReflectionFunction::getEndLine()
! 1685: Returns the line this function's declaration ends at */
! 1686: ZEND_METHOD(reflection_function, getEndLine)
! 1687: {
! 1688: reflection_object *intern;
! 1689: zend_function *fptr;
! 1690:
! 1691: if (zend_parse_parameters_none() == FAILURE) {
! 1692: return;
! 1693: }
! 1694: GET_REFLECTION_OBJECT_PTR(fptr);
! 1695: if (fptr->type == ZEND_USER_FUNCTION) {
! 1696: RETURN_LONG(fptr->op_array.line_end);
! 1697: }
! 1698: RETURN_FALSE;
! 1699: }
! 1700: /* }}} */
! 1701:
! 1702: /* {{{ proto public string ReflectionFunction::getDocComment()
! 1703: Returns the doc comment for this function */
! 1704: ZEND_METHOD(reflection_function, getDocComment)
! 1705: {
! 1706: reflection_object *intern;
! 1707: zend_function *fptr;
! 1708:
! 1709: if (zend_parse_parameters_none() == FAILURE) {
! 1710: return;
! 1711: }
! 1712: GET_REFLECTION_OBJECT_PTR(fptr);
! 1713: if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
! 1714: RETURN_STRINGL(fptr->op_array.doc_comment, fptr->op_array.doc_comment_len, 1);
! 1715: }
! 1716: RETURN_FALSE;
! 1717: }
! 1718: /* }}} */
! 1719:
! 1720: /* {{{ proto public array ReflectionFunction::getStaticVariables()
! 1721: Returns an associative array containing this function's static variables and their values */
! 1722: ZEND_METHOD(reflection_function, getStaticVariables)
! 1723: {
! 1724: zval *tmp_copy;
! 1725: reflection_object *intern;
! 1726: zend_function *fptr;
! 1727:
! 1728: if (zend_parse_parameters_none() == FAILURE) {
! 1729: return;
! 1730: }
! 1731: GET_REFLECTION_OBJECT_PTR(fptr);
! 1732:
! 1733: /* Return an empty array in case no static variables exist */
! 1734: array_init(return_value);
! 1735: if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
! 1736: zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
! 1737: 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 *));
! 1738: }
! 1739: }
! 1740: /* }}} */
! 1741:
! 1742: /* {{{ proto public mixed ReflectionFunction::invoke([mixed* args])
! 1743: Invokes the function */
! 1744: ZEND_METHOD(reflection_function, invoke)
! 1745: {
! 1746: zval *retval_ptr;
! 1747: zval ***params = NULL;
! 1748: int result, num_args = 0;
! 1749: zend_fcall_info fci;
! 1750: zend_fcall_info_cache fcc;
! 1751: reflection_object *intern;
! 1752: zend_function *fptr;
! 1753:
! 1754: METHOD_NOTSTATIC(reflection_function_ptr);
! 1755: GET_REFLECTION_OBJECT_PTR(fptr);
! 1756:
! 1757: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", ¶ms, &num_args) == FAILURE) {
! 1758: return;
! 1759: }
! 1760:
! 1761: fci.size = sizeof(fci);
! 1762: fci.function_table = NULL;
! 1763: fci.function_name = NULL;
! 1764: fci.symbol_table = NULL;
! 1765: fci.object_ptr = NULL;
! 1766: fci.retval_ptr_ptr = &retval_ptr;
! 1767: fci.param_count = num_args;
! 1768: fci.params = params;
! 1769: fci.no_separation = 1;
! 1770:
! 1771: fcc.initialized = 1;
! 1772: fcc.function_handler = fptr;
! 1773: fcc.calling_scope = EG(scope);
! 1774: fcc.called_scope = NULL;
! 1775: fcc.object_ptr = NULL;
! 1776:
! 1777: result = zend_call_function(&fci, &fcc TSRMLS_CC);
! 1778:
! 1779: if (num_args) {
! 1780: efree(params);
! 1781: }
! 1782:
! 1783: if (result == FAILURE) {
! 1784: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 1785: "Invocation of function %s() failed", fptr->common.function_name);
! 1786: return;
! 1787: }
! 1788:
! 1789: if (retval_ptr) {
! 1790: COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
! 1791: }
! 1792: }
! 1793: /* }}} */
! 1794:
! 1795: static int _zval_array_to_c_array(zval **arg, zval ****params TSRMLS_DC) /* {{{ */
! 1796: {
! 1797: *(*params)++ = arg;
! 1798: return ZEND_HASH_APPLY_KEEP;
! 1799: } /* }}} */
! 1800:
! 1801: /* {{{ proto public mixed ReflectionFunction::invokeArgs(array args)
! 1802: Invokes the function and pass its arguments as array. */
! 1803: ZEND_METHOD(reflection_function, invokeArgs)
! 1804: {
! 1805: zval *retval_ptr;
! 1806: zval ***params;
! 1807: int result;
! 1808: int argc;
! 1809: zend_fcall_info fci;
! 1810: zend_fcall_info_cache fcc;
! 1811: reflection_object *intern;
! 1812: zend_function *fptr;
! 1813: zval *param_array;
! 1814:
! 1815: METHOD_NOTSTATIC(reflection_function_ptr);
! 1816: GET_REFLECTION_OBJECT_PTR(fptr);
! 1817:
! 1818: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", ¶m_array) == FAILURE) {
! 1819: return;
! 1820: }
! 1821:
! 1822: argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
! 1823:
! 1824: params = safe_emalloc(sizeof(zval **), argc, 0);
! 1825: zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC);
! 1826: params -= argc;
! 1827:
! 1828: fci.size = sizeof(fci);
! 1829: fci.function_table = NULL;
! 1830: fci.function_name = NULL;
! 1831: fci.symbol_table = NULL;
! 1832: fci.object_ptr = NULL;
! 1833: fci.retval_ptr_ptr = &retval_ptr;
! 1834: fci.param_count = argc;
! 1835: fci.params = params;
! 1836: fci.no_separation = 1;
! 1837:
! 1838: fcc.initialized = 1;
! 1839: fcc.function_handler = fptr;
! 1840: fcc.calling_scope = EG(scope);
! 1841: fcc.called_scope = NULL;
! 1842: fcc.object_ptr = NULL;
! 1843:
! 1844: result = zend_call_function(&fci, &fcc TSRMLS_CC);
! 1845:
! 1846: efree(params);
! 1847:
! 1848: if (result == FAILURE) {
! 1849: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 1850: "Invocation of function %s() failed", fptr->common.function_name);
! 1851: return;
! 1852: }
! 1853:
! 1854: if (retval_ptr) {
! 1855: COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
! 1856: }
! 1857: }
! 1858: /* }}} */
! 1859:
! 1860: /* {{{ proto public bool ReflectionFunction::returnsReference()
! 1861: Gets whether this function returns a reference */
! 1862: ZEND_METHOD(reflection_function, returnsReference)
! 1863: {
! 1864: reflection_object *intern;
! 1865: zend_function *fptr;
! 1866:
! 1867: METHOD_NOTSTATIC(reflection_function_abstract_ptr);
! 1868: GET_REFLECTION_OBJECT_PTR(fptr);
! 1869:
! 1870: RETURN_BOOL(fptr->op_array.return_reference);
! 1871: }
! 1872: /* }}} */
! 1873:
! 1874: /* {{{ proto public bool ReflectionFunction::getNumberOfParameters()
! 1875: Gets the number of required parameters */
! 1876: ZEND_METHOD(reflection_function, getNumberOfParameters)
! 1877: {
! 1878: reflection_object *intern;
! 1879: zend_function *fptr;
! 1880:
! 1881: METHOD_NOTSTATIC(reflection_function_abstract_ptr);
! 1882: GET_REFLECTION_OBJECT_PTR(fptr);
! 1883:
! 1884: RETURN_LONG(fptr->common.num_args);
! 1885: }
! 1886: /* }}} */
! 1887:
! 1888: /* {{{ proto public bool ReflectionFunction::getNumberOfRequiredParameters()
! 1889: Gets the number of required parameters */
! 1890: ZEND_METHOD(reflection_function, getNumberOfRequiredParameters)
! 1891: {
! 1892: reflection_object *intern;
! 1893: zend_function *fptr;
! 1894:
! 1895: METHOD_NOTSTATIC(reflection_function_abstract_ptr);
! 1896: GET_REFLECTION_OBJECT_PTR(fptr);
! 1897:
! 1898: RETURN_LONG(fptr->common.required_num_args);
! 1899: }
! 1900: /* }}} */
! 1901:
! 1902: /* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
! 1903: Returns an array of parameter objects for this function */
! 1904: ZEND_METHOD(reflection_function, getParameters)
! 1905: {
! 1906: reflection_object *intern;
! 1907: zend_function *fptr;
! 1908: zend_uint i;
! 1909: struct _zend_arg_info *arg_info;
! 1910:
! 1911: METHOD_NOTSTATIC(reflection_function_abstract_ptr);
! 1912: GET_REFLECTION_OBJECT_PTR(fptr);
! 1913:
! 1914: arg_info= fptr->common.arg_info;
! 1915:
! 1916: array_init(return_value);
! 1917: for (i = 0; i < fptr->common.num_args; i++) {
! 1918: zval *parameter;
! 1919:
! 1920: ALLOC_ZVAL(parameter);
! 1921: reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), intern->obj, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
! 1922: add_next_index_zval(return_value, parameter);
! 1923:
! 1924: arg_info++;
! 1925: }
! 1926: }
! 1927: /* }}} */
! 1928:
! 1929: /* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension()
! 1930: Returns NULL or the extension the function belongs to */
! 1931: ZEND_METHOD(reflection_function, getExtension)
! 1932: {
! 1933: reflection_object *intern;
! 1934: zend_function *fptr;
! 1935: zend_internal_function *internal;
! 1936:
! 1937: METHOD_NOTSTATIC(reflection_function_abstract_ptr);
! 1938: GET_REFLECTION_OBJECT_PTR(fptr);
! 1939:
! 1940: if (fptr->type != ZEND_INTERNAL_FUNCTION) {
! 1941: RETURN_NULL();
! 1942: }
! 1943:
! 1944: internal = (zend_internal_function *)fptr;
! 1945: if (internal->module) {
! 1946: reflection_extension_factory(return_value, internal->module->name TSRMLS_CC);
! 1947: } else {
! 1948: RETURN_NULL();
! 1949: }
! 1950: }
! 1951: /* }}} */
! 1952:
! 1953: /* {{{ proto public string|false ReflectionFunction::getExtensionName()
! 1954: Returns false or the name of the extension the function belongs to */
! 1955: ZEND_METHOD(reflection_function, getExtensionName)
! 1956: {
! 1957: reflection_object *intern;
! 1958: zend_function *fptr;
! 1959: zend_internal_function *internal;
! 1960:
! 1961: METHOD_NOTSTATIC(reflection_function_abstract_ptr);
! 1962: GET_REFLECTION_OBJECT_PTR(fptr);
! 1963:
! 1964: if (fptr->type != ZEND_INTERNAL_FUNCTION) {
! 1965: RETURN_FALSE;
! 1966: }
! 1967:
! 1968: internal = (zend_internal_function *)fptr;
! 1969: if (internal->module) {
! 1970: RETURN_STRING(internal->module->name, 1);
! 1971: } else {
! 1972: RETURN_FALSE;
! 1973: }
! 1974: }
! 1975: /* }}} */
! 1976:
! 1977: /* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
! 1978: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 1979: ZEND_METHOD(reflection_parameter, export)
! 1980: {
! 1981: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2);
! 1982: }
! 1983: /* }}} */
! 1984:
! 1985: /* {{{ proto public void ReflectionParameter::__construct(mixed function, mixed parameter)
! 1986: Constructor. Throws an Exception in case the given method does not exist */
! 1987: ZEND_METHOD(reflection_parameter, __construct)
! 1988: {
! 1989: parameter_reference *ref;
! 1990: zval *reference, **parameter;
! 1991: zval *object;
! 1992: zval *name;
! 1993: reflection_object *intern;
! 1994: zend_function *fptr;
! 1995: struct _zend_arg_info *arg_info;
! 1996: int position;
! 1997: zend_class_entry *ce = NULL;
! 1998: zend_bool is_closure = 0;
! 1999:
! 2000: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, ¶meter) == FAILURE) {
! 2001: return;
! 2002: }
! 2003:
! 2004: object = getThis();
! 2005: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 2006: if (intern == NULL) {
! 2007: return;
! 2008: }
! 2009:
! 2010: /* First, find the function */
! 2011: switch (Z_TYPE_P(reference)) {
! 2012: case IS_STRING: {
! 2013: unsigned int lcname_len;
! 2014: char *lcname;
! 2015:
! 2016: lcname_len = Z_STRLEN_P(reference);
! 2017: lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
! 2018: if (zend_hash_find(EG(function_table), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) {
! 2019: efree(lcname);
! 2020: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2021: "Function %s() does not exist", Z_STRVAL_P(reference));
! 2022: return;
! 2023: }
! 2024: efree(lcname);
! 2025: }
! 2026: ce = fptr->common.scope;
! 2027: break;
! 2028:
! 2029: case IS_ARRAY: {
! 2030: zval **classref;
! 2031: zval **method;
! 2032: zend_class_entry **pce;
! 2033: unsigned int lcname_len;
! 2034: char *lcname;
! 2035:
! 2036: if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE)
! 2037: || (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE))
! 2038: {
! 2039: _DO_THROW("Expected array($object, $method) or array($classname, $method)");
! 2040: /* returns out of this function */
! 2041: }
! 2042:
! 2043: if (Z_TYPE_PP(classref) == IS_OBJECT) {
! 2044: ce = Z_OBJCE_PP(classref);
! 2045: } else {
! 2046: convert_to_string_ex(classref);
! 2047: if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
! 2048: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2049: "Class %s does not exist", Z_STRVAL_PP(classref));
! 2050: return;
! 2051: }
! 2052: ce = *pce;
! 2053: }
! 2054:
! 2055: convert_to_string_ex(method);
! 2056: lcname_len = Z_STRLEN_PP(method);
! 2057: lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), lcname_len);
! 2058: if (ce == zend_ce_closure && Z_TYPE_PP(classref) == IS_OBJECT
! 2059: && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 2060: && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
! 2061: && (fptr = zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL)
! 2062: {
! 2063: /* nothign to do. don't set is_closure since is the invoke handler,
! 2064: not the closure itself */
! 2065: } else if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
! 2066: efree(lcname);
! 2067: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2068: "Method %s::%s() does not exist", ce->name, Z_STRVAL_PP(method));
! 2069: return;
! 2070: }
! 2071: efree(lcname);
! 2072: }
! 2073: break;
! 2074:
! 2075: case IS_OBJECT: {
! 2076: ce = Z_OBJCE_P(reference);
! 2077:
! 2078: if (instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
! 2079: fptr = (zend_function *)zend_get_closure_method_def(reference TSRMLS_CC);
! 2080: Z_ADDREF_P(reference);
! 2081: is_closure = 1;
! 2082: } else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == FAILURE) {
! 2083: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2084: "Method %s::%s() does not exist", ce->name, ZEND_INVOKE_FUNC_NAME);
! 2085: return;
! 2086: }
! 2087: }
! 2088: break;
! 2089:
! 2090: default:
! 2091: _DO_THROW("The parameter class is expected to be either a string, an array(class, method) or a callable object");
! 2092: /* returns out of this function */
! 2093: }
! 2094:
! 2095: /* Now, search for the parameter */
! 2096: arg_info = fptr->common.arg_info;
! 2097: if (Z_TYPE_PP(parameter) == IS_LONG) {
! 2098: position= Z_LVAL_PP(parameter);
! 2099: if (position < 0 || (zend_uint)position >= fptr->common.num_args) {
! 2100: if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
! 2101: if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
! 2102: efree(fptr->common.function_name);
! 2103: }
! 2104: efree(fptr);
! 2105: }
! 2106: if (is_closure) {
! 2107: zval_ptr_dtor(&reference);
! 2108: }
! 2109: _DO_THROW("The parameter specified by its offset could not be found");
! 2110: /* returns out of this function */
! 2111: }
! 2112: } else {
! 2113: zend_uint i;
! 2114:
! 2115: position= -1;
! 2116: convert_to_string_ex(parameter);
! 2117: for (i = 0; i < fptr->common.num_args; i++) {
! 2118: if (arg_info[i].name && strcmp(arg_info[i].name, Z_STRVAL_PP(parameter)) == 0) {
! 2119: position= i;
! 2120: break;
! 2121: }
! 2122: }
! 2123: if (position == -1) {
! 2124: if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
! 2125: if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
! 2126: efree(fptr->common.function_name);
! 2127: }
! 2128: efree(fptr);
! 2129: }
! 2130: if (is_closure) {
! 2131: zval_ptr_dtor(&reference);
! 2132: }
! 2133: _DO_THROW("The parameter specified by its name could not be found");
! 2134: /* returns out of this function */
! 2135: }
! 2136: }
! 2137:
! 2138: MAKE_STD_ZVAL(name);
! 2139: if (arg_info[position].name) {
! 2140: ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
! 2141: } else {
! 2142: ZVAL_NULL(name);
! 2143: }
! 2144: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 2145:
! 2146: ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
! 2147: ref->arg_info = &arg_info[position];
! 2148: ref->offset = (zend_uint)position;
! 2149: ref->required = fptr->common.required_num_args;
! 2150: ref->fptr = fptr;
! 2151: /* TODO: copy fptr */
! 2152: intern->ptr = ref;
! 2153: intern->ref_type = REF_TYPE_PARAMETER;
! 2154: intern->ce = ce;
! 2155: if (reference && is_closure) {
! 2156: intern->obj = reference;
! 2157: }
! 2158: }
! 2159: /* }}} */
! 2160:
! 2161: /* {{{ proto public string ReflectionParameter::__toString()
! 2162: Returns a string representation */
! 2163: ZEND_METHOD(reflection_parameter, __toString)
! 2164: {
! 2165: reflection_object *intern;
! 2166: parameter_reference *param;
! 2167: string str;
! 2168:
! 2169: if (zend_parse_parameters_none() == FAILURE) {
! 2170: return;
! 2171: }
! 2172: GET_REFLECTION_OBJECT_PTR(param);
! 2173: string_init(&str);
! 2174: _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "" TSRMLS_CC);
! 2175: RETURN_STRINGL(str.string, str.len - 1, 0);
! 2176: }
! 2177: /* }}} */
! 2178:
! 2179: /* {{{ proto public string ReflectionParameter::getName()
! 2180: Returns this parameters's name */
! 2181: ZEND_METHOD(reflection_parameter, getName)
! 2182: {
! 2183: if (zend_parse_parameters_none() == FAILURE) {
! 2184: return;
! 2185: }
! 2186: _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
! 2187: }
! 2188: /* }}} */
! 2189:
! 2190: /* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction()
! 2191: Returns the ReflectionFunction for the function of this parameter */
! 2192: ZEND_METHOD(reflection_parameter, getDeclaringFunction)
! 2193: {
! 2194: reflection_object *intern;
! 2195: parameter_reference *param;
! 2196:
! 2197: if (zend_parse_parameters_none() == FAILURE) {
! 2198: return;
! 2199: }
! 2200: GET_REFLECTION_OBJECT_PTR(param);
! 2201:
! 2202: if (!param->fptr->common.scope) {
! 2203: reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
! 2204: } else {
! 2205: reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
! 2206: }
! 2207: }
! 2208: /* }}} */
! 2209:
! 2210: /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass()
! 2211: Returns in which class this parameter is defined (not the typehint of the parameter) */
! 2212: ZEND_METHOD(reflection_parameter, getDeclaringClass)
! 2213: {
! 2214: reflection_object *intern;
! 2215: parameter_reference *param;
! 2216:
! 2217: if (zend_parse_parameters_none() == FAILURE) {
! 2218: return;
! 2219: }
! 2220: GET_REFLECTION_OBJECT_PTR(param);
! 2221:
! 2222: if (param->fptr->common.scope) {
! 2223: zend_reflection_class_factory(param->fptr->common.scope, return_value TSRMLS_CC);
! 2224: }
! 2225: }
! 2226: /* }}} */
! 2227:
! 2228: /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass()
! 2229: Returns this parameters's class hint or NULL if there is none */
! 2230: ZEND_METHOD(reflection_parameter, getClass)
! 2231: {
! 2232: reflection_object *intern;
! 2233: parameter_reference *param;
! 2234: zend_class_entry **pce, *ce;
! 2235:
! 2236: if (zend_parse_parameters_none() == FAILURE) {
! 2237: return;
! 2238: }
! 2239: GET_REFLECTION_OBJECT_PTR(param);
! 2240:
! 2241: if (param->arg_info->class_name) {
! 2242: /* Class name is stored as a string, we might also get "self" or "parent"
! 2243: * - For "self", simply use the function scope. If scope is NULL then
! 2244: * the function is global and thus self does not make any sense
! 2245: *
! 2246: * - For "parent", use the function scope's parent. If scope is NULL then
! 2247: * the function is global and thus parent does not make any sense.
! 2248: * If the parent is NULL then the class does not extend anything and
! 2249: * thus parent does not make any sense, either.
! 2250: *
! 2251: * TODO: Think about moving these checks to the compiler or some sort of
! 2252: * lint-mode.
! 2253: */
! 2254: if (0 == strncmp(param->arg_info->class_name, "self", sizeof("self")- 1)) {
! 2255: ce = param->fptr->common.scope;
! 2256: if (!ce) {
! 2257: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2258: "Parameter uses 'self' as type hint but function is not a class member!");
! 2259: return;
! 2260: }
! 2261: pce= &ce;
! 2262: } else if (0 == strncmp(param->arg_info->class_name, "parent", sizeof("parent")- 1)) {
! 2263: ce = param->fptr->common.scope;
! 2264: if (!ce) {
! 2265: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2266: "Parameter uses 'parent' as type hint but function is not a class member!");
! 2267: return;
! 2268: }
! 2269: if (!ce->parent) {
! 2270: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2271: "Parameter uses 'parent' as type hint although class does not have a parent!");
! 2272: return;
! 2273: }
! 2274: pce= &ce->parent;
! 2275: } else if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) {
! 2276: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2277: "Class %s does not exist", param->arg_info->class_name);
! 2278: return;
! 2279: }
! 2280: zend_reflection_class_factory(*pce, return_value TSRMLS_CC);
! 2281: }
! 2282: }
! 2283: /* }}} */
! 2284:
! 2285: /* {{{ proto public bool ReflectionParameter::isArray()
! 2286: Returns whether parameter MUST be an array */
! 2287: ZEND_METHOD(reflection_parameter, isArray)
! 2288: {
! 2289: reflection_object *intern;
! 2290: parameter_reference *param;
! 2291:
! 2292: if (zend_parse_parameters_none() == FAILURE) {
! 2293: return;
! 2294: }
! 2295: GET_REFLECTION_OBJECT_PTR(param);
! 2296:
! 2297: RETVAL_BOOL(param->arg_info->array_type_hint);
! 2298: }
! 2299: /* }}} */
! 2300:
! 2301: /* {{{ proto public bool ReflectionParameter::allowsNull()
! 2302: Returns whether NULL is allowed as this parameters's value */
! 2303: ZEND_METHOD(reflection_parameter, allowsNull)
! 2304: {
! 2305: reflection_object *intern;
! 2306: parameter_reference *param;
! 2307:
! 2308: if (zend_parse_parameters_none() == FAILURE) {
! 2309: return;
! 2310: }
! 2311: GET_REFLECTION_OBJECT_PTR(param);
! 2312:
! 2313: RETVAL_BOOL(param->arg_info->allow_null);
! 2314: }
! 2315: /* }}} */
! 2316:
! 2317: /* {{{ proto public bool ReflectionParameter::isPassedByReference()
! 2318: Returns whether this parameters is passed to by reference */
! 2319: ZEND_METHOD(reflection_parameter, isPassedByReference)
! 2320: {
! 2321: reflection_object *intern;
! 2322: parameter_reference *param;
! 2323:
! 2324: if (zend_parse_parameters_none() == FAILURE) {
! 2325: return;
! 2326: }
! 2327: GET_REFLECTION_OBJECT_PTR(param);
! 2328:
! 2329: RETVAL_BOOL(param->arg_info->pass_by_reference);
! 2330: }
! 2331: /* }}} */
! 2332:
! 2333: /* {{{ proto public bool ReflectionParameter::getPosition()
! 2334: Returns whether this parameter is an optional parameter */
! 2335: ZEND_METHOD(reflection_parameter, getPosition)
! 2336: {
! 2337: reflection_object *intern;
! 2338: parameter_reference *param;
! 2339:
! 2340: if (zend_parse_parameters_none() == FAILURE) {
! 2341: return;
! 2342: }
! 2343: GET_REFLECTION_OBJECT_PTR(param);
! 2344:
! 2345: RETVAL_LONG(param->offset);
! 2346: }
! 2347: /* }}} */
! 2348:
! 2349: /* {{{ proto public bool ReflectionParameter::isOptional()
! 2350: Returns whether this parameter is an optional parameter */
! 2351: ZEND_METHOD(reflection_parameter, isOptional)
! 2352: {
! 2353: reflection_object *intern;
! 2354: parameter_reference *param;
! 2355:
! 2356: if (zend_parse_parameters_none() == FAILURE) {
! 2357: return;
! 2358: }
! 2359: GET_REFLECTION_OBJECT_PTR(param);
! 2360:
! 2361: RETVAL_BOOL(param->offset >= param->required);
! 2362: }
! 2363: /* }}} */
! 2364:
! 2365: /* {{{ proto public bool ReflectionParameter::isDefaultValueAvailable()
! 2366: Returns whether the default value of this parameter is available */
! 2367: ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
! 2368: {
! 2369: reflection_object *intern;
! 2370: parameter_reference *param;
! 2371: zend_op *precv;
! 2372:
! 2373: if (zend_parse_parameters_none() == FAILURE) {
! 2374: return;
! 2375: }
! 2376: GET_REFLECTION_OBJECT_PTR(param);
! 2377:
! 2378: if (param->fptr->type != ZEND_USER_FUNCTION)
! 2379: {
! 2380: RETURN_FALSE;
! 2381: }
! 2382: if (param->offset < param->required) {
! 2383: RETURN_FALSE;
! 2384: }
! 2385: precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
! 2386: if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
! 2387: RETURN_FALSE;
! 2388: }
! 2389: RETURN_TRUE;
! 2390: }
! 2391: /* }}} */
! 2392:
! 2393: /* {{{ proto public bool ReflectionParameter::getDefaultValue()
! 2394: Returns the default value of this parameter or throws an exception */
! 2395: ZEND_METHOD(reflection_parameter, getDefaultValue)
! 2396: {
! 2397: reflection_object *intern;
! 2398: parameter_reference *param;
! 2399: zend_op *precv;
! 2400:
! 2401: if (zend_parse_parameters_none() == FAILURE) {
! 2402: return;
! 2403: }
! 2404: GET_REFLECTION_OBJECT_PTR(param);
! 2405:
! 2406: if (param->fptr->type != ZEND_USER_FUNCTION)
! 2407: {
! 2408: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions");
! 2409: return;
! 2410: }
! 2411: if (param->offset < param->required) {
! 2412: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional");
! 2413: return;
! 2414: }
! 2415: precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
! 2416: if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
! 2417: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error");
! 2418: return;
! 2419: }
! 2420:
! 2421: *return_value = precv->op2.u.constant;
! 2422: INIT_PZVAL(return_value);
! 2423: if (Z_TYPE_P(return_value) != IS_CONSTANT && Z_TYPE_P(return_value) != IS_CONSTANT_ARRAY) {
! 2424: zval_copy_ctor(return_value);
! 2425: }
! 2426: zval_update_constant_ex(&return_value, (void*)0, param->fptr->common.scope TSRMLS_CC);
! 2427: }
! 2428: /* }}} */
! 2429:
! 2430: /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException
! 2431: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 2432: ZEND_METHOD(reflection_method, export)
! 2433: {
! 2434: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2);
! 2435: }
! 2436: /* }}} */
! 2437:
! 2438: /* {{{ proto public void ReflectionMethod::__construct(mixed class_or_method [, string name])
! 2439: Constructor. Throws an Exception in case the given method does not exist */
! 2440: ZEND_METHOD(reflection_method, __construct)
! 2441: {
! 2442: zval *name, *classname;
! 2443: zval *object, *orig_obj;
! 2444: reflection_object *intern;
! 2445: char *lcname;
! 2446: zend_class_entry **pce;
! 2447: zend_class_entry *ce;
! 2448: zend_function *mptr;
! 2449: char *name_str, *tmp;
! 2450: int name_len, tmp_len;
! 2451: zval ztmp;
! 2452:
! 2453: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
! 2454: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
! 2455: return;
! 2456: }
! 2457: if ((tmp = strstr(name_str, "::")) == NULL) {
! 2458: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Invalid method name %s", name_str);
! 2459: return;
! 2460: }
! 2461: classname = &ztmp;
! 2462: tmp_len = tmp - name_str;
! 2463: ZVAL_STRINGL(classname, name_str, tmp_len, 1);
! 2464: name_len = name_len - (tmp_len + 2);
! 2465: name_str = tmp + 2;
! 2466: orig_obj = NULL;
! 2467: } else if (Z_TYPE_P(classname) == IS_OBJECT) {
! 2468: orig_obj = classname;
! 2469: } else {
! 2470: orig_obj = NULL;
! 2471: }
! 2472:
! 2473: object = getThis();
! 2474: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 2475: if (intern == NULL) {
! 2476: return;
! 2477: }
! 2478:
! 2479: /* Find the class entry */
! 2480: switch (Z_TYPE_P(classname)) {
! 2481: case IS_STRING:
! 2482: if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
! 2483: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2484: "Class %s does not exist", Z_STRVAL_P(classname));
! 2485: if (classname == &ztmp) {
! 2486: zval_dtor(&ztmp);
! 2487: }
! 2488: return;
! 2489: }
! 2490: ce = *pce;
! 2491: break;
! 2492:
! 2493: case IS_OBJECT:
! 2494: ce = Z_OBJCE_P(classname);
! 2495: break;
! 2496:
! 2497: default:
! 2498: if (classname == &ztmp) {
! 2499: zval_dtor(&ztmp);
! 2500: }
! 2501: _DO_THROW("The parameter class is expected to be either a string or an object");
! 2502: /* returns out of this function */
! 2503: }
! 2504:
! 2505: if (classname == &ztmp) {
! 2506: zval_dtor(&ztmp);
! 2507: }
! 2508:
! 2509: lcname = zend_str_tolower_dup(name_str, name_len);
! 2510:
! 2511: if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 2512: && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
! 2513: && (mptr = zend_get_closure_invoke_method(orig_obj TSRMLS_CC)) != NULL)
! 2514: {
! 2515: /* do nothing, mptr already set */
! 2516: } else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
! 2517: efree(lcname);
! 2518: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2519: "Method %s::%s() does not exist", ce->name, name_str);
! 2520: return;
! 2521: }
! 2522: efree(lcname);
! 2523:
! 2524: MAKE_STD_ZVAL(classname);
! 2525: ZVAL_STRINGL(classname, mptr->common.scope->name, mptr->common.scope->name_length, 1);
! 2526:
! 2527: zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
! 2528:
! 2529: MAKE_STD_ZVAL(name);
! 2530: ZVAL_STRING(name, mptr->common.function_name, 1);
! 2531: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 2532: intern->ptr = mptr;
! 2533: intern->ref_type = REF_TYPE_FUNCTION;
! 2534: intern->ce = ce;
! 2535: }
! 2536: /* }}} */
! 2537:
! 2538: /* {{{ proto public string ReflectionMethod::__toString()
! 2539: Returns a string representation */
! 2540: ZEND_METHOD(reflection_method, __toString)
! 2541: {
! 2542: reflection_object *intern;
! 2543: zend_function *mptr;
! 2544: string str;
! 2545:
! 2546: if (zend_parse_parameters_none() == FAILURE) {
! 2547: return;
! 2548: }
! 2549: GET_REFLECTION_OBJECT_PTR(mptr);
! 2550: string_init(&str);
! 2551: _function_string(&str, mptr, intern->ce, "" TSRMLS_CC);
! 2552: RETURN_STRINGL(str.string, str.len - 1, 0);
! 2553: }
! 2554: /* }}} */
! 2555:
! 2556: /* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
! 2557: Invokes the method. */
! 2558: ZEND_METHOD(reflection_method, invoke)
! 2559: {
! 2560: zval *retval_ptr;
! 2561: zval ***params = NULL;
! 2562: zval *object_ptr;
! 2563: reflection_object *intern;
! 2564: zend_function *mptr;
! 2565: int result, num_args = 0;
! 2566: zend_fcall_info fci;
! 2567: zend_fcall_info_cache fcc;
! 2568: zend_class_entry *obj_ce;
! 2569:
! 2570: METHOD_NOTSTATIC(reflection_method_ptr);
! 2571:
! 2572: GET_REFLECTION_OBJECT_PTR(mptr);
! 2573:
! 2574: if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
! 2575: || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
! 2576: && intern->ignore_visibility == 0)
! 2577: {
! 2578: if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
! 2579: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2580: "Trying to invoke abstract method %s::%s()",
! 2581: mptr->common.scope->name, mptr->common.function_name);
! 2582: } else {
! 2583: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2584: "Trying to invoke %s method %s::%s() from scope %s",
! 2585: mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
! 2586: mptr->common.scope->name, mptr->common.function_name,
! 2587: Z_OBJCE_P(getThis())->name);
! 2588: }
! 2589: return;
! 2590: }
! 2591:
! 2592: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", ¶ms, &num_args) == FAILURE) {
! 2593: return;
! 2594: }
! 2595:
! 2596: /* In case this is a static method, we should'nt pass an object_ptr
! 2597: * (which is used as calling context aka $this). We can thus ignore the
! 2598: * first parameter.
! 2599: *
! 2600: * Else, we verify that the given object is an instance of the class.
! 2601: */
! 2602: if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
! 2603: object_ptr = NULL;
! 2604: obj_ce = mptr->common.scope;
! 2605: } else {
! 2606: if (Z_TYPE_PP(params[0]) != IS_OBJECT) {
! 2607: efree(params);
! 2608: _DO_THROW("Non-object passed to Invoke()");
! 2609: /* Returns from this function */
! 2610: }
! 2611:
! 2612: obj_ce = Z_OBJCE_PP(params[0]);
! 2613:
! 2614: if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
! 2615: if (params) {
! 2616: efree(params);
! 2617: }
! 2618: _DO_THROW("Given object is not an instance of the class this method was declared in");
! 2619: /* Returns from this function */
! 2620: }
! 2621:
! 2622: object_ptr = *params[0];
! 2623: }
! 2624:
! 2625: fci.size = sizeof(fci);
! 2626: fci.function_table = NULL;
! 2627: fci.function_name = NULL;
! 2628: fci.symbol_table = NULL;
! 2629: fci.object_ptr = object_ptr;
! 2630: fci.retval_ptr_ptr = &retval_ptr;
! 2631: fci.param_count = num_args - 1;
! 2632: fci.params = params + 1;
! 2633: fci.no_separation = 1;
! 2634:
! 2635: fcc.initialized = 1;
! 2636: fcc.function_handler = mptr;
! 2637: fcc.calling_scope = obj_ce;
! 2638: fcc.called_scope = intern->ce;
! 2639: fcc.object_ptr = object_ptr;
! 2640:
! 2641: result = zend_call_function(&fci, &fcc TSRMLS_CC);
! 2642:
! 2643: if (params) {
! 2644: efree(params);
! 2645: }
! 2646:
! 2647: if (result == FAILURE) {
! 2648: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2649: "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
! 2650: return;
! 2651: }
! 2652:
! 2653: if (retval_ptr) {
! 2654: COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
! 2655: }
! 2656: }
! 2657: /* }}} */
! 2658:
! 2659: /* {{{ proto public mixed ReflectionMethod::invokeArgs(mixed object, array args)
! 2660: Invokes the function and pass its arguments as array. */
! 2661: ZEND_METHOD(reflection_method, invokeArgs)
! 2662: {
! 2663: zval *retval_ptr;
! 2664: zval ***params;
! 2665: zval *object;
! 2666: reflection_object *intern;
! 2667: zend_function *mptr;
! 2668: int argc;
! 2669: int result;
! 2670: zend_fcall_info fci;
! 2671: zend_fcall_info_cache fcc;
! 2672: zend_class_entry *obj_ce;
! 2673: zval *param_array;
! 2674:
! 2675: METHOD_NOTSTATIC(reflection_method_ptr);
! 2676:
! 2677: GET_REFLECTION_OBJECT_PTR(mptr);
! 2678:
! 2679: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a", &object, ¶m_array) == FAILURE) {
! 2680: return;
! 2681: }
! 2682:
! 2683: if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
! 2684: || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
! 2685: && intern->ignore_visibility == 0)
! 2686: {
! 2687: if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
! 2688: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2689: "Trying to invoke abstract method %s::%s()",
! 2690: mptr->common.scope->name, mptr->common.function_name);
! 2691: } else {
! 2692: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2693: "Trying to invoke %s method %s::%s() from scope %s",
! 2694: mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
! 2695: mptr->common.scope->name, mptr->common.function_name,
! 2696: Z_OBJCE_P(getThis())->name);
! 2697: }
! 2698: return;
! 2699: }
! 2700:
! 2701: argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
! 2702:
! 2703: params = safe_emalloc(sizeof(zval **), argc, 0);
! 2704: zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC);
! 2705: params -= argc;
! 2706:
! 2707: /* In case this is a static method, we should'nt pass an object_ptr
! 2708: * (which is used as calling context aka $this). We can thus ignore the
! 2709: * first parameter.
! 2710: *
! 2711: * Else, we verify that the given object is an instance of the class.
! 2712: */
! 2713: if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
! 2714: object = NULL;
! 2715: obj_ce = mptr->common.scope;
! 2716: } else {
! 2717: if (!object) {
! 2718: efree(params);
! 2719: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2720: "Trying to invoke non static method %s::%s() without an object",
! 2721: mptr->common.scope->name, mptr->common.function_name);
! 2722: return;
! 2723: }
! 2724:
! 2725: obj_ce = Z_OBJCE_P(object);
! 2726:
! 2727: if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
! 2728: efree(params);
! 2729: _DO_THROW("Given object is not an instance of the class this method was declared in");
! 2730: /* Returns from this function */
! 2731: }
! 2732: }
! 2733:
! 2734: fci.size = sizeof(fci);
! 2735: fci.function_table = NULL;
! 2736: fci.function_name = NULL;
! 2737: fci.symbol_table = NULL;
! 2738: fci.object_ptr = object;
! 2739: fci.retval_ptr_ptr = &retval_ptr;
! 2740: fci.param_count = argc;
! 2741: fci.params = params;
! 2742: fci.no_separation = 1;
! 2743:
! 2744: fcc.initialized = 1;
! 2745: fcc.function_handler = mptr;
! 2746: fcc.calling_scope = obj_ce;
! 2747: fcc.called_scope = obj_ce;
! 2748: fcc.object_ptr = object;
! 2749:
! 2750: result = zend_call_function(&fci, &fcc TSRMLS_CC);
! 2751:
! 2752: efree(params);
! 2753:
! 2754: if (result == FAILURE) {
! 2755: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2756: "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
! 2757: return;
! 2758: }
! 2759:
! 2760: if (retval_ptr) {
! 2761: COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
! 2762: }
! 2763: }
! 2764: /* }}} */
! 2765:
! 2766: /* {{{ proto public bool ReflectionMethod::isFinal()
! 2767: Returns whether this method is final */
! 2768: ZEND_METHOD(reflection_method, isFinal)
! 2769: {
! 2770: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
! 2771: }
! 2772: /* }}} */
! 2773:
! 2774: /* {{{ proto public bool ReflectionMethod::isAbstract()
! 2775: Returns whether this method is abstract */
! 2776: ZEND_METHOD(reflection_method, isAbstract)
! 2777: {
! 2778: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT);
! 2779: }
! 2780: /* }}} */
! 2781:
! 2782: /* {{{ proto public bool ReflectionMethod::isPublic()
! 2783: Returns whether this method is public */
! 2784: ZEND_METHOD(reflection_method, isPublic)
! 2785: {
! 2786: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
! 2787: }
! 2788: /* }}} */
! 2789:
! 2790: /* {{{ proto public bool ReflectionMethod::isPrivate()
! 2791: Returns whether this method is private */
! 2792: ZEND_METHOD(reflection_method, isPrivate)
! 2793: {
! 2794: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
! 2795: }
! 2796: /* }}} */
! 2797:
! 2798: /* {{{ proto public bool ReflectionMethod::isProtected()
! 2799: Returns whether this method is protected */
! 2800: ZEND_METHOD(reflection_method, isProtected)
! 2801: {
! 2802: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
! 2803: }
! 2804: /* }}} */
! 2805:
! 2806: /* {{{ proto public bool ReflectionMethod::isStatic()
! 2807: Returns whether this method is static */
! 2808: ZEND_METHOD(reflection_method, isStatic)
! 2809: {
! 2810: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
! 2811: }
! 2812: /* }}} */
! 2813:
! 2814: /* {{{ proto public bool ReflectionFunction::isDeprecated()
! 2815: Returns whether this function is deprecated */
! 2816: ZEND_METHOD(reflection_function, isDeprecated)
! 2817: {
! 2818: _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
! 2819: }
! 2820: /* }}} */
! 2821:
! 2822: /* {{{ proto public bool ReflectionFunction::inNamespace()
! 2823: Returns whether this function is defined in namespace */
! 2824: ZEND_METHOD(reflection_function, inNamespace)
! 2825: {
! 2826: zval **name;
! 2827: char *colon;
! 2828:
! 2829: if (zend_parse_parameters_none() == FAILURE) {
! 2830: return;
! 2831: }
! 2832: if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
! 2833: RETURN_FALSE;
! 2834: }
! 2835: if (Z_TYPE_PP(name) == IS_STRING
! 2836: && (colon = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
! 2837: && colon > Z_STRVAL_PP(name))
! 2838: {
! 2839: RETURN_TRUE;
! 2840: }
! 2841: RETURN_FALSE;
! 2842: }
! 2843: /* }}} */
! 2844:
! 2845: /* {{{ proto public string ReflectionFunction::getNamespaceName()
! 2846: Returns the name of namespace where this function is defined */
! 2847: ZEND_METHOD(reflection_function, getNamespaceName)
! 2848: {
! 2849: zval **name;
! 2850: char *backslash;
! 2851:
! 2852: if (zend_parse_parameters_none() == FAILURE) {
! 2853: return;
! 2854: }
! 2855: if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
! 2856: RETURN_FALSE;
! 2857: }
! 2858: if (Z_TYPE_PP(name) == IS_STRING
! 2859: && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
! 2860: && backslash > Z_STRVAL_PP(name))
! 2861: {
! 2862: RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1);
! 2863: }
! 2864: RETURN_EMPTY_STRING();
! 2865: }
! 2866: /* }}} */
! 2867:
! 2868: /* {{{ proto public string ReflectionFunction::getShortName()
! 2869: Returns the short name of the function (without namespace part) */
! 2870: ZEND_METHOD(reflection_function, getShortName)
! 2871: {
! 2872: zval **name;
! 2873: char *backslash;
! 2874:
! 2875: if (zend_parse_parameters_none() == FAILURE) {
! 2876: return;
! 2877: }
! 2878: if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
! 2879: RETURN_FALSE;
! 2880: }
! 2881: if (Z_TYPE_PP(name) == IS_STRING
! 2882: && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
! 2883: && backslash > Z_STRVAL_PP(name))
! 2884: {
! 2885: RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1);
! 2886: }
! 2887: RETURN_ZVAL(*name, 1, 0);
! 2888: }
! 2889: /* }}} */
! 2890:
! 2891: /* {{{ proto public bool ReflectionMethod::isConstructor()
! 2892: Returns whether this method is the constructor */
! 2893: ZEND_METHOD(reflection_method, isConstructor)
! 2894: {
! 2895: reflection_object *intern;
! 2896: zend_function *mptr;
! 2897:
! 2898: if (zend_parse_parameters_none() == FAILURE) {
! 2899: return;
! 2900: }
! 2901: GET_REFLECTION_OBJECT_PTR(mptr);
! 2902: /* we need to check if the ctor is the ctor of the class level we we
! 2903: * looking at since we might be looking at an inherited old style ctor
! 2904: * defined in base class. */
! 2905: RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope);
! 2906: }
! 2907: /* }}} */
! 2908:
! 2909: /* {{{ proto public bool ReflectionMethod::isDestructor()
! 2910: Returns whether this method is static */
! 2911: ZEND_METHOD(reflection_method, isDestructor)
! 2912: {
! 2913: reflection_object *intern;
! 2914: zend_function *mptr;
! 2915:
! 2916: if (zend_parse_parameters_none() == FAILURE) {
! 2917: return;
! 2918: }
! 2919: GET_REFLECTION_OBJECT_PTR(mptr);
! 2920: RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR);
! 2921: }
! 2922: /* }}} */
! 2923:
! 2924: /* {{{ proto public int ReflectionMethod::getModifiers()
! 2925: Returns a bitfield of the access modifiers for this method */
! 2926: ZEND_METHOD(reflection_method, getModifiers)
! 2927: {
! 2928: reflection_object *intern;
! 2929: zend_function *mptr;
! 2930:
! 2931: if (zend_parse_parameters_none() == FAILURE) {
! 2932: return;
! 2933: }
! 2934: GET_REFLECTION_OBJECT_PTR(mptr);
! 2935:
! 2936: RETURN_LONG(mptr->common.fn_flags);
! 2937: }
! 2938: /* }}} */
! 2939:
! 2940: /* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass()
! 2941: Get the declaring class */
! 2942: ZEND_METHOD(reflection_method, getDeclaringClass)
! 2943: {
! 2944: reflection_object *intern;
! 2945: zend_function *mptr;
! 2946:
! 2947: METHOD_NOTSTATIC(reflection_method_ptr);
! 2948: GET_REFLECTION_OBJECT_PTR(mptr);
! 2949:
! 2950: if (zend_parse_parameters_none() == FAILURE) {
! 2951: return;
! 2952: }
! 2953:
! 2954: zend_reflection_class_factory(mptr->common.scope, return_value TSRMLS_CC);
! 2955: }
! 2956: /* }}} */
! 2957:
! 2958: /* {{{ proto public ReflectionClass ReflectionMethod::getPrototype()
! 2959: Get the prototype */
! 2960: ZEND_METHOD(reflection_method, getPrototype)
! 2961: {
! 2962: reflection_object *intern;
! 2963: zend_function *mptr;
! 2964:
! 2965: METHOD_NOTSTATIC(reflection_method_ptr);
! 2966: GET_REFLECTION_OBJECT_PTR(mptr);
! 2967:
! 2968: if (zend_parse_parameters_none() == FAILURE) {
! 2969: return;
! 2970: }
! 2971:
! 2972: if (!mptr->common.prototype) {
! 2973: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 2974: "Method %s::%s does not have a prototype", intern->ce->name, mptr->common.function_name);
! 2975: return;
! 2976: }
! 2977:
! 2978: reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value TSRMLS_CC);
! 2979: }
! 2980: /* }}} */
! 2981:
! 2982: /* {{{ proto public void ReflectionMethod::setAccessible(bool visible)
! 2983: Sets whether non-public methods can be invoked */
! 2984: ZEND_METHOD(reflection_method, setAccessible)
! 2985: {
! 2986: reflection_object *intern;
! 2987: zend_bool visible;
! 2988:
! 2989: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
! 2990: return;
! 2991: }
! 2992:
! 2993: intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
! 2994:
! 2995: if (intern == NULL) {
! 2996: return;
! 2997: }
! 2998:
! 2999: intern->ignore_visibility = visible;
! 3000: }
! 3001: /* }}} */
! 3002:
! 3003: /* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
! 3004: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 3005: ZEND_METHOD(reflection_class, export)
! 3006: {
! 3007: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1);
! 3008: }
! 3009: /* }}} */
! 3010:
! 3011: /* {{{ reflection_class_object_ctor */
! 3012: static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
! 3013: {
! 3014: zval *argument;
! 3015: zval *object;
! 3016: zval *classname;
! 3017: reflection_object *intern;
! 3018: zend_class_entry **ce;
! 3019:
! 3020: if (is_object) {
! 3021: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &argument) == FAILURE) {
! 3022: return;
! 3023: }
! 3024: } else {
! 3025: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &argument) == FAILURE) {
! 3026: return;
! 3027: }
! 3028: }
! 3029:
! 3030: object = getThis();
! 3031: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 3032: if (intern == NULL) {
! 3033: return;
! 3034: }
! 3035:
! 3036: if (Z_TYPE_P(argument) == IS_OBJECT) {
! 3037: MAKE_STD_ZVAL(classname);
! 3038: ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
! 3039: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
! 3040: intern->ptr = Z_OBJCE_P(argument);
! 3041: if (is_object) {
! 3042: intern->obj = argument;
! 3043: zval_add_ref(&argument);
! 3044: }
! 3045: } else {
! 3046: convert_to_string_ex(&argument);
! 3047: if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
! 3048: if (!EG(exception)) {
! 3049: zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument));
! 3050: }
! 3051: return;
! 3052: }
! 3053:
! 3054: MAKE_STD_ZVAL(classname);
! 3055: ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
! 3056: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
! 3057:
! 3058: intern->ptr = *ce;
! 3059: }
! 3060: intern->ref_type = REF_TYPE_OTHER;
! 3061: }
! 3062: /* }}} */
! 3063:
! 3064: /* {{{ proto public void ReflectionClass::__construct(mixed argument) throws ReflectionException
! 3065: Constructor. Takes a string or an instance as an argument */
! 3066: ZEND_METHOD(reflection_class, __construct)
! 3067: {
! 3068: reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
! 3069: }
! 3070: /* }}} */
! 3071:
! 3072: /* {{{ proto public array ReflectionClass::getStaticProperties()
! 3073: Returns an associative array containing all static property values of the class */
! 3074: ZEND_METHOD(reflection_class, getStaticProperties)
! 3075: {
! 3076: reflection_object *intern;
! 3077: zend_class_entry *ce;
! 3078: HashPosition pos;
! 3079: zval **value;
! 3080:
! 3081: if (zend_parse_parameters_none() == FAILURE) {
! 3082: return;
! 3083: }
! 3084:
! 3085: GET_REFLECTION_OBJECT_PTR(ce);
! 3086:
! 3087: zend_update_class_constants(ce TSRMLS_CC);
! 3088:
! 3089: array_init(return_value);
! 3090:
! 3091: zend_hash_internal_pointer_reset_ex(CE_STATIC_MEMBERS(ce), &pos);
! 3092:
! 3093: while (zend_hash_get_current_data_ex(CE_STATIC_MEMBERS(ce), (void **) &value, &pos) == SUCCESS) {
! 3094: uint key_len;
! 3095: char *key;
! 3096: ulong num_index;
! 3097:
! 3098: if (zend_hash_get_current_key_ex(CE_STATIC_MEMBERS(ce), &key, &key_len, &num_index, 0, &pos) != FAILURE && key) {
! 3099: char *prop_name, *class_name;
! 3100: zval *prop_copy;
! 3101:
! 3102: zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
! 3103:
! 3104: /* filter privates from base classes */
! 3105: if (!(class_name && class_name[0] != '*' && strcmp(class_name, ce->name))) {
! 3106: /* copy: enforce read only access */
! 3107: ALLOC_ZVAL(prop_copy);
! 3108: MAKE_COPY_ZVAL(value, prop_copy);
! 3109:
! 3110: add_assoc_zval(return_value, prop_name, prop_copy);
! 3111: }
! 3112: }
! 3113: zend_hash_move_forward_ex(CE_STATIC_MEMBERS(ce), &pos);
! 3114: }
! 3115: }
! 3116: /* }}} */
! 3117:
! 3118: /* {{{ proto public mixed ReflectionClass::getStaticPropertyValue(string name [, mixed default])
! 3119: Returns the value of a static property */
! 3120: ZEND_METHOD(reflection_class, getStaticPropertyValue)
! 3121: {
! 3122: reflection_object *intern;
! 3123: zend_class_entry *ce;
! 3124: char *name;
! 3125: int name_len;
! 3126: zval **prop, *def_value = NULL;
! 3127:
! 3128: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &name_len, &def_value) == FAILURE) {
! 3129: return;
! 3130: }
! 3131:
! 3132: GET_REFLECTION_OBJECT_PTR(ce);
! 3133:
! 3134: zend_update_class_constants(ce TSRMLS_CC);
! 3135: prop = zend_std_get_static_property(ce, name, name_len, 1 TSRMLS_CC);
! 3136: if (!prop) {
! 3137: if (def_value) {
! 3138: RETURN_ZVAL(def_value, 1, 0);
! 3139: } else {
! 3140: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 3141: "Class %s does not have a property named %s", ce->name, name);
! 3142: }
! 3143: return;
! 3144: } else {
! 3145: RETURN_ZVAL(*prop, 1, 0);
! 3146: }
! 3147: }
! 3148: /* }}} */
! 3149:
! 3150: /* {{{ proto public void ReflectionClass::setStaticPropertyValue($name, $value)
! 3151: Sets the value of a static property */
! 3152: ZEND_METHOD(reflection_class, setStaticPropertyValue)
! 3153: {
! 3154: reflection_object *intern;
! 3155: zend_class_entry *ce;
! 3156: char *name;
! 3157: int name_len;
! 3158: zval **variable_ptr, *value;
! 3159: int refcount;
! 3160: zend_uchar is_ref;
! 3161:
! 3162: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &value) == FAILURE) {
! 3163: return;
! 3164: }
! 3165:
! 3166: GET_REFLECTION_OBJECT_PTR(ce);
! 3167:
! 3168: zend_update_class_constants(ce TSRMLS_CC);
! 3169: variable_ptr = zend_std_get_static_property(ce, name, name_len, 1 TSRMLS_CC);
! 3170: if (!variable_ptr) {
! 3171: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 3172: "Class %s does not have a property named %s", ce->name, name);
! 3173: return;
! 3174: }
! 3175: refcount = Z_REFCOUNT_PP(variable_ptr);
! 3176: is_ref = Z_ISREF_PP(variable_ptr);
! 3177: zval_dtor(*variable_ptr);
! 3178: **variable_ptr = *value;
! 3179: zval_copy_ctor(*variable_ptr);
! 3180: Z_SET_REFCOUNT_PP(variable_ptr, refcount);
! 3181: Z_SET_ISREF_TO_PP(variable_ptr, is_ref);
! 3182:
! 3183: }
! 3184: /* }}} */
! 3185:
! 3186: /* {{{ proto public array ReflectionClass::getDefaultProperties()
! 3187: Returns an associative array containing copies of all default property values of the class */
! 3188: ZEND_METHOD(reflection_class, getDefaultProperties)
! 3189: {
! 3190: reflection_object *intern;
! 3191: zend_class_entry *ce;
! 3192: int count, i;
! 3193: HashTable *ht_list[3];
! 3194:
! 3195: if (zend_parse_parameters_none() == FAILURE) {
! 3196: return;
! 3197: }
! 3198: GET_REFLECTION_OBJECT_PTR(ce);
! 3199: array_init(return_value);
! 3200:
! 3201: zend_update_class_constants(ce TSRMLS_CC);
! 3202:
! 3203: ht_list[0] = CE_STATIC_MEMBERS(ce);
! 3204: ht_list[1] = &ce->default_properties;
! 3205: ht_list[2] = NULL;
! 3206:
! 3207: for (i = 0; ht_list[i] != NULL; i++) {
! 3208:
! 3209: count = zend_hash_num_elements(ht_list[i]);
! 3210: if (count > 0) {
! 3211: HashPosition pos;
! 3212: zval **prop;
! 3213:
! 3214: zend_hash_internal_pointer_reset_ex(ht_list[i], &pos);
! 3215: while (zend_hash_get_current_data_ex(ht_list[i], (void **) &prop, &pos) == SUCCESS) {
! 3216: char *key, *class_name, *prop_name;
! 3217: uint key_len;
! 3218: ulong num_index;
! 3219: zval *prop_copy;
! 3220:
! 3221: zend_hash_get_current_key_ex(ht_list[i], &key, &key_len, &num_index, 0, &pos);
! 3222: zend_hash_move_forward_ex(ht_list[i], &pos);
! 3223: zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
! 3224: if (class_name && class_name[0] != '*' && strcmp(class_name, ce->name)) {
! 3225: /* filter privates from base classes */
! 3226: continue;
! 3227: }
! 3228:
! 3229: /* copy: enforce read only access */
! 3230: ALLOC_ZVAL(prop_copy);
! 3231: MAKE_COPY_ZVAL(prop, prop_copy);
! 3232:
! 3233: add_assoc_zval(return_value, prop_name, prop_copy);
! 3234: }
! 3235: }
! 3236: }
! 3237: }
! 3238: /* }}} */
! 3239:
! 3240: /* {{{ proto public string ReflectionClass::__toString()
! 3241: Returns a string representation */
! 3242: ZEND_METHOD(reflection_class, __toString)
! 3243: {
! 3244: reflection_object *intern;
! 3245: zend_class_entry *ce;
! 3246: string str;
! 3247:
! 3248: if (zend_parse_parameters_none() == FAILURE) {
! 3249: return;
! 3250: }
! 3251: GET_REFLECTION_OBJECT_PTR(ce);
! 3252: string_init(&str);
! 3253: _class_string(&str, ce, intern->obj, "" TSRMLS_CC);
! 3254: RETURN_STRINGL(str.string, str.len - 1, 0);
! 3255: }
! 3256: /* }}} */
! 3257:
! 3258: /* {{{ proto public string ReflectionClass::getName()
! 3259: Returns the class' name */
! 3260: ZEND_METHOD(reflection_class, getName)
! 3261: {
! 3262: if (zend_parse_parameters_none() == FAILURE) {
! 3263: return;
! 3264: }
! 3265: _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
! 3266: }
! 3267: /* }}} */
! 3268:
! 3269: /* {{{ proto public bool ReflectionClass::isInternal()
! 3270: Returns whether this class is an internal class */
! 3271: ZEND_METHOD(reflection_class, isInternal)
! 3272: {
! 3273: reflection_object *intern;
! 3274: zend_class_entry *ce;
! 3275:
! 3276: if (zend_parse_parameters_none() == FAILURE) {
! 3277: return;
! 3278: }
! 3279: GET_REFLECTION_OBJECT_PTR(ce);
! 3280: RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS);
! 3281: }
! 3282: /* }}} */
! 3283:
! 3284: /* {{{ proto public bool ReflectionClass::isUserDefined()
! 3285: Returns whether this class is user-defined */
! 3286: ZEND_METHOD(reflection_class, isUserDefined)
! 3287: {
! 3288: reflection_object *intern;
! 3289: zend_class_entry *ce;
! 3290:
! 3291: if (zend_parse_parameters_none() == FAILURE) {
! 3292: return;
! 3293: }
! 3294: GET_REFLECTION_OBJECT_PTR(ce);
! 3295: RETURN_BOOL(ce->type == ZEND_USER_CLASS);
! 3296: }
! 3297: /* }}} */
! 3298:
! 3299: /* {{{ proto public string ReflectionClass::getFileName()
! 3300: Returns the filename of the file this class was declared in */
! 3301: ZEND_METHOD(reflection_class, getFileName)
! 3302: {
! 3303: reflection_object *intern;
! 3304: zend_class_entry *ce;
! 3305:
! 3306: if (zend_parse_parameters_none() == FAILURE) {
! 3307: return;
! 3308: }
! 3309: GET_REFLECTION_OBJECT_PTR(ce);
! 3310: if (ce->type == ZEND_USER_CLASS) {
! 3311: RETURN_STRING(ce->filename, 1);
! 3312: }
! 3313: RETURN_FALSE;
! 3314: }
! 3315: /* }}} */
! 3316:
! 3317: /* {{{ proto public int ReflectionClass::getStartLine()
! 3318: Returns the line this class' declaration starts at */
! 3319: ZEND_METHOD(reflection_class, getStartLine)
! 3320: {
! 3321: reflection_object *intern;
! 3322: zend_class_entry *ce;
! 3323:
! 3324: if (zend_parse_parameters_none() == FAILURE) {
! 3325: return;
! 3326: }
! 3327: GET_REFLECTION_OBJECT_PTR(ce);
! 3328: if (ce->type == ZEND_USER_FUNCTION) {
! 3329: RETURN_LONG(ce->line_start);
! 3330: }
! 3331: RETURN_FALSE;
! 3332: }
! 3333: /* }}} */
! 3334:
! 3335: /* {{{ proto public int ReflectionClass::getEndLine()
! 3336: Returns the line this class' declaration ends at */
! 3337: ZEND_METHOD(reflection_class, getEndLine)
! 3338: {
! 3339: reflection_object *intern;
! 3340: zend_class_entry *ce;
! 3341:
! 3342: if (zend_parse_parameters_none() == FAILURE) {
! 3343: return;
! 3344: }
! 3345: GET_REFLECTION_OBJECT_PTR(ce);
! 3346: if (ce->type == ZEND_USER_CLASS) {
! 3347: RETURN_LONG(ce->line_end);
! 3348: }
! 3349: RETURN_FALSE;
! 3350: }
! 3351: /* }}} */
! 3352:
! 3353: /* {{{ proto public string ReflectionClass::getDocComment()
! 3354: Returns the doc comment for this class */
! 3355: ZEND_METHOD(reflection_class, getDocComment)
! 3356: {
! 3357: reflection_object *intern;
! 3358: zend_class_entry *ce;
! 3359:
! 3360: if (zend_parse_parameters_none() == FAILURE) {
! 3361: return;
! 3362: }
! 3363: GET_REFLECTION_OBJECT_PTR(ce);
! 3364: if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
! 3365: RETURN_STRINGL(ce->doc_comment, ce->doc_comment_len, 1);
! 3366: }
! 3367: RETURN_FALSE;
! 3368: }
! 3369: /* }}} */
! 3370:
! 3371: /* {{{ proto public ReflectionMethod ReflectionClass::getConstructor()
! 3372: Returns the class' constructor if there is one, NULL otherwise */
! 3373: ZEND_METHOD(reflection_class, getConstructor)
! 3374: {
! 3375: reflection_object *intern;
! 3376: zend_class_entry *ce;
! 3377:
! 3378: if (zend_parse_parameters_none() == FAILURE) {
! 3379: return;
! 3380: }
! 3381: GET_REFLECTION_OBJECT_PTR(ce);
! 3382:
! 3383: if (ce->constructor) {
! 3384: reflection_method_factory(ce, ce->constructor, NULL, return_value TSRMLS_CC);
! 3385: } else {
! 3386: RETURN_NULL();
! 3387: }
! 3388: }
! 3389: /* }}} */
! 3390:
! 3391: /* {{{ proto public bool ReflectionClass::hasMethod(string name)
! 3392: Returns whether a method exists or not */
! 3393: ZEND_METHOD(reflection_class, hasMethod)
! 3394: {
! 3395: reflection_object *intern;
! 3396: zend_class_entry *ce;
! 3397: char *name, *lc_name;
! 3398: int name_len;
! 3399:
! 3400: METHOD_NOTSTATIC(reflection_class_ptr);
! 3401: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
! 3402: return;
! 3403: }
! 3404:
! 3405: GET_REFLECTION_OBJECT_PTR(ce);
! 3406: lc_name = zend_str_tolower_dup(name, name_len);
! 3407: if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 3408: && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
! 3409: || zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
! 3410: efree(lc_name);
! 3411: RETURN_TRUE;
! 3412: } else {
! 3413: efree(lc_name);
! 3414: RETURN_FALSE;
! 3415: }
! 3416: }
! 3417: /* }}} */
! 3418:
! 3419: /* {{{ proto public ReflectionMethod ReflectionClass::getMethod(string name) throws ReflectionException
! 3420: Returns the class' method specified by its name */
! 3421: ZEND_METHOD(reflection_class, getMethod)
! 3422: {
! 3423: reflection_object *intern;
! 3424: zend_class_entry *ce;
! 3425: zend_function *mptr;
! 3426: zval obj_tmp;
! 3427: char *name, *lc_name;
! 3428: int name_len;
! 3429:
! 3430: METHOD_NOTSTATIC(reflection_class_ptr);
! 3431: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
! 3432: return;
! 3433: }
! 3434:
! 3435: GET_REFLECTION_OBJECT_PTR(ce);
! 3436: lc_name = zend_str_tolower_dup(name, name_len);
! 3437: if (ce == zend_ce_closure && intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 3438: && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
! 3439: && (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) != NULL)
! 3440: {
! 3441: /* don't assign closure_object since we only reflect the invoke handler
! 3442: method and not the closure definition itself */
! 3443: reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
! 3444: efree(lc_name);
! 3445: } else if (ce == zend_ce_closure && !intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 3446: && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
! 3447: && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(&obj_tmp TSRMLS_CC)) != NULL) {
! 3448: /* don't assign closure_object since we only reflect the invoke handler
! 3449: method and not the closure definition itself */
! 3450: reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
! 3451: zval_dtor(&obj_tmp);
! 3452: efree(lc_name);
! 3453: } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
! 3454: reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
! 3455: efree(lc_name);
! 3456: } else {
! 3457: efree(lc_name);
! 3458: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 3459: "Method %s does not exist", name);
! 3460: return;
! 3461: }
! 3462: }
! 3463: /* }}} */
! 3464:
! 3465: /* {{{ _addmethod */
! 3466: static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, long filter, zval *obj TSRMLS_DC)
! 3467: {
! 3468: zval *method;
! 3469: uint len = strlen(mptr->common.function_name);
! 3470: zend_function *closure;
! 3471:
! 3472: if (mptr->common.fn_flags & filter) {
! 3473: ALLOC_ZVAL(method);
! 3474: if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
! 3475: && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
! 3476: && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
! 3477: {
! 3478: mptr = closure;
! 3479: }
! 3480: /* don't assign closure_object since we only reflect the invoke handler
! 3481: method and not the closure definition itself, even if we have a
! 3482: closure */
! 3483: reflection_method_factory(ce, mptr, NULL, method TSRMLS_CC);
! 3484: add_next_index_zval(retval, method);
! 3485: }
! 3486: }
! 3487: /* }}} */
! 3488:
! 3489: /* {{{ _addmethod */
! 3490: static int _addmethod_va(zend_function *mptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 3491: {
! 3492: zend_class_entry *ce = *va_arg(args, zend_class_entry**);
! 3493: zval *retval = va_arg(args, zval*);
! 3494: long filter = va_arg(args, long);
! 3495: zval *obj = va_arg(args, zval *);
! 3496:
! 3497: _addmethod(mptr, ce, retval, filter, obj TSRMLS_CC);
! 3498: return ZEND_HASH_APPLY_KEEP;
! 3499: }
! 3500: /* }}} */
! 3501:
! 3502: /* {{{ proto public ReflectionMethod[] ReflectionClass::getMethods([long $filter])
! 3503: Returns an array of this class' methods */
! 3504: ZEND_METHOD(reflection_class, getMethods)
! 3505: {
! 3506: reflection_object *intern;
! 3507: zend_class_entry *ce;
! 3508: long filter = 0;
! 3509: int argc = ZEND_NUM_ARGS();
! 3510:
! 3511: METHOD_NOTSTATIC(reflection_class_ptr);
! 3512: if (argc) {
! 3513: if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
! 3514: return;
! 3515: }
! 3516: } else {
! 3517: /* No parameters given, default to "return all" */
! 3518: filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC;
! 3519: }
! 3520:
! 3521: GET_REFLECTION_OBJECT_PTR(ce);
! 3522:
! 3523: array_init(return_value);
! 3524: zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter, intern->obj);
! 3525: if (intern->obj && instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
! 3526: zend_function *closure = zend_get_closure_invoke_method(intern->obj TSRMLS_CC);
! 3527: if (closure) {
! 3528: _addmethod(closure, ce, return_value, filter, intern->obj TSRMLS_CC);
! 3529: _free_function(closure TSRMLS_CC);
! 3530: }
! 3531: }
! 3532: }
! 3533: /* }}} */
! 3534:
! 3535: /* {{{ proto public bool ReflectionClass::hasProperty(string name)
! 3536: Returns whether a property exists or not */
! 3537: ZEND_METHOD(reflection_class, hasProperty)
! 3538: {
! 3539: reflection_object *intern;
! 3540: zend_property_info *property_info;
! 3541: zend_class_entry *ce;
! 3542: char *name;
! 3543: int name_len;
! 3544: zval *property;
! 3545:
! 3546: METHOD_NOTSTATIC(reflection_class_ptr);
! 3547: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
! 3548: return;
! 3549: }
! 3550:
! 3551: GET_REFLECTION_OBJECT_PTR(ce);
! 3552: if (zend_hash_find(&ce->properties_info, name, name_len+1, (void **) &property_info) == SUCCESS) {
! 3553: if (property_info->flags & ZEND_ACC_SHADOW) {
! 3554: RETURN_FALSE;
! 3555: }
! 3556: RETURN_TRUE;
! 3557: } else {
! 3558: if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property)) {
! 3559: MAKE_STD_ZVAL(property);
! 3560: ZVAL_STRINGL(property, name, name_len, 1);
! 3561: if (Z_OBJ_HANDLER_P(intern->obj, has_property)(intern->obj, property, 2 TSRMLS_CC)) {
! 3562: zval_ptr_dtor(&property);
! 3563: RETURN_TRUE;
! 3564: }
! 3565: zval_ptr_dtor(&property);
! 3566: }
! 3567: RETURN_FALSE;
! 3568: }
! 3569: }
! 3570: /* }}} */
! 3571:
! 3572: /* {{{ proto public ReflectionProperty ReflectionClass::getProperty(string name) throws ReflectionException
! 3573: Returns the class' property specified by its name */
! 3574: ZEND_METHOD(reflection_class, getProperty)
! 3575: {
! 3576: reflection_object *intern;
! 3577: zend_class_entry *ce, **pce;
! 3578: zend_property_info *property_info;
! 3579: char *name, *tmp, *classname;
! 3580: int name_len, classname_len;
! 3581:
! 3582: METHOD_NOTSTATIC(reflection_class_ptr);
! 3583: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
! 3584: return;
! 3585: }
! 3586:
! 3587: GET_REFLECTION_OBJECT_PTR(ce);
! 3588: if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS) {
! 3589: if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
! 3590: reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
! 3591: return;
! 3592: }
! 3593: } else if (intern->obj) {
! 3594: /* Check for dynamic properties */
! 3595: if (zend_hash_exists(Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC), name, name_len+1)) {
! 3596: zend_property_info property_info_tmp;
! 3597: property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC;
! 3598: property_info_tmp.name = estrndup(name, name_len);
! 3599: property_info_tmp.name_length = name_len;
! 3600: property_info_tmp.h = zend_get_hash_value(name, name_len+1);
! 3601: property_info_tmp.doc_comment = NULL;
! 3602: property_info_tmp.ce = ce;
! 3603:
! 3604: reflection_property_factory(ce, &property_info_tmp, return_value TSRMLS_CC);
! 3605: intern = (reflection_object *) zend_object_store_get_object(return_value TSRMLS_CC);
! 3606: intern->ref_type = REF_TYPE_DYNAMIC_PROPERTY;
! 3607: return;
! 3608: }
! 3609: }
! 3610: if ((tmp = strstr(name, "::")) != NULL) {
! 3611: classname_len = tmp - name;
! 3612: classname = zend_str_tolower_dup(name, classname_len);
! 3613: classname[classname_len] = '\0';
! 3614: name_len = name_len - (classname_len + 2);
! 3615: name = tmp + 2;
! 3616:
! 3617: if (zend_lookup_class(classname, classname_len, &pce TSRMLS_CC) == FAILURE) {
! 3618: if (!EG(exception)) {
! 3619: zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", classname);
! 3620: }
! 3621: efree(classname);
! 3622: return;
! 3623: }
! 3624: efree(classname);
! 3625:
! 3626: if (!instanceof_function(ce, *pce TSRMLS_CC)) {
! 3627: 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);
! 3628: return;
! 3629: }
! 3630: ce = *pce;
! 3631:
! 3632: if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
! 3633: reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
! 3634: return;
! 3635: }
! 3636: }
! 3637: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 3638: "Property %s does not exist", name);
! 3639: }
! 3640: /* }}} */
! 3641:
! 3642: /* {{{ _addproperty */
! 3643: static int _addproperty(zend_property_info *pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 3644: {
! 3645: zval *property;
! 3646: zend_class_entry *ce = *va_arg(args, zend_class_entry**);
! 3647: zval *retval = va_arg(args, zval*);
! 3648: long filter = va_arg(args, long);
! 3649:
! 3650: if (pptr->flags & ZEND_ACC_SHADOW) {
! 3651: return 0;
! 3652: }
! 3653:
! 3654: if (pptr->flags & filter) {
! 3655: ALLOC_ZVAL(property);
! 3656: reflection_property_factory(ce, pptr, property TSRMLS_CC);
! 3657: add_next_index_zval(retval, property);
! 3658: }
! 3659: return 0;
! 3660: }
! 3661: /* }}} */
! 3662:
! 3663: /* {{{ _adddynproperty */
! 3664: static int _adddynproperty(zval **pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 3665: {
! 3666: zval *property;
! 3667: zend_class_entry *ce = *va_arg(args, zend_class_entry**);
! 3668: zval *retval = va_arg(args, zval*), member;
! 3669:
! 3670: if (hash_key->arKey[0] == '\0') {
! 3671: return 0; /* non public cannot be dynamic */
! 3672: }
! 3673:
! 3674: ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0);
! 3675: if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) {
! 3676: MAKE_STD_ZVAL(property);
! 3677: EG(std_property_info).flags = ZEND_ACC_IMPLICIT_PUBLIC;
! 3678: reflection_property_factory(ce, &EG(std_property_info), property TSRMLS_CC);
! 3679: add_next_index_zval(retval, property);
! 3680: }
! 3681: return 0;
! 3682: }
! 3683: /* }}} */
! 3684:
! 3685: /* {{{ proto public ReflectionProperty[] ReflectionClass::getProperties([long $filter])
! 3686: Returns an array of this class' properties */
! 3687: ZEND_METHOD(reflection_class, getProperties)
! 3688: {
! 3689: reflection_object *intern;
! 3690: zend_class_entry *ce;
! 3691: long filter = 0;
! 3692: int argc = ZEND_NUM_ARGS();
! 3693:
! 3694: METHOD_NOTSTATIC(reflection_class_ptr);
! 3695: if (argc) {
! 3696: if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
! 3697: return;
! 3698: }
! 3699: } else {
! 3700: /* No parameters given, default to "return all" */
! 3701: filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC;
! 3702: }
! 3703:
! 3704: GET_REFLECTION_OBJECT_PTR(ce);
! 3705:
! 3706: array_init(return_value);
! 3707: zend_hash_apply_with_arguments(&ce->properties_info TSRMLS_CC, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter);
! 3708:
! 3709: if (intern->obj && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT_P(intern->obj)->get_properties) {
! 3710: HashTable *properties = Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC);
! 3711: zend_hash_apply_with_arguments(properties TSRMLS_CC, (apply_func_args_t) _adddynproperty, 2, &ce, return_value);
! 3712: }
! 3713: }
! 3714: /* }}} */
! 3715:
! 3716: /* {{{ proto public bool ReflectionClass::hasConstant(string name)
! 3717: Returns whether a constant exists or not */
! 3718: ZEND_METHOD(reflection_class, hasConstant)
! 3719: {
! 3720: reflection_object *intern;
! 3721: zend_class_entry *ce;
! 3722: char *name;
! 3723: int name_len;
! 3724:
! 3725: METHOD_NOTSTATIC(reflection_class_ptr);
! 3726: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
! 3727: return;
! 3728: }
! 3729:
! 3730: GET_REFLECTION_OBJECT_PTR(ce);
! 3731: if (zend_hash_exists(&ce->constants_table, name, name_len + 1)) {
! 3732: RETURN_TRUE;
! 3733: } else {
! 3734: RETURN_FALSE;
! 3735: }
! 3736: }
! 3737: /* }}} */
! 3738:
! 3739: /* {{{ proto public array ReflectionClass::getConstants()
! 3740: Returns an associative array containing this class' constants and their values */
! 3741: ZEND_METHOD(reflection_class, getConstants)
! 3742: {
! 3743: zval *tmp_copy;
! 3744: reflection_object *intern;
! 3745: zend_class_entry *ce;
! 3746:
! 3747: if (zend_parse_parameters_none() == FAILURE) {
! 3748: return;
! 3749: }
! 3750: GET_REFLECTION_OBJECT_PTR(ce);
! 3751: array_init(return_value);
! 3752: zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC);
! 3753: zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
! 3754: }
! 3755: /* }}} */
! 3756:
! 3757: /* {{{ proto public mixed ReflectionClass::getConstant(string name)
! 3758: Returns the class' constant specified by its name */
! 3759: ZEND_METHOD(reflection_class, getConstant)
! 3760: {
! 3761: reflection_object *intern;
! 3762: zend_class_entry *ce;
! 3763: zval **value;
! 3764: char *name;
! 3765: int name_len;
! 3766:
! 3767: METHOD_NOTSTATIC(reflection_class_ptr);
! 3768: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
! 3769: return;
! 3770: }
! 3771:
! 3772: GET_REFLECTION_OBJECT_PTR(ce);
! 3773: zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC);
! 3774: if (zend_hash_find(&ce->constants_table, name, name_len + 1, (void **) &value) == FAILURE) {
! 3775: RETURN_FALSE;
! 3776: }
! 3777: MAKE_COPY_ZVAL(value, return_value);
! 3778: }
! 3779: /* }}} */
! 3780:
! 3781: /* {{{ _class_check_flag */
! 3782: static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
! 3783: {
! 3784: reflection_object *intern;
! 3785: zend_class_entry *ce;
! 3786:
! 3787: if (zend_parse_parameters_none() == FAILURE) {
! 3788: return;
! 3789: }
! 3790: GET_REFLECTION_OBJECT_PTR(ce);
! 3791: RETVAL_BOOL(ce->ce_flags & mask);
! 3792: }
! 3793: /* }}} */
! 3794:
! 3795: /* {{{ proto public bool ReflectionClass::isInstantiable()
! 3796: Returns whether this class is instantiable */
! 3797: ZEND_METHOD(reflection_class, isInstantiable)
! 3798: {
! 3799: reflection_object *intern;
! 3800: zend_class_entry *ce;
! 3801:
! 3802: if (zend_parse_parameters_none() == FAILURE) {
! 3803: return;
! 3804: }
! 3805: GET_REFLECTION_OBJECT_PTR(ce);
! 3806: if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
! 3807: RETURN_FALSE;
! 3808: }
! 3809:
! 3810: /* Basically, the class is instantiable. Though, if there is a constructor
! 3811: * and it is not publicly accessible, it isn't! */
! 3812: if (!ce->constructor) {
! 3813: RETURN_TRUE;
! 3814: }
! 3815:
! 3816: RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC);
! 3817: }
! 3818: /* }}} */
! 3819:
! 3820: /* {{{ proto public bool ReflectionClass::isInterface()
! 3821: Returns whether this is an interface or a class */
! 3822: ZEND_METHOD(reflection_class, isInterface)
! 3823: {
! 3824: _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE);
! 3825: }
! 3826: /* }}} */
! 3827:
! 3828: /* {{{ proto public bool ReflectionClass::isFinal()
! 3829: Returns whether this class is final */
! 3830: ZEND_METHOD(reflection_class, isFinal)
! 3831: {
! 3832: _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL_CLASS);
! 3833: }
! 3834: /* }}} */
! 3835:
! 3836: /* {{{ proto public bool ReflectionClass::isAbstract()
! 3837: Returns whether this class is abstract */
! 3838: ZEND_METHOD(reflection_class, isAbstract)
! 3839: {
! 3840: _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
! 3841: }
! 3842: /* }}} */
! 3843:
! 3844: /* {{{ proto public int ReflectionClass::getModifiers()
! 3845: Returns a bitfield of the access modifiers for this class */
! 3846: ZEND_METHOD(reflection_class, getModifiers)
! 3847: {
! 3848: reflection_object *intern;
! 3849: zend_class_entry *ce;
! 3850:
! 3851: if (zend_parse_parameters_none() == FAILURE) {
! 3852: return;
! 3853: }
! 3854: GET_REFLECTION_OBJECT_PTR(ce);
! 3855:
! 3856: RETURN_LONG(ce->ce_flags);
! 3857: }
! 3858: /* }}} */
! 3859:
! 3860: /* {{{ proto public bool ReflectionClass::isInstance(stdclass object)
! 3861: Returns whether the given object is an instance of this class */
! 3862: ZEND_METHOD(reflection_class, isInstance)
! 3863: {
! 3864: reflection_object *intern;
! 3865: zend_class_entry *ce;
! 3866: zval *object;
! 3867:
! 3868: METHOD_NOTSTATIC(reflection_class_ptr);
! 3869: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
! 3870: return;
! 3871: }
! 3872: GET_REFLECTION_OBJECT_PTR(ce);
! 3873: RETURN_BOOL(HAS_CLASS_ENTRY(*object) && instanceof_function(Z_OBJCE_P(object), ce TSRMLS_CC));
! 3874: }
! 3875: /* }}} */
! 3876:
! 3877: /* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...)
! 3878: Returns an instance of this class */
! 3879: ZEND_METHOD(reflection_class, newInstance)
! 3880: {
! 3881: zval *retval_ptr = NULL;
! 3882: reflection_object *intern;
! 3883: zend_class_entry *ce;
! 3884:
! 3885: METHOD_NOTSTATIC(reflection_class_ptr);
! 3886: GET_REFLECTION_OBJECT_PTR(ce);
! 3887:
! 3888: /* Run the constructor if there is one */
! 3889: if (ce->constructor) {
! 3890: zval ***params = NULL;
! 3891: int num_args = 0;
! 3892: zend_fcall_info fci;
! 3893: zend_fcall_info_cache fcc;
! 3894:
! 3895: if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
! 3896: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
! 3897: return;
! 3898: }
! 3899:
! 3900: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", ¶ms, &num_args) == FAILURE) {
! 3901: if (params) {
! 3902: efree(params);
! 3903: }
! 3904: RETURN_FALSE;
! 3905: }
! 3906:
! 3907: object_init_ex(return_value, ce);
! 3908:
! 3909: fci.size = sizeof(fci);
! 3910: fci.function_table = EG(function_table);
! 3911: fci.function_name = NULL;
! 3912: fci.symbol_table = NULL;
! 3913: fci.object_ptr = return_value;
! 3914: fci.retval_ptr_ptr = &retval_ptr;
! 3915: fci.param_count = num_args;
! 3916: fci.params = params;
! 3917: fci.no_separation = 1;
! 3918:
! 3919: fcc.initialized = 1;
! 3920: fcc.function_handler = ce->constructor;
! 3921: fcc.calling_scope = EG(scope);
! 3922: fcc.called_scope = Z_OBJCE_P(return_value);
! 3923: fcc.object_ptr = return_value;
! 3924:
! 3925: if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
! 3926: if (params) {
! 3927: efree(params);
! 3928: }
! 3929: if (retval_ptr) {
! 3930: zval_ptr_dtor(&retval_ptr);
! 3931: }
! 3932: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
! 3933: RETURN_NULL();
! 3934: }
! 3935: if (retval_ptr) {
! 3936: zval_ptr_dtor(&retval_ptr);
! 3937: }
! 3938: if (params) {
! 3939: efree(params);
! 3940: }
! 3941: } else if (!ZEND_NUM_ARGS()) {
! 3942: object_init_ex(return_value, ce);
! 3943: } else {
! 3944: 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);
! 3945: }
! 3946: }
! 3947: /* }}} */
! 3948:
! 3949: /* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args])
! 3950: Returns an instance of this class */
! 3951: ZEND_METHOD(reflection_class, newInstanceArgs)
! 3952: {
! 3953: zval *retval_ptr = NULL;
! 3954: reflection_object *intern;
! 3955: zend_class_entry *ce;
! 3956: int argc = 0;
! 3957: HashTable *args;
! 3958:
! 3959:
! 3960: METHOD_NOTSTATIC(reflection_class_ptr);
! 3961: GET_REFLECTION_OBJECT_PTR(ce);
! 3962:
! 3963: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) {
! 3964: return;
! 3965: }
! 3966: if (ZEND_NUM_ARGS() > 0) {
! 3967: argc = args->nNumOfElements;
! 3968: }
! 3969:
! 3970: /* Run the constructor if there is one */
! 3971: if (ce->constructor) {
! 3972: zval ***params = NULL;
! 3973: zend_fcall_info fci;
! 3974: zend_fcall_info_cache fcc;
! 3975:
! 3976: if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
! 3977: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
! 3978: return;
! 3979: }
! 3980:
! 3981: if (argc) {
! 3982: params = safe_emalloc(sizeof(zval **), argc, 0);
! 3983: zend_hash_apply_with_argument(args, (apply_func_arg_t)_zval_array_to_c_array, ¶ms TSRMLS_CC);
! 3984: params -= argc;
! 3985: }
! 3986:
! 3987: object_init_ex(return_value, ce);
! 3988:
! 3989: fci.size = sizeof(fci);
! 3990: fci.function_table = EG(function_table);
! 3991: fci.function_name = NULL;
! 3992: fci.symbol_table = NULL;
! 3993: fci.object_ptr = return_value;
! 3994: fci.retval_ptr_ptr = &retval_ptr;
! 3995: fci.param_count = argc;
! 3996: fci.params = params;
! 3997: fci.no_separation = 1;
! 3998:
! 3999: fcc.initialized = 1;
! 4000: fcc.function_handler = ce->constructor;
! 4001: fcc.calling_scope = EG(scope);
! 4002: fcc.called_scope = Z_OBJCE_P(return_value);
! 4003: fcc.object_ptr = return_value;
! 4004:
! 4005: if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
! 4006: if (params) {
! 4007: efree(params);
! 4008: }
! 4009: if (retval_ptr) {
! 4010: zval_ptr_dtor(&retval_ptr);
! 4011: }
! 4012: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
! 4013: RETURN_NULL();
! 4014: }
! 4015: if (retval_ptr) {
! 4016: zval_ptr_dtor(&retval_ptr);
! 4017: }
! 4018: if (params) {
! 4019: efree(params);
! 4020: }
! 4021: } else if (!ZEND_NUM_ARGS() || !argc) {
! 4022: object_init_ex(return_value, ce);
! 4023: } else {
! 4024: 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);
! 4025: }
! 4026: }
! 4027: /* }}} */
! 4028:
! 4029: /* {{{ proto public ReflectionClass[] ReflectionClass::getInterfaces()
! 4030: Returns an array of interfaces this class implements */
! 4031: ZEND_METHOD(reflection_class, getInterfaces)
! 4032: {
! 4033: reflection_object *intern;
! 4034: zend_class_entry *ce;
! 4035:
! 4036: if (zend_parse_parameters_none() == FAILURE) {
! 4037: return;
! 4038: }
! 4039: GET_REFLECTION_OBJECT_PTR(ce);
! 4040:
! 4041: /* Return an empty array if this class implements no interfaces */
! 4042: array_init(return_value);
! 4043:
! 4044: if (ce->num_interfaces) {
! 4045: zend_uint i;
! 4046:
! 4047: for (i=0; i < ce->num_interfaces; i++) {
! 4048: zval *interface;
! 4049: ALLOC_ZVAL(interface);
! 4050: zend_reflection_class_factory(ce->interfaces[i], interface TSRMLS_CC);
! 4051: add_assoc_zval_ex(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length + 1, interface);
! 4052: }
! 4053: }
! 4054: }
! 4055: /* }}} */
! 4056:
! 4057: /* {{{ proto public String[] ReflectionClass::getInterfaceNames()
! 4058: Returns an array of names of interfaces this class implements */
! 4059: ZEND_METHOD(reflection_class, getInterfaceNames)
! 4060: {
! 4061: reflection_object *intern;
! 4062: zend_class_entry *ce;
! 4063: zend_uint i;
! 4064:
! 4065: if (zend_parse_parameters_none() == FAILURE) {
! 4066: return;
! 4067: }
! 4068: GET_REFLECTION_OBJECT_PTR(ce);
! 4069:
! 4070: /* Return an empty array if this class implements no interfaces */
! 4071: array_init(return_value);
! 4072:
! 4073: for (i=0; i < ce->num_interfaces; i++) {
! 4074: add_next_index_stringl(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length, 1);
! 4075: }
! 4076: }
! 4077: /* }}} */
! 4078:
! 4079: /* {{{ proto public ReflectionClass ReflectionClass::getParentClass()
! 4080: Returns the class' parent class, or, if none exists, FALSE */
! 4081: ZEND_METHOD(reflection_class, getParentClass)
! 4082: {
! 4083: reflection_object *intern;
! 4084: zend_class_entry *ce;
! 4085:
! 4086: if (zend_parse_parameters_none() == FAILURE) {
! 4087: return;
! 4088: }
! 4089: GET_REFLECTION_OBJECT_PTR(ce);
! 4090:
! 4091: if (ce->parent) {
! 4092: zend_reflection_class_factory(ce->parent, return_value TSRMLS_CC);
! 4093: } else {
! 4094: RETURN_FALSE;
! 4095: }
! 4096: }
! 4097: /* }}} */
! 4098:
! 4099: /* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class)
! 4100: Returns whether this class is a subclass of another class */
! 4101: ZEND_METHOD(reflection_class, isSubclassOf)
! 4102: {
! 4103: reflection_object *intern, *argument;
! 4104: zend_class_entry *ce, **pce, *class_ce;
! 4105: zval *class_name;
! 4106:
! 4107: METHOD_NOTSTATIC(reflection_class_ptr);
! 4108: GET_REFLECTION_OBJECT_PTR(ce);
! 4109:
! 4110: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE) {
! 4111: return;
! 4112: }
! 4113:
! 4114: switch(class_name->type) {
! 4115: case IS_STRING:
! 4116: if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
! 4117: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4118: "Class %s does not exist", Z_STRVAL_P(class_name));
! 4119: return;
! 4120: }
! 4121: class_ce = *pce;
! 4122: break;
! 4123: case IS_OBJECT:
! 4124: if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr TSRMLS_CC)) {
! 4125: argument = (reflection_object *) zend_object_store_get_object(class_name TSRMLS_CC);
! 4126: if (argument == NULL || argument->ptr == NULL) {
! 4127: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
! 4128: /* Bails out */
! 4129: }
! 4130: class_ce = argument->ptr;
! 4131: break;
! 4132: }
! 4133: /* no break */
! 4134: default:
! 4135: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4136: "Parameter one must either be a string or a ReflectionClass object");
! 4137: return;
! 4138: }
! 4139:
! 4140: RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce TSRMLS_CC)));
! 4141: }
! 4142: /* }}} */
! 4143:
! 4144: /* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name)
! 4145: Returns whether this class is a subclass of another class */
! 4146: ZEND_METHOD(reflection_class, implementsInterface)
! 4147: {
! 4148: reflection_object *intern, *argument;
! 4149: zend_class_entry *ce, *interface_ce, **pce;
! 4150: zval *interface;
! 4151:
! 4152: METHOD_NOTSTATIC(reflection_class_ptr);
! 4153: GET_REFLECTION_OBJECT_PTR(ce);
! 4154:
! 4155: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &interface) == FAILURE) {
! 4156: return;
! 4157: }
! 4158:
! 4159: switch(interface->type) {
! 4160: case IS_STRING:
! 4161: if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
! 4162: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4163: "Interface %s does not exist", Z_STRVAL_P(interface));
! 4164: return;
! 4165: }
! 4166: interface_ce = *pce;
! 4167: break;
! 4168: case IS_OBJECT:
! 4169: if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr TSRMLS_CC)) {
! 4170: argument = (reflection_object *) zend_object_store_get_object(interface TSRMLS_CC);
! 4171: if (argument == NULL || argument->ptr == NULL) {
! 4172: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
! 4173: /* Bails out */
! 4174: }
! 4175: interface_ce = argument->ptr;
! 4176: break;
! 4177: }
! 4178: /* no break */
! 4179: default:
! 4180: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4181: "Parameter one must either be a string or a ReflectionClass object");
! 4182: return;
! 4183: }
! 4184:
! 4185: if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
! 4186: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4187: "Interface %s is a Class", interface_ce->name);
! 4188: return;
! 4189: }
! 4190: RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC));
! 4191: }
! 4192: /* }}} */
! 4193:
! 4194: /* {{{ proto public bool ReflectionClass::isIterateable()
! 4195: Returns whether this class is iterateable (can be used inside foreach) */
! 4196: ZEND_METHOD(reflection_class, isIterateable)
! 4197: {
! 4198: reflection_object *intern;
! 4199: zend_class_entry *ce;
! 4200:
! 4201: if (zend_parse_parameters_none() == FAILURE) {
! 4202: return;
! 4203: }
! 4204:
! 4205: METHOD_NOTSTATIC(reflection_class_ptr);
! 4206: GET_REFLECTION_OBJECT_PTR(ce);
! 4207:
! 4208: RETURN_BOOL(ce->get_iterator != NULL);
! 4209: }
! 4210: /* }}} */
! 4211:
! 4212: /* {{{ proto public ReflectionExtension|NULL ReflectionClass::getExtension()
! 4213: Returns NULL or the extension the class belongs to */
! 4214: ZEND_METHOD(reflection_class, getExtension)
! 4215: {
! 4216: reflection_object *intern;
! 4217: zend_class_entry *ce;
! 4218:
! 4219: if (zend_parse_parameters_none() == FAILURE) {
! 4220: return;
! 4221: }
! 4222:
! 4223: METHOD_NOTSTATIC(reflection_class_ptr);
! 4224: GET_REFLECTION_OBJECT_PTR(ce);
! 4225:
! 4226: if (ce->module) {
! 4227: reflection_extension_factory(return_value, ce->module->name TSRMLS_CC);
! 4228: }
! 4229: }
! 4230: /* }}} */
! 4231:
! 4232: /* {{{ proto public string|false ReflectionClass::getExtensionName()
! 4233: Returns false or the name of the extension the class belongs to */
! 4234: ZEND_METHOD(reflection_class, getExtensionName)
! 4235: {
! 4236: reflection_object *intern;
! 4237: zend_class_entry *ce;
! 4238:
! 4239: if (zend_parse_parameters_none() == FAILURE) {
! 4240: return;
! 4241: }
! 4242:
! 4243: METHOD_NOTSTATIC(reflection_class_ptr);
! 4244: GET_REFLECTION_OBJECT_PTR(ce);
! 4245:
! 4246: if (ce->module) {
! 4247: RETURN_STRING(ce->module->name, 1);
! 4248: } else {
! 4249: RETURN_FALSE;
! 4250: }
! 4251: }
! 4252: /* }}} */
! 4253:
! 4254: /* {{{ proto public bool ReflectionClass::inNamespace()
! 4255: Returns whether this class is defined in namespace */
! 4256: ZEND_METHOD(reflection_class, inNamespace)
! 4257: {
! 4258: zval **name;
! 4259: char *colon;
! 4260:
! 4261: if (zend_parse_parameters_none() == FAILURE) {
! 4262: return;
! 4263: }
! 4264: if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
! 4265: RETURN_FALSE;
! 4266: }
! 4267: if (Z_TYPE_PP(name) == IS_STRING
! 4268: && (colon = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
! 4269: && colon > Z_STRVAL_PP(name))
! 4270: {
! 4271: RETURN_TRUE;
! 4272: }
! 4273: RETURN_FALSE;
! 4274: }
! 4275: /* }}} */
! 4276:
! 4277: /* {{{ proto public string ReflectionClass::getNamespaceName()
! 4278: Returns the name of namespace where this class is defined */
! 4279: ZEND_METHOD(reflection_class, getNamespaceName)
! 4280: {
! 4281: zval **name;
! 4282: char *backslash;
! 4283:
! 4284: if (zend_parse_parameters_none() == FAILURE) {
! 4285: return;
! 4286: }
! 4287: if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
! 4288: RETURN_FALSE;
! 4289: }
! 4290: if (Z_TYPE_PP(name) == IS_STRING
! 4291: && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
! 4292: && backslash > Z_STRVAL_PP(name))
! 4293: {
! 4294: RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1);
! 4295: }
! 4296: RETURN_EMPTY_STRING();
! 4297: }
! 4298: /* }}} */
! 4299:
! 4300: /* {{{ proto public string ReflectionClass::getShortName()
! 4301: Returns the short name of the class (without namespace part) */
! 4302: ZEND_METHOD(reflection_class, getShortName)
! 4303: {
! 4304: zval **name;
! 4305: char *backslash;
! 4306:
! 4307: if (zend_parse_parameters_none() == FAILURE) {
! 4308: return;
! 4309: }
! 4310: if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
! 4311: RETURN_FALSE;
! 4312: }
! 4313: if (Z_TYPE_PP(name) == IS_STRING
! 4314: && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
! 4315: && backslash > Z_STRVAL_PP(name))
! 4316: {
! 4317: RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1);
! 4318: }
! 4319: RETURN_ZVAL(*name, 1, 0);
! 4320: }
! 4321: /* }}} */
! 4322:
! 4323: /* {{{ proto public static mixed ReflectionObject::export(mixed argument [, bool return]) throws ReflectionException
! 4324: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 4325: ZEND_METHOD(reflection_object, export)
! 4326: {
! 4327: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1);
! 4328: }
! 4329: /* }}} */
! 4330:
! 4331: /* {{{ proto public void ReflectionObject::__construct(mixed argument) throws ReflectionException
! 4332: Constructor. Takes an instance as an argument */
! 4333: ZEND_METHOD(reflection_object, __construct)
! 4334: {
! 4335: reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
! 4336: }
! 4337: /* }}} */
! 4338:
! 4339: /* {{{ proto public static mixed ReflectionProperty::export(mixed class, string name [, bool return]) throws ReflectionException
! 4340: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 4341: ZEND_METHOD(reflection_property, export)
! 4342: {
! 4343: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2);
! 4344: }
! 4345: /* }}} */
! 4346:
! 4347: /* {{{ proto public void ReflectionProperty::__construct(mixed class, string name)
! 4348: Constructor. Throws an Exception in case the given property does not exist */
! 4349: ZEND_METHOD(reflection_property, __construct)
! 4350: {
! 4351: zval *propname, *classname;
! 4352: char *name_str, *class_name, *prop_name;
! 4353: int name_len, dynam_prop = 0;
! 4354: zval *object;
! 4355: reflection_object *intern;
! 4356: zend_class_entry **pce;
! 4357: zend_class_entry *ce;
! 4358: zend_property_info *property_info = NULL;
! 4359: property_reference *reference;
! 4360:
! 4361: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
! 4362: return;
! 4363: }
! 4364:
! 4365: object = getThis();
! 4366: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 4367: if (intern == NULL) {
! 4368: return;
! 4369: }
! 4370:
! 4371: /* Find the class entry */
! 4372: switch (Z_TYPE_P(classname)) {
! 4373: case IS_STRING:
! 4374: if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
! 4375: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4376: "Class %s does not exist", Z_STRVAL_P(classname));
! 4377: return;
! 4378: }
! 4379: ce = *pce;
! 4380: break;
! 4381:
! 4382: case IS_OBJECT:
! 4383: ce = Z_OBJCE_P(classname);
! 4384: break;
! 4385:
! 4386: default:
! 4387: _DO_THROW("The parameter class is expected to be either a string or an object");
! 4388: /* returns out of this function */
! 4389: }
! 4390:
! 4391: if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
! 4392: /* Check for dynamic properties */
! 4393: if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
! 4394: if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname TSRMLS_CC), name_str, name_len+1)) {
! 4395: dynam_prop = 1;
! 4396: }
! 4397: }
! 4398: if (dynam_prop == 0) {
! 4399: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Property %s::$%s does not exist", ce->name, name_str);
! 4400: return;
! 4401: }
! 4402: }
! 4403:
! 4404: if (dynam_prop == 0 && (property_info->flags & ZEND_ACC_PRIVATE) == 0) {
! 4405: /* we have to search the class hierarchy for this (implicit) public or protected property */
! 4406: zend_class_entry *tmp_ce = ce;
! 4407: zend_property_info *tmp_info;
! 4408:
! 4409: while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, name_str, name_len + 1, (void **) &tmp_info) != SUCCESS) {
! 4410: ce = tmp_ce;
! 4411: property_info = tmp_info;
! 4412: tmp_ce = tmp_ce->parent;
! 4413: }
! 4414: }
! 4415:
! 4416: MAKE_STD_ZVAL(classname);
! 4417: MAKE_STD_ZVAL(propname);
! 4418:
! 4419: if (dynam_prop == 0) {
! 4420: zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
! 4421: ZVAL_STRINGL(classname, property_info->ce->name, property_info->ce->name_length, 1);
! 4422: ZVAL_STRING(propname, prop_name, 1);
! 4423: } else {
! 4424: ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
! 4425: ZVAL_STRINGL(propname, name_str, name_len, 1);
! 4426: }
! 4427: zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
! 4428: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL);
! 4429:
! 4430: reference = (property_reference*) emalloc(sizeof(property_reference));
! 4431: if (dynam_prop) {
! 4432: reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC;
! 4433: reference->prop.name = Z_STRVAL_P(propname);
! 4434: reference->prop.name_length = Z_STRLEN_P(propname);
! 4435: reference->prop.h = zend_get_hash_value(name_str, name_len+1);
! 4436: reference->prop.doc_comment = NULL;
! 4437: reference->prop.ce = ce;
! 4438: } else {
! 4439: reference->prop = *property_info;
! 4440: }
! 4441: reference->ce = ce;
! 4442: intern->ptr = reference;
! 4443: intern->ref_type = REF_TYPE_PROPERTY;
! 4444: intern->ce = ce;
! 4445: intern->ignore_visibility = 0;
! 4446: }
! 4447: /* }}} */
! 4448:
! 4449: /* {{{ proto public string ReflectionProperty::__toString()
! 4450: Returns a string representation */
! 4451: ZEND_METHOD(reflection_property, __toString)
! 4452: {
! 4453: reflection_object *intern;
! 4454: property_reference *ref;
! 4455: string str;
! 4456:
! 4457: if (zend_parse_parameters_none() == FAILURE) {
! 4458: return;
! 4459: }
! 4460: GET_REFLECTION_OBJECT_PTR(ref);
! 4461: string_init(&str);
! 4462: _property_string(&str, &ref->prop, NULL, "" TSRMLS_CC);
! 4463: RETURN_STRINGL(str.string, str.len - 1, 0);
! 4464: }
! 4465: /* }}} */
! 4466:
! 4467: /* {{{ proto public string ReflectionProperty::getName()
! 4468: Returns the class' name */
! 4469: ZEND_METHOD(reflection_property, getName)
! 4470: {
! 4471: if (zend_parse_parameters_none() == FAILURE) {
! 4472: return;
! 4473: }
! 4474: _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
! 4475: }
! 4476: /* }}} */
! 4477:
! 4478: static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
! 4479: {
! 4480: reflection_object *intern;
! 4481: property_reference *ref;
! 4482:
! 4483: if (zend_parse_parameters_none() == FAILURE) {
! 4484: return;
! 4485: }
! 4486: GET_REFLECTION_OBJECT_PTR(ref);
! 4487: RETURN_BOOL(ref->prop.flags & mask);
! 4488: }
! 4489:
! 4490: /* {{{ proto public bool ReflectionProperty::isPublic()
! 4491: Returns whether this property is public */
! 4492: ZEND_METHOD(reflection_property, isPublic)
! 4493: {
! 4494: _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
! 4495: }
! 4496: /* }}} */
! 4497:
! 4498: /* {{{ proto public bool ReflectionProperty::isPrivate()
! 4499: Returns whether this property is private */
! 4500: ZEND_METHOD(reflection_property, isPrivate)
! 4501: {
! 4502: _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
! 4503: }
! 4504: /* }}} */
! 4505:
! 4506: /* {{{ proto public bool ReflectionProperty::isProtected()
! 4507: Returns whether this property is protected */
! 4508: ZEND_METHOD(reflection_property, isProtected)
! 4509: {
! 4510: _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
! 4511: }
! 4512: /* }}} */
! 4513:
! 4514: /* {{{ proto public bool ReflectionProperty::isStatic()
! 4515: Returns whether this property is static */
! 4516: ZEND_METHOD(reflection_property, isStatic)
! 4517: {
! 4518: _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
! 4519: }
! 4520: /* }}} */
! 4521:
! 4522: /* {{{ proto public bool ReflectionProperty::isDefault()
! 4523: Returns whether this property is default (declared at compilation time). */
! 4524: ZEND_METHOD(reflection_property, isDefault)
! 4525: {
! 4526: _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC);
! 4527: }
! 4528: /* }}} */
! 4529:
! 4530: /* {{{ proto public int ReflectionProperty::getModifiers()
! 4531: Returns a bitfield of the access modifiers for this property */
! 4532: ZEND_METHOD(reflection_property, getModifiers)
! 4533: {
! 4534: reflection_object *intern;
! 4535: property_reference *ref;
! 4536:
! 4537: if (zend_parse_parameters_none() == FAILURE) {
! 4538: return;
! 4539: }
! 4540: GET_REFLECTION_OBJECT_PTR(ref);
! 4541:
! 4542: RETURN_LONG(ref->prop.flags);
! 4543: }
! 4544: /* }}} */
! 4545:
! 4546: /* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
! 4547: Returns this property's value */
! 4548: ZEND_METHOD(reflection_property, getValue)
! 4549: {
! 4550: reflection_object *intern;
! 4551: property_reference *ref;
! 4552: zval *object, name;
! 4553: zval **member = NULL, *member_p = NULL;
! 4554:
! 4555: METHOD_NOTSTATIC(reflection_property_ptr);
! 4556: GET_REFLECTION_OBJECT_PTR(ref);
! 4557:
! 4558: if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) {
! 4559: _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
! 4560: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4561: "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
! 4562: zval_dtor(&name);
! 4563: return;
! 4564: }
! 4565:
! 4566: if ((ref->prop.flags & ZEND_ACC_STATIC)) {
! 4567: zend_update_class_constants(intern->ce TSRMLS_CC);
! 4568: if (zend_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &member) == FAILURE) {
! 4569: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
! 4570: /* Bails out */
! 4571: }
! 4572: MAKE_COPY_ZVAL(member, return_value);
! 4573: } else {
! 4574: char *class_name, *prop_name;
! 4575:
! 4576: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
! 4577: return;
! 4578: }
! 4579: zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
! 4580: member_p = zend_read_property(ref->ce, object, prop_name, strlen(prop_name), 1 TSRMLS_CC);
! 4581: MAKE_COPY_ZVAL(&member_p, return_value);
! 4582: if (member_p != EG(uninitialized_zval_ptr)) {
! 4583: zval_add_ref(&member_p);
! 4584: zval_ptr_dtor(&member_p);
! 4585: }
! 4586: }
! 4587: }
! 4588: /* }}} */
! 4589:
! 4590: /* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value)
! 4591: Sets this property's value */
! 4592: ZEND_METHOD(reflection_property, setValue)
! 4593: {
! 4594: reflection_object *intern;
! 4595: property_reference *ref;
! 4596: zval **variable_ptr;
! 4597: zval *object, name;
! 4598: zval *value;
! 4599: int setter_done = 0;
! 4600: zval *tmp;
! 4601: HashTable *prop_table;
! 4602:
! 4603: METHOD_NOTSTATIC(reflection_property_ptr);
! 4604: GET_REFLECTION_OBJECT_PTR(ref);
! 4605:
! 4606: if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
! 4607: _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
! 4608: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4609: "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
! 4610: zval_dtor(&name);
! 4611: return;
! 4612: }
! 4613:
! 4614: if ((ref->prop.flags & ZEND_ACC_STATIC)) {
! 4615: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
! 4616: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &tmp, &value) == FAILURE) {
! 4617: return;
! 4618: }
! 4619: }
! 4620: zend_update_class_constants(intern->ce TSRMLS_CC);
! 4621: prop_table = CE_STATIC_MEMBERS(intern->ce);
! 4622:
! 4623: if (zend_hash_quick_find(prop_table, ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &variable_ptr) == FAILURE) {
! 4624: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
! 4625: /* Bails out */
! 4626: }
! 4627: if (*variable_ptr == value) {
! 4628: setter_done = 1;
! 4629: } else {
! 4630: if (PZVAL_IS_REF(*variable_ptr)) {
! 4631: zval_dtor(*variable_ptr);
! 4632: (*variable_ptr)->type = value->type;
! 4633: (*variable_ptr)->value = value->value;
! 4634: if (Z_REFCOUNT_P(value) > 0) {
! 4635: zval_copy_ctor(*variable_ptr);
! 4636: }
! 4637: setter_done = 1;
! 4638: }
! 4639: }
! 4640: if (!setter_done) {
! 4641: zval **foo;
! 4642:
! 4643: Z_ADDREF_P(value);
! 4644: if (PZVAL_IS_REF(value)) {
! 4645: SEPARATE_ZVAL(&value);
! 4646: }
! 4647: zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo);
! 4648: }
! 4649: } else {
! 4650: char *class_name, *prop_name;
! 4651:
! 4652: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
! 4653: return;
! 4654: }
! 4655: zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
! 4656: zend_update_property(ref->ce, object, prop_name, strlen(prop_name), value TSRMLS_CC);
! 4657: }
! 4658: }
! 4659: /* }}} */
! 4660:
! 4661: /* {{{ proto public ReflectionClass ReflectionProperty::getDeclaringClass()
! 4662: Get the declaring class */
! 4663: ZEND_METHOD(reflection_property, getDeclaringClass)
! 4664: {
! 4665: reflection_object *intern;
! 4666: property_reference *ref;
! 4667: zend_class_entry *tmp_ce, *ce;
! 4668: zend_property_info *tmp_info;
! 4669: char *prop_name, *class_name;
! 4670: int prop_name_len;
! 4671:
! 4672: if (zend_parse_parameters_none() == FAILURE) {
! 4673: return;
! 4674: }
! 4675: GET_REFLECTION_OBJECT_PTR(ref);
! 4676:
! 4677: if (zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name) != SUCCESS) {
! 4678: RETURN_FALSE;
! 4679: }
! 4680:
! 4681: prop_name_len = strlen(prop_name);
! 4682: ce = tmp_ce = ref->ce;
! 4683: while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, prop_name_len + 1, (void **) &tmp_info) == SUCCESS) {
! 4684: if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
! 4685: /* it's a private property, so it can't be inherited */
! 4686: break;
! 4687: }
! 4688: ce = tmp_ce;
! 4689: if (tmp_ce == tmp_info->ce) {
! 4690: /* declared in this class, done */
! 4691: break;
! 4692: }
! 4693: tmp_ce = tmp_ce->parent;
! 4694: }
! 4695:
! 4696: zend_reflection_class_factory(ce, return_value TSRMLS_CC);
! 4697: }
! 4698: /* }}} */
! 4699:
! 4700: /* {{{ proto public string ReflectionProperty::getDocComment()
! 4701: Returns the doc comment for this property */
! 4702: ZEND_METHOD(reflection_property, getDocComment)
! 4703: {
! 4704: reflection_object *intern;
! 4705: property_reference *ref;
! 4706:
! 4707: if (zend_parse_parameters_none() == FAILURE) {
! 4708: return;
! 4709: }
! 4710: GET_REFLECTION_OBJECT_PTR(ref);
! 4711: if (ref->prop.doc_comment) {
! 4712: RETURN_STRINGL(ref->prop.doc_comment, ref->prop.doc_comment_len, 1);
! 4713: }
! 4714: RETURN_FALSE;
! 4715: }
! 4716: /* }}} */
! 4717:
! 4718: /* {{{ proto public int ReflectionProperty::setAccessible(bool visible)
! 4719: Sets whether non-public properties can be requested */
! 4720: ZEND_METHOD(reflection_property, setAccessible)
! 4721: {
! 4722: reflection_object *intern;
! 4723: zend_bool visible;
! 4724:
! 4725: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
! 4726: return;
! 4727: }
! 4728:
! 4729: intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
! 4730:
! 4731: if (intern == NULL) {
! 4732: return;
! 4733: }
! 4734:
! 4735: intern->ignore_visibility = visible;
! 4736: }
! 4737: /* }}} */
! 4738:
! 4739: /* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException
! 4740: Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
! 4741: ZEND_METHOD(reflection_extension, export)
! 4742: {
! 4743: _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1);
! 4744: }
! 4745: /* }}} */
! 4746:
! 4747: /* {{{ proto public void ReflectionExtension::__construct(string name)
! 4748: Constructor. Throws an Exception in case the given extension does not exist */
! 4749: ZEND_METHOD(reflection_extension, __construct)
! 4750: {
! 4751: zval *name;
! 4752: zval *object;
! 4753: char *lcname;
! 4754: reflection_object *intern;
! 4755: zend_module_entry *module;
! 4756: char *name_str;
! 4757: int name_len;
! 4758: ALLOCA_FLAG(use_heap)
! 4759:
! 4760: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
! 4761: return;
! 4762: }
! 4763:
! 4764: object = getThis();
! 4765: intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
! 4766: if (intern == NULL) {
! 4767: return;
! 4768: }
! 4769: lcname = do_alloca(name_len + 1, use_heap);
! 4770: zend_str_tolower_copy(lcname, name_str, name_len);
! 4771: if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
! 4772: free_alloca(lcname, use_heap);
! 4773: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 4774: "Extension %s does not exist", name_str);
! 4775: return;
! 4776: }
! 4777: free_alloca(lcname, use_heap);
! 4778: MAKE_STD_ZVAL(name);
! 4779: ZVAL_STRING(name, module->name, 1);
! 4780: zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
! 4781: intern->ptr = module;
! 4782: intern->ref_type = REF_TYPE_OTHER;
! 4783: intern->ce = NULL;
! 4784: }
! 4785: /* }}} */
! 4786:
! 4787: /* {{{ proto public string ReflectionExtension::__toString()
! 4788: Returns a string representation */
! 4789: ZEND_METHOD(reflection_extension, __toString)
! 4790: {
! 4791: reflection_object *intern;
! 4792: zend_module_entry *module;
! 4793: string str;
! 4794:
! 4795: if (zend_parse_parameters_none() == FAILURE) {
! 4796: return;
! 4797: }
! 4798: GET_REFLECTION_OBJECT_PTR(module);
! 4799: string_init(&str);
! 4800: _extension_string(&str, module, "" TSRMLS_CC);
! 4801: RETURN_STRINGL(str.string, str.len - 1, 0);
! 4802: }
! 4803: /* }}} */
! 4804:
! 4805: /* {{{ proto public string ReflectionExtension::getName()
! 4806: Returns this extension's name */
! 4807: ZEND_METHOD(reflection_extension, getName)
! 4808: {
! 4809: if (zend_parse_parameters_none() == FAILURE) {
! 4810: return;
! 4811: }
! 4812: _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
! 4813: }
! 4814: /* }}} */
! 4815:
! 4816: /* {{{ proto public string ReflectionExtension::getVersion()
! 4817: Returns this extension's version */
! 4818: ZEND_METHOD(reflection_extension, getVersion)
! 4819: {
! 4820: reflection_object *intern;
! 4821: zend_module_entry *module;
! 4822:
! 4823: if (zend_parse_parameters_none() == FAILURE) {
! 4824: return;
! 4825: }
! 4826: GET_REFLECTION_OBJECT_PTR(module);
! 4827:
! 4828: /* An extension does not necessarily have a version number */
! 4829: if (module->version == NO_VERSION_YET) {
! 4830: RETURN_NULL();
! 4831: } else {
! 4832: RETURN_STRING(module->version, 1);
! 4833: }
! 4834: }
! 4835: /* }}} */
! 4836:
! 4837: /* {{{ proto public ReflectionFunction[] ReflectionExtension::getFunctions()
! 4838: Returns an array of this extension's fuctions */
! 4839: ZEND_METHOD(reflection_extension, getFunctions)
! 4840: {
! 4841: reflection_object *intern;
! 4842: zend_module_entry *module;
! 4843:
! 4844: if (zend_parse_parameters_none() == FAILURE) {
! 4845: return;
! 4846: }
! 4847: GET_REFLECTION_OBJECT_PTR(module);
! 4848:
! 4849: array_init(return_value);
! 4850: if (module->functions) {
! 4851: zval *function;
! 4852: zend_function *fptr;
! 4853: const zend_function_entry *func = module->functions;
! 4854:
! 4855: /* Is there a better way of doing this? */
! 4856: while (func->fname) {
! 4857: int fname_len = strlen(func->fname);
! 4858: char *lc_name = zend_str_tolower_dup(func->fname, fname_len);
! 4859:
! 4860: if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) {
! 4861: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
! 4862: func++;
! 4863: efree(lc_name);
! 4864: continue;
! 4865: }
! 4866:
! 4867: ALLOC_ZVAL(function);
! 4868: reflection_function_factory(fptr, NULL, function TSRMLS_CC);
! 4869: add_assoc_zval_ex(return_value, func->fname, fname_len+1, function);
! 4870: func++;
! 4871: efree(lc_name);
! 4872: }
! 4873: }
! 4874: }
! 4875: /* }}} */
! 4876:
! 4877: static int _addconstant(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 4878: {
! 4879: zval *const_val;
! 4880: zval *retval = va_arg(args, zval*);
! 4881: int number = va_arg(args, int);
! 4882:
! 4883: if (number == constant->module_number) {
! 4884: ALLOC_ZVAL(const_val);
! 4885: *const_val = constant->value;
! 4886: zval_copy_ctor(const_val);
! 4887: INIT_PZVAL(const_val);
! 4888: add_assoc_zval_ex(retval, constant->name, constant->name_len, const_val);
! 4889: }
! 4890: return 0;
! 4891: }
! 4892:
! 4893: /* {{{ proto public array ReflectionExtension::getConstants()
! 4894: Returns an associative array containing this extension's constants and their values */
! 4895: ZEND_METHOD(reflection_extension, getConstants)
! 4896: {
! 4897: reflection_object *intern;
! 4898: zend_module_entry *module;
! 4899:
! 4900: if (zend_parse_parameters_none() == FAILURE) {
! 4901: return;
! 4902: }
! 4903: GET_REFLECTION_OBJECT_PTR(module);
! 4904:
! 4905: array_init(return_value);
! 4906: zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _addconstant, 2, return_value, module->module_number);
! 4907: }
! 4908: /* }}} */
! 4909:
! 4910: /* {{{ _addinientry */
! 4911: static int _addinientry(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 4912: {
! 4913: zval *retval = va_arg(args, zval*);
! 4914: int number = va_arg(args, int);
! 4915:
! 4916: if (number == ini_entry->module_number) {
! 4917: if (ini_entry->value) {
! 4918: add_assoc_stringl(retval, ini_entry->name, ini_entry->value, ini_entry->value_length, 1);
! 4919: } else {
! 4920: add_assoc_null(retval, ini_entry->name);
! 4921: }
! 4922: }
! 4923: return ZEND_HASH_APPLY_KEEP;
! 4924: }
! 4925: /* }}} */
! 4926:
! 4927: /* {{{ proto public array ReflectionExtension::getINIEntries()
! 4928: Returns an associative array containing this extension's INI entries and their values */
! 4929: ZEND_METHOD(reflection_extension, getINIEntries)
! 4930: {
! 4931: reflection_object *intern;
! 4932: zend_module_entry *module;
! 4933:
! 4934: if (zend_parse_parameters_none() == FAILURE) {
! 4935: return;
! 4936: }
! 4937: GET_REFLECTION_OBJECT_PTR(module);
! 4938:
! 4939: array_init(return_value);
! 4940: zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _addinientry, 2, return_value, module->module_number);
! 4941: }
! 4942: /* }}} */
! 4943:
! 4944: /* {{{ add_extension_class */
! 4945: static int add_extension_class(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
! 4946: {
! 4947: zval *class_array = va_arg(args, zval*), *zclass;
! 4948: struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
! 4949: int add_reflection_class = va_arg(args, int);
! 4950:
! 4951: if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
! 4952: if (add_reflection_class) {
! 4953: ALLOC_ZVAL(zclass);
! 4954: zend_reflection_class_factory(*pce, zclass TSRMLS_CC);
! 4955: add_assoc_zval_ex(class_array, (*pce)->name, (*pce)->name_length + 1, zclass);
! 4956: } else {
! 4957: add_next_index_stringl(class_array, (*pce)->name, (*pce)->name_length, 1);
! 4958: }
! 4959: }
! 4960: return ZEND_HASH_APPLY_KEEP;
! 4961: }
! 4962: /* }}} */
! 4963:
! 4964: /* {{{ proto public ReflectionClass[] ReflectionExtension::getClasses()
! 4965: Returns an array containing ReflectionClass objects for all classes of this extension */
! 4966: ZEND_METHOD(reflection_extension, getClasses)
! 4967: {
! 4968: reflection_object *intern;
! 4969: zend_module_entry *module;
! 4970:
! 4971: if (zend_parse_parameters_none() == FAILURE) {
! 4972: return;
! 4973: }
! 4974: GET_REFLECTION_OBJECT_PTR(module);
! 4975:
! 4976: array_init(return_value);
! 4977: zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 1);
! 4978: }
! 4979: /* }}} */
! 4980:
! 4981: /* {{{ proto public array ReflectionExtension::getClassNames()
! 4982: Returns an array containing all names of all classes of this extension */
! 4983: ZEND_METHOD(reflection_extension, getClassNames)
! 4984: {
! 4985: reflection_object *intern;
! 4986: zend_module_entry *module;
! 4987:
! 4988: if (zend_parse_parameters_none() == FAILURE) {
! 4989: return;
! 4990: }
! 4991: GET_REFLECTION_OBJECT_PTR(module);
! 4992:
! 4993: array_init(return_value);
! 4994: zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 0);
! 4995: }
! 4996: /* }}} */
! 4997:
! 4998: /* {{{ proto public array ReflectionExtension::getDependencies()
! 4999: Returns an array containing all names of all extensions this extension depends on */
! 5000: ZEND_METHOD(reflection_extension, getDependencies)
! 5001: {
! 5002: reflection_object *intern;
! 5003: zend_module_entry *module;
! 5004: const zend_module_dep *dep;
! 5005:
! 5006: if (zend_parse_parameters_none() == FAILURE) {
! 5007: return;
! 5008: }
! 5009: GET_REFLECTION_OBJECT_PTR(module);
! 5010:
! 5011: array_init(return_value);
! 5012:
! 5013: dep = module->deps;
! 5014:
! 5015: if (!dep)
! 5016: {
! 5017: return;
! 5018: }
! 5019:
! 5020: while(dep->name) {
! 5021: char *relation;
! 5022: char *rel_type;
! 5023: int len;
! 5024:
! 5025: switch(dep->type) {
! 5026: case MODULE_DEP_REQUIRED:
! 5027: rel_type = "Required";
! 5028: break;
! 5029: case MODULE_DEP_CONFLICTS:
! 5030: rel_type = "Conflicts";
! 5031: break;
! 5032: case MODULE_DEP_OPTIONAL:
! 5033: rel_type = "Optional";
! 5034: break;
! 5035: default:
! 5036: rel_type = "Error"; /* shouldn't happen */
! 5037: break;
! 5038: }
! 5039:
! 5040: len = spprintf(&relation, 0, "%s%s%s%s%s",
! 5041: rel_type,
! 5042: dep->rel ? " " : "",
! 5043: dep->rel ? dep->rel : "",
! 5044: dep->version ? " " : "",
! 5045: dep->version ? dep->version : "");
! 5046: add_assoc_stringl(return_value, dep->name, relation, len, 0);
! 5047: dep++;
! 5048: }
! 5049: }
! 5050: /* }}} */
! 5051:
! 5052: /* {{{ proto public void ReflectionExtension::info() U
! 5053: Prints phpinfo block for the extension */
! 5054: ZEND_METHOD(reflection_extension, info)
! 5055: {
! 5056: reflection_object *intern;
! 5057: zend_module_entry *module;
! 5058:
! 5059: if (zend_parse_parameters_none() == FAILURE) {
! 5060: return;
! 5061: }
! 5062: GET_REFLECTION_OBJECT_PTR(module);
! 5063:
! 5064: php_info_print_module(module TSRMLS_CC);
! 5065: }
! 5066: /* }}} */
! 5067:
! 5068: /* {{{ method tables */
! 5069: static const zend_function_entry reflection_exception_functions[] = {
! 5070: PHP_FE_END
! 5071: };
! 5072:
! 5073: ZEND_BEGIN_ARG_INFO(arginfo_reflection__void, 0)
! 5074: ZEND_END_ARG_INFO()
! 5075:
! 5076:
! 5077: ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0)
! 5078: ZEND_ARG_INFO(0, modifiers)
! 5079: ZEND_END_ARG_INFO()
! 5080:
! 5081: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1)
! 5082: ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0)
! 5083: ZEND_ARG_INFO(0, return)
! 5084: ZEND_END_ARG_INFO()
! 5085:
! 5086: static const zend_function_entry reflection_functions[] = {
! 5087: ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 5088: ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 5089: PHP_FE_END
! 5090: };
! 5091:
! 5092: static const zend_function_entry reflector_functions[] = {
! 5093: ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
! 5094: ZEND_ABSTRACT_ME(reflector, __toString, arginfo_reflection__void)
! 5095: PHP_FE_END
! 5096: };
! 5097:
! 5098: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1)
! 5099: ZEND_ARG_INFO(0, name)
! 5100: ZEND_ARG_INFO(0, return)
! 5101: ZEND_END_ARG_INFO()
! 5102:
! 5103: ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
! 5104: ZEND_ARG_INFO(0, name)
! 5105: ZEND_END_ARG_INFO()
! 5106:
! 5107: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0)
! 5108: ZEND_ARG_INFO(0, args)
! 5109: ZEND_END_ARG_INFO()
! 5110:
! 5111: ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0)
! 5112: ZEND_ARG_ARRAY_INFO(0, args, 0)
! 5113: ZEND_END_ARG_INFO()
! 5114:
! 5115: static const zend_function_entry reflection_function_abstract_functions[] = {
! 5116: ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
! 5117: PHP_ABSTRACT_ME(reflection_function, __toString, arginfo_reflection__void)
! 5118: ZEND_ME(reflection_function, inNamespace, arginfo_reflection__void, 0)
! 5119: ZEND_ME(reflection_function, isClosure, arginfo_reflection__void, 0)
! 5120: ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
! 5121: ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
! 5122: ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
! 5123: ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
! 5124: ZEND_ME(reflection_function, getEndLine, arginfo_reflection__void, 0)
! 5125: ZEND_ME(reflection_function, getExtension, arginfo_reflection__void, 0)
! 5126: ZEND_ME(reflection_function, getExtensionName, arginfo_reflection__void, 0)
! 5127: ZEND_ME(reflection_function, getFileName, arginfo_reflection__void, 0)
! 5128: ZEND_ME(reflection_function, getName, arginfo_reflection__void, 0)
! 5129: ZEND_ME(reflection_function, getNamespaceName, arginfo_reflection__void, 0)
! 5130: ZEND_ME(reflection_function, getNumberOfParameters, arginfo_reflection__void, 0)
! 5131: ZEND_ME(reflection_function, getNumberOfRequiredParameters, arginfo_reflection__void, 0)
! 5132: ZEND_ME(reflection_function, getParameters, arginfo_reflection__void, 0)
! 5133: ZEND_ME(reflection_function, getShortName, arginfo_reflection__void, 0)
! 5134: ZEND_ME(reflection_function, getStartLine, arginfo_reflection__void, 0)
! 5135: ZEND_ME(reflection_function, getStaticVariables, arginfo_reflection__void, 0)
! 5136: ZEND_ME(reflection_function, returnsReference, arginfo_reflection__void, 0)
! 5137: PHP_FE_END
! 5138: };
! 5139:
! 5140: static const zend_function_entry reflection_function_functions[] = {
! 5141: ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0)
! 5142: ZEND_ME(reflection_function, __toString, arginfo_reflection__void, 0)
! 5143: ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5144: ZEND_ME(reflection_function, isDisabled, arginfo_reflection__void, 0)
! 5145: ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
! 5146: ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
! 5147: PHP_FE_END
! 5148: };
! 5149:
! 5150: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2)
! 5151: ZEND_ARG_INFO(0, class)
! 5152: ZEND_ARG_INFO(0, name)
! 5153: ZEND_ARG_INFO(0, return)
! 5154: ZEND_END_ARG_INFO()
! 5155:
! 5156: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1)
! 5157: ZEND_ARG_INFO(0, class_or_method)
! 5158: ZEND_ARG_INFO(0, name)
! 5159: ZEND_END_ARG_INFO()
! 5160:
! 5161: ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0)
! 5162: ZEND_ARG_INFO(0, object)
! 5163: ZEND_ARG_INFO(0, args)
! 5164: ZEND_END_ARG_INFO()
! 5165:
! 5166: ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0)
! 5167: ZEND_ARG_INFO(0, object)
! 5168: ZEND_ARG_ARRAY_INFO(0, args, 0)
! 5169: ZEND_END_ARG_INFO()
! 5170:
! 5171: ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
! 5172: ZEND_ARG_INFO(0, value)
! 5173: ZEND_END_ARG_INFO()
! 5174:
! 5175: static const zend_function_entry reflection_method_functions[] = {
! 5176: ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5177: ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
! 5178: ZEND_ME(reflection_method, __toString, arginfo_reflection__void, 0)
! 5179: ZEND_ME(reflection_method, isPublic, arginfo_reflection__void, 0)
! 5180: ZEND_ME(reflection_method, isPrivate, arginfo_reflection__void, 0)
! 5181: ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0)
! 5182: ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0)
! 5183: ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0)
! 5184: ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0)
! 5185: ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0)
! 5186: ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0)
! 5187: ZEND_ME(reflection_method, getModifiers, arginfo_reflection__void, 0)
! 5188: ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
! 5189: ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
! 5190: ZEND_ME(reflection_method, getDeclaringClass, arginfo_reflection__void, 0)
! 5191: ZEND_ME(reflection_method, getPrototype, arginfo_reflection__void, 0)
! 5192: ZEND_ME(reflection_property, setAccessible, arginfo_reflection_method_setAccessible, 0)
! 5193: PHP_FE_END
! 5194: };
! 5195:
! 5196:
! 5197: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1)
! 5198: ZEND_ARG_INFO(0, argument)
! 5199: ZEND_ARG_INFO(0, return)
! 5200: ZEND_END_ARG_INFO()
! 5201:
! 5202: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0)
! 5203: ZEND_ARG_INFO(0, argument)
! 5204: ZEND_END_ARG_INFO()
! 5205:
! 5206: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1)
! 5207: ZEND_ARG_INFO(0, name)
! 5208: ZEND_ARG_INFO(0, default)
! 5209: ZEND_END_ARG_INFO()
! 5210:
! 5211: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0)
! 5212: ZEND_ARG_INFO(0, name)
! 5213: ZEND_ARG_INFO(0, value)
! 5214: ZEND_END_ARG_INFO()
! 5215:
! 5216: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0)
! 5217: ZEND_ARG_INFO(0, name)
! 5218: ZEND_END_ARG_INFO()
! 5219:
! 5220: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0)
! 5221: ZEND_ARG_INFO(0, name)
! 5222: ZEND_END_ARG_INFO()
! 5223:
! 5224: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0)
! 5225: ZEND_ARG_INFO(0, filter)
! 5226: ZEND_END_ARG_INFO()
! 5227:
! 5228: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0)
! 5229: ZEND_ARG_INFO(0, name)
! 5230: ZEND_END_ARG_INFO()
! 5231:
! 5232: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0)
! 5233: ZEND_ARG_INFO(0, name)
! 5234: ZEND_END_ARG_INFO()
! 5235:
! 5236: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0)
! 5237: ZEND_ARG_INFO(0, filter)
! 5238: ZEND_END_ARG_INFO()
! 5239:
! 5240: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0)
! 5241: ZEND_ARG_INFO(0, name)
! 5242: ZEND_END_ARG_INFO()
! 5243:
! 5244: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0)
! 5245: ZEND_ARG_INFO(0, name)
! 5246: ZEND_END_ARG_INFO()
! 5247:
! 5248: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
! 5249: ZEND_ARG_INFO(0, object)
! 5250: ZEND_END_ARG_INFO()
! 5251:
! 5252: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
! 5253: ZEND_ARG_INFO(0, args)
! 5254: ZEND_END_ARG_INFO()
! 5255:
! 5256: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0)
! 5257: ZEND_ARG_ARRAY_INFO(0, args, 0)
! 5258: ZEND_END_ARG_INFO()
! 5259:
! 5260: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0)
! 5261: ZEND_ARG_INFO(0, class)
! 5262: ZEND_END_ARG_INFO()
! 5263:
! 5264: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0)
! 5265: ZEND_ARG_INFO(0, interface)
! 5266: ZEND_END_ARG_INFO()
! 5267:
! 5268: static const zend_function_entry reflection_class_functions[] = {
! 5269: ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
! 5270: ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5271: ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0)
! 5272: ZEND_ME(reflection_class, __toString, arginfo_reflection__void, 0)
! 5273: ZEND_ME(reflection_class, getName, arginfo_reflection__void, 0)
! 5274: ZEND_ME(reflection_class, isInternal, arginfo_reflection__void, 0)
! 5275: ZEND_ME(reflection_class, isUserDefined, arginfo_reflection__void, 0)
! 5276: ZEND_ME(reflection_class, isInstantiable, arginfo_reflection__void, 0)
! 5277: ZEND_ME(reflection_class, getFileName, arginfo_reflection__void, 0)
! 5278: ZEND_ME(reflection_class, getStartLine, arginfo_reflection__void, 0)
! 5279: ZEND_ME(reflection_class, getEndLine, arginfo_reflection__void, 0)
! 5280: ZEND_ME(reflection_class, getDocComment, arginfo_reflection__void, 0)
! 5281: ZEND_ME(reflection_class, getConstructor, arginfo_reflection__void, 0)
! 5282: ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0)
! 5283: ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0)
! 5284: ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0)
! 5285: ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0)
! 5286: ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0)
! 5287: ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0)
! 5288: ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0)
! 5289: ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0)
! 5290: ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0)
! 5291: ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0)
! 5292: ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0)
! 5293: ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0)
! 5294: ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0)
! 5295: ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0)
! 5296: ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0)
! 5297: ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0)
! 5298: ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0)
! 5299: ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0)
! 5300: ZEND_ME(reflection_class, getParentClass, arginfo_reflection__void, 0)
! 5301: ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0)
! 5302: ZEND_ME(reflection_class, getStaticProperties, arginfo_reflection__void, 0)
! 5303: ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0)
! 5304: ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0)
! 5305: ZEND_ME(reflection_class, getDefaultProperties, arginfo_reflection__void, 0)
! 5306: ZEND_ME(reflection_class, isIterateable, arginfo_reflection__void, 0)
! 5307: ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0)
! 5308: ZEND_ME(reflection_class, getExtension, arginfo_reflection__void, 0)
! 5309: ZEND_ME(reflection_class, getExtensionName, arginfo_reflection__void, 0)
! 5310: ZEND_ME(reflection_class, inNamespace, arginfo_reflection__void, 0)
! 5311: ZEND_ME(reflection_class, getNamespaceName, arginfo_reflection__void, 0)
! 5312: ZEND_ME(reflection_class, getShortName, arginfo_reflection__void, 0)
! 5313: PHP_FE_END
! 5314: };
! 5315:
! 5316:
! 5317: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1)
! 5318: ZEND_ARG_INFO(0, argument)
! 5319: ZEND_ARG_INFO(0, return)
! 5320: ZEND_END_ARG_INFO()
! 5321:
! 5322: ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0)
! 5323: ZEND_ARG_INFO(0, argument)
! 5324: ZEND_END_ARG_INFO()
! 5325:
! 5326: static const zend_function_entry reflection_object_functions[] = {
! 5327: ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5328: ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0)
! 5329: PHP_FE_END
! 5330: };
! 5331:
! 5332:
! 5333: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 2)
! 5334: ZEND_ARG_INFO(0, class)
! 5335: ZEND_ARG_INFO(0, name)
! 5336: ZEND_ARG_INFO(0, return)
! 5337: ZEND_END_ARG_INFO()
! 5338:
! 5339: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property___construct, 0, 0, 2)
! 5340: ZEND_ARG_INFO(0, class)
! 5341: ZEND_ARG_INFO(0, name)
! 5342: ZEND_END_ARG_INFO()
! 5343:
! 5344: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_getValue, 0, 0, 0)
! 5345: ZEND_ARG_INFO(0, object)
! 5346: ZEND_END_ARG_INFO()
! 5347:
! 5348: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1)
! 5349: ZEND_ARG_INFO(0, object)
! 5350: ZEND_ARG_INFO(0, value)
! 5351: ZEND_END_ARG_INFO()
! 5352:
! 5353: ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setAccessible, 0)
! 5354: ZEND_ARG_INFO(0, visible)
! 5355: ZEND_END_ARG_INFO()
! 5356:
! 5357: static const zend_function_entry reflection_property_functions[] = {
! 5358: ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
! 5359: ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5360: ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0)
! 5361: ZEND_ME(reflection_property, __toString, arginfo_reflection__void, 0)
! 5362: ZEND_ME(reflection_property, getName, arginfo_reflection__void, 0)
! 5363: ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0)
! 5364: ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0)
! 5365: ZEND_ME(reflection_property, isPublic, arginfo_reflection__void, 0)
! 5366: ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0)
! 5367: ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0)
! 5368: ZEND_ME(reflection_property, isStatic, arginfo_reflection__void, 0)
! 5369: ZEND_ME(reflection_property, isDefault, arginfo_reflection__void, 0)
! 5370: ZEND_ME(reflection_property, getModifiers, arginfo_reflection__void, 0)
! 5371: ZEND_ME(reflection_property, getDeclaringClass, arginfo_reflection__void, 0)
! 5372: ZEND_ME(reflection_property, getDocComment, arginfo_reflection__void, 0)
! 5373: ZEND_ME(reflection_property, setAccessible, arginfo_reflection_property_setAccessible, 0)
! 5374: PHP_FE_END
! 5375: };
! 5376:
! 5377: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2)
! 5378: ZEND_ARG_INFO(0, function)
! 5379: ZEND_ARG_INFO(0, parameter)
! 5380: ZEND_ARG_INFO(0, return)
! 5381: ZEND_END_ARG_INFO()
! 5382:
! 5383: ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0)
! 5384: ZEND_ARG_INFO(0, function)
! 5385: ZEND_ARG_INFO(0, parameter)
! 5386: ZEND_END_ARG_INFO()
! 5387:
! 5388: static const zend_function_entry reflection_parameter_functions[] = {
! 5389: ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
! 5390: ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5391: ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0)
! 5392: ZEND_ME(reflection_parameter, __toString, arginfo_reflection__void, 0)
! 5393: ZEND_ME(reflection_parameter, getName, arginfo_reflection__void, 0)
! 5394: ZEND_ME(reflection_parameter, isPassedByReference, arginfo_reflection__void, 0)
! 5395: ZEND_ME(reflection_parameter, getDeclaringFunction, arginfo_reflection__void, 0)
! 5396: ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0)
! 5397: ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0)
! 5398: ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0)
! 5399: ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0)
! 5400: ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0)
! 5401: ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
! 5402: ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
! 5403: ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
! 5404: PHP_FE_END
! 5405: };
! 5406:
! 5407: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
! 5408: ZEND_ARG_INFO(0, name)
! 5409: ZEND_ARG_INFO(0, return)
! 5410: ZEND_END_ARG_INFO()
! 5411:
! 5412: ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0)
! 5413: ZEND_ARG_INFO(0, name)
! 5414: ZEND_END_ARG_INFO()
! 5415:
! 5416: static const zend_function_entry reflection_extension_functions[] = {
! 5417: ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
! 5418: ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
! 5419: ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0)
! 5420: ZEND_ME(reflection_extension, __toString, arginfo_reflection__void, 0)
! 5421: ZEND_ME(reflection_extension, getName, arginfo_reflection__void, 0)
! 5422: ZEND_ME(reflection_extension, getVersion, arginfo_reflection__void, 0)
! 5423: ZEND_ME(reflection_extension, getFunctions, arginfo_reflection__void, 0)
! 5424: ZEND_ME(reflection_extension, getConstants, arginfo_reflection__void, 0)
! 5425: ZEND_ME(reflection_extension, getINIEntries, arginfo_reflection__void, 0)
! 5426: ZEND_ME(reflection_extension, getClasses, arginfo_reflection__void, 0)
! 5427: ZEND_ME(reflection_extension, getClassNames, arginfo_reflection__void, 0)
! 5428: ZEND_ME(reflection_extension, getDependencies, arginfo_reflection__void, 0)
! 5429: ZEND_ME(reflection_extension, info, arginfo_reflection__void, 0)
! 5430: PHP_FE_END
! 5431: };
! 5432: /* }}} */
! 5433:
! 5434: const zend_function_entry reflection_ext_functions[] = { /* {{{ */
! 5435: PHP_FE_END
! 5436: }; /* }}} */
! 5437:
! 5438: static zend_object_handlers *zend_std_obj_handlers;
! 5439:
! 5440: /* {{{ _reflection_write_property */
! 5441: static void _reflection_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
! 5442: {
! 5443: if ((Z_TYPE_P(member) == IS_STRING)
! 5444: && zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
! 5445: && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name")))
! 5446: || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class")))))
! 5447: {
! 5448: zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
! 5449: "Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member));
! 5450: }
! 5451: else
! 5452: {
! 5453: zend_std_obj_handlers->write_property(object, member, value TSRMLS_CC);
! 5454: }
! 5455: }
! 5456: /* }}} */
! 5457:
! 5458: PHP_MINIT_FUNCTION(reflection) /* {{{ */
! 5459: {
! 5460: zend_class_entry _reflection_entry;
! 5461:
! 5462: zend_std_obj_handlers = zend_get_std_object_handlers();
! 5463: memcpy(&reflection_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
! 5464: reflection_object_handlers.clone_obj = NULL;
! 5465: reflection_object_handlers.write_property = _reflection_write_property;
! 5466:
! 5467: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions);
! 5468: reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
! 5469:
! 5470: INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions);
! 5471: reflection_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
! 5472:
! 5473: INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions);
! 5474: reflector_ptr = zend_register_internal_interface(&_reflection_entry TSRMLS_CC);
! 5475:
! 5476: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions);
! 5477: _reflection_entry.create_object = reflection_objects_new;
! 5478: reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
! 5479: reflection_register_implement(reflection_function_abstract_ptr, reflector_ptr TSRMLS_CC);
! 5480: zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT TSRMLS_CC);
! 5481:
! 5482: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions);
! 5483: _reflection_entry.create_object = reflection_objects_new;
! 5484: reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
! 5485: zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5486:
! 5487: REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
! 5488:
! 5489: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
! 5490: _reflection_entry.create_object = reflection_objects_new;
! 5491: reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
! 5492: reflection_register_implement(reflection_parameter_ptr, reflector_ptr TSRMLS_CC);
! 5493: zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5494:
! 5495: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
! 5496: _reflection_entry.create_object = reflection_objects_new;
! 5497: reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
! 5498: zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5499: zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5500:
! 5501: REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC);
! 5502: REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC);
! 5503: REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED);
! 5504: REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE);
! 5505: REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT);
! 5506: REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL);
! 5507:
! 5508: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions);
! 5509: _reflection_entry.create_object = reflection_objects_new;
! 5510: reflection_class_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
! 5511: reflection_register_implement(reflection_class_ptr, reflector_ptr TSRMLS_CC);
! 5512: zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5513:
! 5514: REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
! 5515: REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
! 5516: REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL_CLASS);
! 5517:
! 5518: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions);
! 5519: _reflection_entry.create_object = reflection_objects_new;
! 5520: reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr, NULL TSRMLS_CC);
! 5521:
! 5522: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions);
! 5523: _reflection_entry.create_object = reflection_objects_new;
! 5524: reflection_property_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
! 5525: reflection_register_implement(reflection_property_ptr, reflector_ptr TSRMLS_CC);
! 5526: zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5527: zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5528:
! 5529: REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC);
! 5530: REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC);
! 5531: REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED);
! 5532: REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE);
! 5533:
! 5534: INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions);
! 5535: _reflection_entry.create_object = reflection_objects_new;
! 5536: reflection_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
! 5537: reflection_register_implement(reflection_extension_ptr, reflector_ptr TSRMLS_CC);
! 5538: zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
! 5539:
! 5540: return SUCCESS;
! 5541: } /* }}} */
! 5542:
! 5543: PHP_MINFO_FUNCTION(reflection) /* {{{ */
! 5544: {
! 5545: php_info_print_table_start();
! 5546: php_info_print_table_header(2, "Reflection", "enabled");
! 5547:
! 5548: php_info_print_table_row(2, "Version", "$Revision: 321634 $");
! 5549:
! 5550: php_info_print_table_end();
! 5551: } /* }}} */
! 5552:
! 5553: zend_module_entry reflection_module_entry = { /* {{{ */
! 5554: STANDARD_MODULE_HEADER,
! 5555: "Reflection",
! 5556: reflection_ext_functions,
! 5557: PHP_MINIT(reflection),
! 5558: NULL,
! 5559: NULL,
! 5560: NULL,
! 5561: PHP_MINFO(reflection),
! 5562: "$Revision: 321634 $",
! 5563: STANDARD_MODULE_PROPERTIES
! 5564: }; /* }}} */
! 5565:
! 5566: /*
! 5567: * Local variables:
! 5568: * tab-width: 4
! 5569: * c-basic-offset: 4
! 5570: * indent-tabs-mode: t
! 5571: * End:
! 5572: * vim600: noet sw=4 ts=4 fdm=marker
! 5573: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>