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