Re: ReflectionMethod::setAccessible()

From: Date: Thu, 03 Sep 2009 10:12:06 +0000
Subject: Re: ReflectionMethod::setAccessible()
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-45460@lists.php.net to get a copy of this message
hi Sebastian, I like the idea, a definitive +1. I did not check the implementation yet however I'd to say that I'm not in favor of including it in 5.3.1 (for obvious reasons). Cheers, On Wed, Sep 2, 2009 at 9:48 PM, Sebastian Bergmann<sb@sebastian-bergmann.de> wrote: >  The patch below adds the ReflectionMethod::setAccessible() method and >  adds support for the ignore_visibility flag that is controlled by this >  method to ReflectionMethod::invoke() and ReflectionMethod::invokeArgs(). > >  The patch complements ReflectionProperty::setAccessible() that was added >  in PHP 5.3.0. It has been developed for PHP_5_3 and I am proposing it >  for PHP 5.3.1 (it's a new feature, but a minor one). > >  If accepted, I will provide a patch against trunk as well as tests >  and documentation. > >  Cheers! > Sebastian > > Index: ext/reflection/php_reflection.c > =================================================================== > --- ext/reflection/php_reflection.c     (revision 287971) > +++ ext/reflection/php_reflection.c     (working copy) > @@ -176,7 +176,6 @@ >  typedef struct _property_reference { >        zend_class_entry *ce; >        zend_property_info prop; > -       unsigned int ignore_visibility:1; >  } property_reference; > >  /* Struct for parameters */ > @@ -201,6 +200,7 @@ >        reflection_type_t ref_type; >        zval *obj; >        zend_class_entry *ce; > +       unsigned int ignore_visibility:1; >  } reflection_object; > >  static zend_object_handlers reflection_object_handlers; > @@ -1290,10 +1290,10 @@ >        reference = (property_reference*) emalloc(sizeof(property_reference)); >        reference->ce = ce; >        reference->prop = *prop; > -       reference->ignore_visibility = 0; >        intern->ptr = reference; >        intern->ref_type = REF_TYPE_PROPERTY; >        intern->ce = ce; > +       intern->ignore_visibility = 0; >        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), > (void **) &name, sizeof(zval *), NULL); >        zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), > (void **) &classname, sizeof(zval *), NULL); >  } > @@ -2561,8 +2561,9 @@ > >        GET_REFLECTION_OBJECT_PTR(mptr); > > -       if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) > -               || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) > +       if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) > +                || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) > +                && intern->ignore_visibility == 0) >        { >                if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) { >                        zend_throw_exception_ex(reflection_exception_ptr, 0 > TSRMLS_CC, > @@ -2669,8 +2670,9 @@ >                return; >        } > > -       if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) > -               || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) > +       if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) > +                || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) > +                && intern->ignore_visibility == 0) >        { >                if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) { >                        zend_throw_exception_ex(reflection_exception_ptr, 0 > TSRMLS_CC, > @@ -2959,6 +2961,28 @@ >  } >  /* }}} */ > > +/* {{{ proto public void ReflectionMethod::setAccessible() > +   Sets whether non-public methods can be invoked */ > +ZEND_METHOD(reflection_method, setAccessible) > +{ > +       reflection_object *intern; > +       zend_bool visible; > + > +       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == > FAILURE) { > +               return; > +       } > + > +       intern = getThis(); > +       intern = (reflection_object *) zend_object_store_get_object(intern TSRMLS_CC); > + > +       if (intern == NULL) { > +               return; > +       } > + > +       intern->ignore_visibility = visible; > +} > +/* }}} */ > + >  /* {{{ 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) > @@ -4375,10 +4399,10 @@ >                reference->prop = *property_info; >        } >        reference->ce = ce; > -       reference->ignore_visibility = 0; >        intern->ptr = reference; >        intern->ref_type = REF_TYPE_PROPERTY; >        intern->ce = ce; > +       intern->ignore_visibility = 0; >  } >  /* }}} */ > > @@ -4491,7 +4515,7 @@ >        METHOD_NOTSTATIC(reflection_property_ptr); >        GET_REFLECTION_OBJECT_PTR(ref); > > -       if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) > && ref->ignore_visibility == 0) { > +       if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) > && intern->ignore_visibility == 0) { >                _default_get_entry(getThis(), "name", > sizeof("name"), &name TSRMLS_CC); >                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, >                        "Cannot access non-public member %s::%s", > intern->ce->name, Z_STRVAL(name)); > @@ -4543,7 +4567,7 @@ >        METHOD_NOTSTATIC(reflection_property_ptr); >        GET_REFLECTION_OBJECT_PTR(ref); > > -       if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && ref->ignore_visibility > == 0) { > +       if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && > intern->ignore_visibility == 0) { >                _default_get_entry(getThis(), "name", > sizeof("name"), &name TSRMLS_CC); >                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, >                        "Cannot access non-public member %s::%s", > intern->ce->name, Z_STRVAL(name)); > @@ -4660,14 +4684,20 @@ >  ZEND_METHOD(reflection_property, setAccessible) >  { >        reflection_object *intern; > -       property_reference *ref; >        zend_bool visible; > >        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == > FAILURE) { >                return; >        } > -       GET_REFLECTION_OBJECT_PTR(ref); > -       ref->ignore_visibility = visible; > + > +       intern = getThis(); > +       intern = (reflection_object *) zend_object_store_get_object(intern TSRMLS_CC); > + > +       if (intern == NULL) { > +               return; > +       } > + > +       intern->ignore_visibility = visible; >  } >  /* }}} */ > > @@ -5095,6 +5125,10 @@ >        ZEND_ARG_ARRAY_INFO(0, args, 0) >  ZEND_END_ARG_INFO() > > +ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0) > +       ZEND_ARG_INFO(0, value) > +ZEND_END_ARG_INFO() > + >  static const zend_function_entry reflection_method_functions[] = { >        ZEND_ME(reflection_method, export, arginfo_reflection_method_export, > ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) >        ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0) > @@ -5112,6 +5146,7 @@ >        ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0) >        ZEND_ME(reflection_method, getDeclaringClass, NULL, 0) >        ZEND_ME(reflection_method, getPrototype, NULL, 0) > +       ZEND_ME(reflection_property, setAccessible, arginfo_reflection_method_setAccessible, > 0) >        {NULL, NULL, NULL} >  }; > > > -- > Sebastian Bergmann                    Co-Founder and Principal Consultant > http://sebastian-bergmann.de/                       >     http://thePHP.cc/ > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > -- Pierre http://blog.thepimp.net | http://www.libgd.org

« previous php.internals (#45460) next »