@@ -97,6 +97,7 @@ PHPAPI zend_class_entry *reflection_enum_ptr;
97
97
PHPAPI zend_class_entry * reflection_enum_unit_case_ptr ;
98
98
PHPAPI zend_class_entry * reflection_enum_backed_case_ptr ;
99
99
PHPAPI zend_class_entry * reflection_fiber_ptr ;
100
+ PHPAPI zend_class_entry * reflection_constant_ptr ;
100
101
101
102
/* Exception throwing macro */
102
103
#define _DO_THROW (msg ) \
@@ -538,20 +539,48 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
538
539
static void _const_string (smart_str * str , char * name , zval * value , char * indent )
539
540
{
540
541
const char * type = zend_zval_type_name (value );
542
+ uint32_t flags = Z_CONSTANT_FLAGS_P (value );
543
+
544
+ smart_str_appends (str , indent );
545
+ smart_str_appends (str , "Constant [ " );
546
+
547
+ if (flags & (CONST_PERSISTENT |CONST_NO_FILE_CACHE |CONST_DEPRECATED )) {
548
+ bool first = true;
549
+ smart_str_appends (str , "<" );
550
+
551
+ #define DUMP_CONST_FLAG (flag , output ) \
552
+ do { \
553
+ if (flags & flag) { \
554
+ if (!first) smart_str_appends(str, ", "); \
555
+ smart_str_appends(str, output); \
556
+ first = false; \
557
+ } \
558
+ } while (0)
559
+ DUMP_CONST_FLAG (CONST_PERSISTENT , "persistent" );
560
+ DUMP_CONST_FLAG (CONST_NO_FILE_CACHE , "no_file_cache" );
561
+ DUMP_CONST_FLAG (CONST_DEPRECATED , "deprecated" );
562
+ #undef DUMP_CONST_FLAG
563
+
564
+ smart_str_appends (str , "> " );
565
+ }
566
+
567
+ smart_str_appends (str , type );
568
+ smart_str_appendc (str , ' ' );
569
+ smart_str_appends (str , name );
570
+ smart_str_appends (str , " ] { " );
541
571
542
572
if (Z_TYPE_P (value ) == IS_ARRAY ) {
543
- smart_str_append_printf (str , "%s Constant [ %s %s ] { Array }\n" ,
544
- indent , type , name );
573
+ smart_str_append (str , ZSTR_KNOWN (ZEND_STR_ARRAY_CAPITALIZED ));
545
574
} else if (Z_TYPE_P (value ) == IS_STRING ) {
546
- smart_str_append_printf (str , "%s Constant [ %s %s ] { %s }\n" ,
547
- indent , type , name , Z_STRVAL_P (value ));
575
+ smart_str_appends (str , Z_STRVAL_P (value ));
548
576
} else {
549
577
zend_string * tmp_value_str ;
550
578
zend_string * value_str = zval_get_tmp_string (value , & tmp_value_str );
551
- smart_str_append_printf (str , "%s Constant [ %s %s ] { %s }\n" ,
552
- indent , type , name , ZSTR_VAL (value_str ));
579
+ smart_str_append (str , value_str );
553
580
zend_tmp_string_release (tmp_value_str );
554
581
}
582
+
583
+ smart_str_appends (str , " }\n" );
555
584
}
556
585
/* }}} */
557
586
@@ -1059,7 +1088,7 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i
1059
1088
1060
1089
ZEND_HASH_MAP_FOREACH_PTR (EG (zend_constants ), constant ) {
1061
1090
if (ZEND_CONSTANT_MODULE_NUMBER (constant ) == module -> module_number ) {
1062
- _const_string (& str_constants , ZSTR_VAL (constant -> name ), & constant -> value , indent );
1091
+ _const_string (& str_constants , ZSTR_VAL (constant -> name ), & constant -> value , " " );
1063
1092
num_constants ++ ;
1064
1093
}
1065
1094
} ZEND_HASH_FOREACH_END ();
@@ -7207,6 +7236,140 @@ static zval *_reflection_write_property(zend_object *object, zend_string *name,
7207
7236
}
7208
7237
/* }}} */
7209
7238
7239
+ ZEND_METHOD (ReflectionConstant , __construct )
7240
+ {
7241
+ zend_string * name ;
7242
+
7243
+ zval * object = ZEND_THIS ;
7244
+ reflection_object * intern = Z_REFLECTION_P (object );
7245
+
7246
+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
7247
+ Z_PARAM_STR (name )
7248
+ ZEND_PARSE_PARAMETERS_END ();
7249
+
7250
+ /* Build name with lowercased ns. */
7251
+ bool backslash_prefixed = ZSTR_VAL (name )[0 ] == '\\' ;
7252
+ char * source = ZSTR_VAL (name ) + backslash_prefixed ;
7253
+ size_t source_len = ZSTR_LEN (name ) - backslash_prefixed ;
7254
+ zend_string * lc_name = zend_string_alloc (source_len , /* persistent */ false);
7255
+ const char * ns_end = zend_memrchr (source , '\\' , source_len );
7256
+ size_t ns_len = 0 ;
7257
+ if (ns_end ) {
7258
+ ns_len = ns_end - ZSTR_VAL (name );
7259
+ zend_str_tolower_copy (ZSTR_VAL (lc_name ), source , ns_len );
7260
+ }
7261
+ memcpy (ZSTR_VAL (lc_name ) + ns_len , source + ns_len , source_len - ns_len );
7262
+
7263
+ zend_constant * const_ = zend_get_constant_ptr (lc_name );
7264
+ zend_string_release_ex (lc_name , /* persistent */ false);
7265
+ if (!const_ ) {
7266
+ zend_throw_exception_ex (reflection_exception_ptr , 0 , "Constant \"%s\" does not exist" , ZSTR_VAL (name ));
7267
+ RETURN_THROWS ();
7268
+ }
7269
+
7270
+ intern -> ptr = const_ ;
7271
+ intern -> ref_type = REF_TYPE_OTHER ;
7272
+
7273
+ zval * name_zv = reflection_prop_name (object );
7274
+ zval_ptr_dtor (name_zv );
7275
+ ZVAL_STR_COPY (name_zv , name );
7276
+ }
7277
+
7278
+ ZEND_METHOD (ReflectionConstant , getName )
7279
+ {
7280
+ reflection_object * intern ;
7281
+ zend_constant * const_ ;
7282
+
7283
+ if (zend_parse_parameters_none () == FAILURE ) {
7284
+ RETURN_THROWS ();
7285
+ }
7286
+
7287
+ GET_REFLECTION_OBJECT_PTR (const_ );
7288
+ RETURN_STR_COPY (const_ -> name );
7289
+ }
7290
+
7291
+ ZEND_METHOD (ReflectionConstant , getNamespaceName )
7292
+ {
7293
+ reflection_object * intern ;
7294
+ zend_constant * const_ ;
7295
+
7296
+ if (zend_parse_parameters_none () == FAILURE ) {
7297
+ RETURN_THROWS ();
7298
+ }
7299
+
7300
+ GET_REFLECTION_OBJECT_PTR (const_ );
7301
+
7302
+ const char * backslash = zend_memrchr (ZSTR_VAL (const_ -> name ), '\\' , ZSTR_LEN (const_ -> name ));
7303
+ if (backslash ) {
7304
+ size_t length = backslash - ZSTR_VAL (const_ -> name );
7305
+ RETURN_STRINGL (ZSTR_VAL (const_ -> name ), length );
7306
+ } else {
7307
+ RETURN_EMPTY_STRING ();
7308
+ }
7309
+ }
7310
+
7311
+ ZEND_METHOD (ReflectionConstant , getShortName )
7312
+ {
7313
+ reflection_object * intern ;
7314
+ zend_constant * const_ ;
7315
+
7316
+ if (zend_parse_parameters_none () == FAILURE ) {
7317
+ RETURN_THROWS ();
7318
+ }
7319
+
7320
+ GET_REFLECTION_OBJECT_PTR (const_ );
7321
+
7322
+ const char * backslash = zend_memrchr (ZSTR_VAL (const_ -> name ), '\\' , ZSTR_LEN (const_ -> name ));
7323
+ if (backslash ) {
7324
+ size_t prefix = backslash - ZSTR_VAL (const_ -> name ) + 1 ;
7325
+ size_t length = ZSTR_LEN (const_ -> name ) - prefix ;
7326
+ RETURN_STRINGL (ZSTR_VAL (const_ -> name ) + prefix , length );
7327
+ } else {
7328
+ RETURN_STR_COPY (const_ -> name );
7329
+ }
7330
+ }
7331
+
7332
+ ZEND_METHOD (ReflectionConstant , getValue )
7333
+ {
7334
+ reflection_object * intern ;
7335
+ zend_constant * const_ ;
7336
+
7337
+ if (zend_parse_parameters_none () == FAILURE ) {
7338
+ RETURN_THROWS ();
7339
+ }
7340
+
7341
+ GET_REFLECTION_OBJECT_PTR (const_ );
7342
+ RETURN_COPY (& const_ -> value );
7343
+ }
7344
+
7345
+ ZEND_METHOD (ReflectionConstant , isDeprecated )
7346
+ {
7347
+ reflection_object * intern ;
7348
+ zend_constant * const_ ;
7349
+
7350
+ if (zend_parse_parameters_none () == FAILURE ) {
7351
+ RETURN_THROWS ();
7352
+ }
7353
+
7354
+ GET_REFLECTION_OBJECT_PTR (const_ );
7355
+ RETURN_BOOL (ZEND_CONSTANT_FLAGS (const_ ) & CONST_DEPRECATED );
7356
+ }
7357
+
7358
+ ZEND_METHOD (ReflectionConstant , __toString )
7359
+ {
7360
+ reflection_object * intern ;
7361
+ zend_constant * const_ ;
7362
+ smart_str str = {0 };
7363
+
7364
+ if (zend_parse_parameters_none () == FAILURE ) {
7365
+ RETURN_THROWS ();
7366
+ }
7367
+
7368
+ GET_REFLECTION_OBJECT_PTR (const_ );
7369
+ _const_string (& str , ZSTR_VAL (const_ -> name ), & const_ -> value , "" );
7370
+ RETURN_STR (smart_str_extract (& str ));
7371
+ }
7372
+
7210
7373
PHP_MINIT_FUNCTION (reflection ) /* {{{ */
7211
7374
{
7212
7375
memcpy (& reflection_object_handlers , & std_object_handlers , sizeof (zend_object_handlers ));
@@ -7306,6 +7469,10 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
7306
7469
reflection_fiber_ptr -> create_object = reflection_objects_new ;
7307
7470
reflection_fiber_ptr -> default_object_handlers = & reflection_object_handlers ;
7308
7471
7472
+ reflection_constant_ptr = register_class_ReflectionConstant (reflector_ptr );
7473
+ reflection_constant_ptr -> create_object = reflection_objects_new ;
7474
+ reflection_constant_ptr -> default_object_handlers = & reflection_object_handlers ;
7475
+
7309
7476
REFLECTION_G (key_initialized ) = 0 ;
7310
7477
7311
7478
return SUCCESS ;
0 commit comments