@ -64,6 +64,7 @@ PHPAPI zend_class_entry *reflection_class_ptr;
PHPAPI zend_class_entry * reflection_object_ptr ;
PHPAPI zend_class_entry * reflection_method_ptr ;
PHPAPI zend_class_entry * reflection_property_ptr ;
PHPAPI zend_class_entry * reflection_class_constant_ptr ;
PHPAPI zend_class_entry * reflection_extension_ptr ;
PHPAPI zend_class_entry * reflection_zend_extension_ptr ;
@ -215,7 +216,8 @@ typedef enum {
REF_TYPE_PARAMETER ,
REF_TYPE_TYPE ,
REF_TYPE_PROPERTY ,
REF_TYPE_DYNAMIC_PROPERTY
REF_TYPE_DYNAMIC_PROPERTY ,
REF_TYPE_CLASS_CONSTANT
} reflection_type_t ;
/* Struct for reflection objects */
@ -333,7 +335,7 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */
efree ( intern - > ptr ) ;
break ;
case REF_TYPE_GENERATOR :
break ;
case REF_TYPE_CLASS_CONSTANT :
case REF_TYPE_OTHER :
break ;
}
@ -368,6 +370,7 @@ static zval *reflection_instantiate(zend_class_entry *pce, zval *object) /* {{{
static void _const_string ( string * str , char * name , zval * value , char * indent ) ;
static void _function_string ( string * str , zend_function * fptr , zend_class_entry * scope , char * indent ) ;
static void _property_string ( string * str , zend_property_info * prop , char * prop_name , char * indent ) ;
static void _class_const_string ( string * str , char * name , zend_class_constant * c , char * indent ) ;
static void _class_string ( string * str , zend_class_entry * ce , zval * obj , char * indent ) ;
static void _extension_string ( string * str , zend_module_entry * module , char * indent ) ;
static void _zend_extension_string ( string * str , zend_extension * extension , char * indent ) ;
@ -450,11 +453,11 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
string_printf ( str , " %s - Constants [%d] { \n " , indent , count ) ;
if ( count > 0 ) {
zend_string * key ;
zval * value ;
zend_class_constant * c ;
ZEND_HASH_FOREACH_STR_KEY_VAL ( & ce - > constants_table , key , value ) {
zval_update_constant_ex ( value , 1 , NULL ) ;
_const_string ( str , ZSTR_VAL ( key ) , value , indent ) ;
ZEND_HASH_FOREACH_STR_KEY_PTR ( & ce - > constants_table , key , c ) {
zval_update_constant_ex ( & c - > value , 1 , NULL ) ;
_class_c onst_string ( str , ZSTR_VAL ( key ) , c , indent ) ;
} ZEND_HASH_FOREACH_END ( ) ;
}
string_printf ( str , " %s } \n " , indent ) ;
@ -627,6 +630,20 @@ static void _const_string(string *str, char *name, zval *value, char *indent)
}
/* }}} */
/* {{{ _class_const_string */
static void _class_const_string ( string * str , char * name , zend_class_constant * c , char * indent )
{
char * type = zend_zval_type_name ( & c - > value ) ;
char * visibility = zend_visibility_string ( Z_ACCESS_FLAGS ( c - > value ) ) ;
zend_string * value_str = zval_get_string ( & c - > value ) ;
string_printf ( str , " %s Constant [ %s %s %s ] { %s } \n " ,
indent , visibility , type , name , ZSTR_VAL ( value_str ) ) ;
zend_string_release ( value_str ) ;
}
/* }}} */
/* {{{ _get_recv_opcode */
static zend_op * _get_recv_op ( zend_op_array * op_array , uint32_t offset )
{
@ -1356,6 +1373,27 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
}
/* }}} */
/* {{{ reflection_class_constant_factory */
static void reflection_class_constant_factory ( zend_class_entry * ce , zend_string * name_str , zend_class_constant * constant , zval * object )
{
reflection_object * intern ;
zval name ;
zval classname ;
ZVAL_STR_COPY ( & name , name_str ) ;
ZVAL_STR_COPY ( & classname , ce - > name ) ;
reflection_instantiate ( reflection_class_constant_ptr , object ) ;
intern = Z_REFLECTION_P ( object ) ;
intern - > ptr = constant ;
intern - > ref_type = REF_TYPE_CLASS_CONSTANT ;
intern - > ce = constant - > ce ;
intern - > ignore_visibility = 0 ;
reflection_update_property ( object , " name " , & name ) ;
reflection_update_property ( object , " class " , & classname ) ;
}
/* }}} */
/* {{{ _reflection_export */
static void _reflection_export ( INTERNAL_FUNCTION_PARAMETERS , zend_class_entry * ce_ptr , int ctor_argc )
{
@ -3668,6 +3706,197 @@ ZEND_METHOD(reflection_method, setAccessible)
}
/* }}} */
/* {{{ proto public void ReflectionClassConstant::__construct(mixed class, string name)
Constructor . Throws an Exception in case the given class constant does not exist */
ZEND_METHOD ( reflection_class_constant , __construct )
{
zval * classname , * object , name , cname ;
zend_string * constname ;
reflection_object * intern ;
zend_class_entry * ce ;
zend_class_constant * constant = NULL ;
if ( zend_parse_parameters_throw ( ZEND_NUM_ARGS ( ) , " zS " , & classname , & constname ) = = FAILURE ) {
return ;
}
object = getThis ( ) ;
intern = Z_REFLECTION_P ( object ) ;
if ( intern = = NULL ) {
return ;
}
/* Find the class entry */
switch ( Z_TYPE_P ( classname ) ) {
case IS_STRING :
if ( ( ce = zend_lookup_class ( Z_STR_P ( classname ) ) ) = = NULL ) {
zend_throw_exception_ex ( reflection_exception_ptr , 0 ,
" Class %s does not exist " , Z_STRVAL_P ( classname ) ) ;
return ;
}
break ;
case IS_OBJECT :
ce = Z_OBJCE_P ( classname ) ;
break ;
default :
_DO_THROW ( " The parameter class is expected to be either a string or an object " ) ;
/* returns out of this function */
}
if ( ( constant = zend_hash_find_ptr ( & ce - > constants_table , constname ) ) = = NULL ) {
zend_throw_exception_ex ( reflection_exception_ptr , 0 , " Class Constant %s::%s does not exist " , ZSTR_VAL ( ce - > name ) , ZSTR_VAL ( constname ) ) ;
return ;
}
ZVAL_STR_COPY ( & name , constname ) ;
ZVAL_STR_COPY ( & cname , ce - > name ) ;
intern - > ptr = constant ;
intern - > ref_type = REF_TYPE_CLASS_CONSTANT ;
intern - > ce = constant - > ce ;
intern - > ignore_visibility = 0 ;
reflection_update_property ( object , " name " , & name ) ;
reflection_update_property ( object , " class " , & cname ) ;
}
/* }}} */
/* {{{ proto public string ReflectionClassConstant::__toString()
Returns a string representation */
ZEND_METHOD ( reflection_class_constant , __toString )
{
reflection_object * intern ;
zend_class_constant * ref ;
string str ;
zval name ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ref ) ;
string_init ( & str ) ;
_default_get_entry ( getThis ( ) , " name " , sizeof ( " name " ) - 1 , & name ) ;
_class_const_string ( & str , Z_STRVAL ( name ) , ref , " " ) ;
zval_ptr_dtor ( & name ) ;
RETURN_NEW_STR ( str . buf ) ;
}
/* }}} */
/* {{{ proto public string ReflectionClassConstant::getName()
Returns the constant ' name */
ZEND_METHOD ( reflection_class_constant , getName )
{
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
_default_get_entry ( getThis ( ) , " name " , sizeof ( " name " ) - 1 , return_value ) ;
}
/* }}} */
static void _class_constant_check_flag ( INTERNAL_FUNCTION_PARAMETERS , int mask ) /* { { { */
{
reflection_object * intern ;
zend_class_constant * ref ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ref ) ;
RETURN_BOOL ( Z_ACCESS_FLAGS ( ref - > value ) & mask ) ;
}
/* }}} */
/* {{{ proto public bool ReflectionClassConstant::isPublic()
Returns whether this constant is public */
ZEND_METHOD ( reflection_class_constant , isPublic )
{
_class_constant_check_flag ( INTERNAL_FUNCTION_PARAM_PASSTHRU , ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC ) ;
}
/* }}} */
/* {{{ proto public bool ReflectionClassConstant::isPrivate()
Returns whether this constant is private */
ZEND_METHOD ( reflection_class_constant , isPrivate )
{
_class_constant_check_flag ( INTERNAL_FUNCTION_PARAM_PASSTHRU , ZEND_ACC_PRIVATE ) ;
}
/* }}} */
/* {{{ proto public bool ReflectionClassConstant::isProtected()
Returns whether this constant is protected */
ZEND_METHOD ( reflection_class_constant , isProtected )
{
_class_constant_check_flag ( INTERNAL_FUNCTION_PARAM_PASSTHRU , ZEND_ACC_PROTECTED ) ;
}
/* }}} */
/* {{{ proto public int ReflectionClassConstant::getModifiers()
Returns a bitfield of the access modifiers for this constant */
ZEND_METHOD ( reflection_class_constant , getModifiers )
{
reflection_object * intern ;
zend_class_constant * ref ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ref ) ;
RETURN_LONG ( Z_ACCESS_FLAGS ( ref - > value ) ) ;
}
/* }}} */
/* {{{ proto public mixed ReflectionClassConstant::getValue()
Returns this constant ' s value */
ZEND_METHOD ( reflection_class_constant , getValue )
{
reflection_object * intern ;
zend_class_constant * ref ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ref ) ;
ZVAL_DUP ( return_value , & ref - > value ) ;
}
/* }}} */
/* {{{ proto public ReflectionClass ReflectionClassConstant::getDeclaringClass()
Get the declaring class */
ZEND_METHOD ( reflection_class_constant , getDeclaringClass )
{
reflection_object * intern ;
zend_class_constant * ref ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ref ) ;
zend_reflection_class_factory ( ref - > ce , return_value ) ;
}
/* }}} */
/* {{{ proto public string ReflectionClassConstant::getDocComment()
Returns the doc comment for this constant */
ZEND_METHOD ( reflection_class_constant , getDocComment )
{
reflection_object * intern ;
zend_class_constant * ref ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ref ) ;
if ( ref - > doc_comment ) {
RETURN_STR_COPY ( ref - > doc_comment ) ;
}
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
Exports a reflection object . Returns the output if TRUE is specified for return , printing it otherwise . */
ZEND_METHOD ( reflection_class , export )
@ -4414,6 +4643,8 @@ ZEND_METHOD(reflection_class, getConstants)
{
reflection_object * intern ;
zend_class_entry * ce ;
zend_string * key ;
zend_class_constant * c ;
zval * val ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
@ -4421,12 +4652,36 @@ ZEND_METHOD(reflection_class, getConstants)
}
GET_REFLECTION_OBJECT_PTR ( ce ) ;
array_init ( return_value ) ;
ZEND_HASH_FOREACH_VAL ( & ce - > constants_table , val ) {
if ( UNEXPECTED ( zval_update_constant_ex ( val , 1 , ce ) ! = SUCCESS ) ) {
ZEND_HASH_FOREACH_STR_KEY_PTR ( & ce - > constants_table , key , c ) {
if ( UNEXPECTED ( zval_update_constant_ex ( & c - > value , 1 , ce ) ! = SUCCESS ) ) {
zend_array_destroy ( Z_ARRVAL_P ( return_value ) ) ;
return ;
}
val = zend_hash_add_new ( Z_ARRVAL_P ( return_value ) , key , & c - > value ) ;
Z_TRY_ADDREF_P ( val ) ;
} ZEND_HASH_FOREACH_END ( ) ;
}
/* }}} */
/* {{{ proto public array ReflectionClass::getReflectionConstants()
Returns an associative array containing this class ' constants as ReflectionClassConstant objects */
ZEND_METHOD ( reflection_class , getReflectionConstants )
{
reflection_object * intern ;
zend_class_entry * ce ;
zend_string * name ;
zend_class_constant * constant ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
GET_REFLECTION_OBJECT_PTR ( ce ) ;
array_init ( return_value ) ;
ZEND_HASH_FOREACH_STR_KEY_PTR ( & ce - > constants_table , name , constant ) {
zval class_const ;
reflection_class_constant_factory ( ce , name , constant , & class_const ) ;
zend_hash_next_index_insert ( Z_ARRVAL_P ( return_value ) , & class_const ) ;
} ZEND_HASH_FOREACH_END ( ) ;
zend_hash_copy ( Z_ARRVAL_P ( return_value ) , & ce - > constants_table , zval_add_ref_unref ) ;
}
/* }}} */
@ -4436,7 +4691,7 @@ ZEND_METHOD(reflection_class, getConstant)
{
reflection_object * intern ;
zend_class_entry * ce ;
zval * value ;
zend_class_constant * c ;
zend_string * name ;
METHOD_NOTSTATIC ( reflection_class_ptr ) ;
@ -4445,15 +4700,36 @@ ZEND_METHOD(reflection_class, getConstant)
}
GET_REFLECTION_OBJECT_PTR ( ce ) ;
ZEND_HASH_FOREACH_VAL ( & ce - > constants_table , value ) {
if ( UNEXPECTED ( zval_update_constant_ex ( value , 1 , ce ) ! = SUCCESS ) ) {
ZEND_HASH_FOREACH_PTR ( & ce - > constants_table , c ) {
if ( UNEXPECTED ( zval_update_constant_ex ( & c - > value , 1 , ce ) ! = SUCCESS ) ) {
return ;
}
} ZEND_HASH_FOREACH_END ( ) ;
if ( ( value = zend_hash_find ( & ce - > constants_table , name ) ) = = NULL ) {
if ( ( c = zend_hash_find_ptr ( & ce - > constants_table , name ) ) = = NULL ) {
RETURN_FALSE ;
}
ZVAL_DUP ( return_value , value ) ;
ZVAL_DUP ( return_value , & c - > value ) ;
}
/* }}} */
/* {{{ proto public mixed ReflectionClass::getReflectionConstant(string name)
Returns the class ' constant as ReflectionClassConstant objects */
ZEND_METHOD ( reflection_class , getReflectionConstant )
{
reflection_object * intern ;
zend_class_entry * ce ;
zend_class_constant * constant ;
zend_string * name ;
GET_REFLECTION_OBJECT_PTR ( ce ) ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " S " , & name ) = = FAILURE ) {
return ;
}
if ( ( constant = zend_hash_find_ptr ( & ce - > constants_table , name ) ) = = NULL ) {
RETURN_FALSE ;
}
reflection_class_constant_factory ( ce , name , constant , return_value ) ;
}
/* }}} */
@ -5171,6 +5447,14 @@ ZEND_METHOD(reflection_property, export)
}
/* }}} */
/* {{{ proto public static mixed ReflectionClassConstant::export(mixed class, string name [, bool return]) throws ReflectionException
Exports a reflection object . Returns the output if TRUE is specified for return , printing it otherwise . */
ZEND_METHOD ( reflection_class_constant , export )
{
_reflection_export ( INTERNAL_FUNCTION_PARAM_PASSTHRU , reflection_class_constant_ptr , 2 ) ;
}
/* }}} */
/* {{{ proto public void ReflectionProperty::__construct(mixed class, string name)
Constructor . Throws an Exception in case the given property does not exist */
ZEND_METHOD ( reflection_property , __construct )
@ -6334,7 +6618,9 @@ static const zend_function_entry reflection_class_functions[] = {
ZEND_ME ( reflection_class , getProperties , arginfo_reflection_class_getProperties , 0 )
ZEND_ME ( reflection_class , hasConstant , arginfo_reflection_class_hasConstant , 0 )
ZEND_ME ( reflection_class , getConstants , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class , getReflectionConstants , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class , getConstant , arginfo_reflection_class_getConstant , 0 )
ZEND_ME ( reflection_class , getReflectionConstant , arginfo_reflection_class_getConstant , 0 )
ZEND_ME ( reflection_class , getInterfaces , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class , getInterfaceNames , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class , isInterface , arginfo_reflection__void , 0 )
@ -6426,6 +6712,33 @@ static const zend_function_entry reflection_property_functions[] = {
PHP_FE_END
} ;
ZEND_BEGIN_ARG_INFO_EX ( arginfo_reflection_class_constant_export , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , class )
ZEND_ARG_INFO ( 0 , name )
ZEND_ARG_INFO ( 0 , return )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_reflection_class_constant___construct , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , class )
ZEND_ARG_INFO ( 0 , name )
ZEND_END_ARG_INFO ( )
static const zend_function_entry reflection_class_constant_functions [ ] = {
ZEND_ME ( reflection , __clone , arginfo_reflection__void , ZEND_ACC_PRIVATE | ZEND_ACC_FINAL )
ZEND_ME ( reflection_class_constant , export , arginfo_reflection_class_constant_export , ZEND_ACC_STATIC | ZEND_ACC_PUBLIC )
ZEND_ME ( reflection_class_constant , __construct , arginfo_reflection_class_constant___construct , 0 )
ZEND_ME ( reflection_class_constant , __toString , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , getName , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , getValue , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , isPublic , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , isPrivate , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , isProtected , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , getModifiers , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , getDeclaringClass , arginfo_reflection__void , 0 )
ZEND_ME ( reflection_class_constant , getDocComment , arginfo_reflection__void , 0 )
PHP_FE_END
} ;
ZEND_BEGIN_ARG_INFO_EX ( arginfo_reflection_parameter_export , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , function )
ZEND_ARG_INFO ( 0 , parameter )
@ -6622,6 +6935,13 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
zend_declare_property_string ( reflection_property_ptr , " name " , sizeof ( " name " ) - 1 , " " , ZEND_ACC_PUBLIC ) ;
zend_declare_property_string ( reflection_property_ptr , " class " , sizeof ( " class " ) - 1 , " " , ZEND_ACC_PUBLIC ) ;
INIT_CLASS_ENTRY ( _reflection_entry , " ReflectionClassConstant " , reflection_class_constant_functions ) ;
_reflection_entry . create_object = reflection_objects_new ;
reflection_class_constant_ptr = zend_register_internal_class ( & _reflection_entry ) ;
zend_class_implements ( reflection_class_constant_ptr , 1 , reflector_ptr ) ;
zend_declare_property_string ( reflection_class_constant_ptr , " name " , sizeof ( " name " ) - 1 , " " , ZEND_ACC_PUBLIC ) ;
zend_declare_property_string ( reflection_class_constant_ptr , " class " , sizeof ( " class " ) - 1 , " " , ZEND_ACC_PUBLIC ) ;
REGISTER_REFLECTION_CLASS_CONST_LONG ( property , " IS_STATIC " , ZEND_ACC_STATIC ) ;
REGISTER_REFLECTION_CLASS_CONST_LONG ( property , " IS_PUBLIC " , ZEND_ACC_PUBLIC ) ;
REGISTER_REFLECTION_CLASS_CONST_LONG ( property , " IS_PROTECTED " , ZEND_ACC_PROTECTED ) ;