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/
This is a BC break and may possibly be rejected. Extended classes may
implement a method with same name.
Point is that Reflection API misses it and it should be added even
prior to 5.3.0 be released.
Currently there's no way to achieve such behavior.
So I'm +1.
Cheers,
On Wed, Sep 2, 2009 at 4:48 PM, Sebastian
Bergmannsb@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!
SebastianIndex: 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 ifTRUE
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/--
--
Guilherme Blanco - Web Developer
CBC - Certified Bindows Consultant
Cell Phone: +55 (16) 9215-8480
MSN: guilhermeblanco@hotmail.com
URL: http://blog.bisna.com
São Paulo - SP/Brazil
Sebastian Bergmann schrieb:
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).
An updated version of the patch can be found at
http://gist.github.com/180216.
--
Sebastian Bergmann Co-Founder and Principal Consultant
http://sebastian-bergmann.de/ http://thePHP.cc/
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
Bergmannsb@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!
SebastianIndex: 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 ifTRUE
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/--
--
Pierre
Sebastian Bergmann schrieb:
If accepted, I will provide a patch against trunk as well as tests
and documentation.
Seems to me like there is a consensus that we want this functionality
in PHP. If that is the case, I will just commit it to trunk for now
and we can merge it later to PHP 5.3.X or PHP 5.4.
--
Sebastian Bergmann Co-Founder and Principal Consultant
http://sebastian-bergmann.de/ http://thePHP.cc/