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<s...@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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to