Re: ReflectionMethod::setAccessible()
| From: | Pierre Joye | 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