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