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