ID: 46718 Updated by: [EMAIL PROTECTED] Reported By: [EMAIL PROTECTED] -Status: Open +Status: Closed Bug Type: Reflection related Operating System: irrelevant PHP Version: 5.3CVS-2008-11-29 (CVS) New Comment:
This bug has been fixed in CVS. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2008-11-29 14:49:29] [EMAIL PROTECTED] Here is a patch that implements the missing functionality in ReflectionProperty::setValue(). Index: php_reflection.c =================================================================== RCS file: /repository/php-src/ext/reflection/php_reflection.c,v retrieving revision 1.164.2.33.2.45.2.42 diff -u -B -u -r1.164.2.33.2.45.2.42 php_reflection.c --- php_reflection.c 27 Nov 2008 19:01:22 -0000 1.164.2.33.2.45.2.42 +++ php_reflection.c 29 Nov 2008 14:44:52 -0000 @@ -4365,7 +4365,7 @@ METHOD_NOTSTATIC(reflection_property_ptr); GET_REFLECTION_OBJECT_PTR(ref); - if (!(ref->prop.flags & ZEND_ACC_PUBLIC)) { + if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && ref->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)); @@ -4409,10 +4409,13 @@ zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo); } } else { + char *class_name, *prop_name; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) { return; } - zend_update_property(Z_OBJCE_P(object), object, ref->prop.name, ref->prop.name_length, value TSRMLS_CC); + zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name); + zend_update_property(Z_OBJCE_P(object), object, prop_name, strlen(prop_name), value TSRMLS_CC); } } /* }}} */ Index: tests/reflectionProperty_setAccessible.phpt =================================================================== RCS file: /repository/php-src/ext/reflection/tests/reflectionProperty_setAccessible.phpt,v retrieving revision 1.1.2.3 diff -u -B -u -r1.1.2.3 reflectionProperty_setAccessible.phpt --- tests/reflectionProperty_setAccessible.phpt 24 May 2008 13:34:22 -0000 1.1.2.3 +++ tests/reflectionProperty_setAccessible.phpt 29 Nov 2008 14:44:52 -0000 @@ -2,43 +2,82 @@ Test ReflectionProperty::setAccessible(). --FILE-- <?php - -class TestClass { - public $pub; - public $pub2 = 5; - static public $stat = "static property"; - protected $prot = 4; - private $priv = "keepOut"; +class A { + protected $protected = 'a'; + protected static $protectedStatic = 'b'; + private $private = 'c'; + private static $privateStatic = 'd'; } -class AnotherClass { +$a = new A; +$protected = new ReflectionProperty($a, 'protected'); +$protectedStatic = new ReflectionProperty('A', 'protectedStatic'); +$private = new ReflectionProperty($a, 'private'); +$privateStatic = new ReflectionProperty('A', 'privateStatic'); + +try { + var_dump($protected->getValue($a)); } -$instance = new TestClass(); +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} -echo "\nProtected property:\n"; -$propInfo = new ReflectionProperty('TestClass', 'prot'); try { - var_dump($propInfo->getValue($instance)); + var_dump($protectedStatic->getValue()); } -catch(Exception $exc) { - echo $exc->getMessage(), "\n"; + +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} + +try { + var_dump($private->getValue($a)); } -$propInfo->setAccessible(true); -var_dump($propInfo->getValue($instance)); +catch (ReflectionException $e) { + var_dump($e->getMessage()); +} -$propInfo->setAccessible(false); try { - var_dump($propInfo->getValue($instance)); + var_dump($privateStatic->getValue()); } -catch(Exception $exc) { - echo $exc->getMessage(), "\n"; + +catch (ReflectionException $e) { + var_dump($e->getMessage()); } + +$protected->setAccessible(TRUE); +$protectedStatic->setAccessible(TRUE); +$private->setAccessible(TRUE); +$privateStatic->setAccessible(TRUE); + +var_dump($protected->getValue($a)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($a)); +var_dump($privateStatic->getValue()); + +$protected->setValue($a, 'e'); +$protectedStatic->setValue('f'); +$private->setValue($a, 'g'); +$privateStatic->setValue('h'); + +var_dump($protected->getValue($a)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($a)); +var_dump($privateStatic->getValue()); ?> --EXPECTF-- +string(44) "Cannot access non-public member A::protected" +string(50) "Cannot access non-public member A::protectedStatic" +string(42) "Cannot access non-public member A::private" +string(48) "Cannot access non-public member A::privateStatic" +string(1) "a" +string(1) "b" +string(1) "c" +string(1) "d" +string(1) "e" +string(1) "f" +string(1) "g" +string(1) "h" -Protected property: -Cannot access non-public member TestClass::prot -int(4) -Cannot access non-public member TestClass::prot ------------------------------------------------------------------------ [2008-11-29 14:48:41] [EMAIL PROTECTED] Description: ------------ ReflectionProperty::setValue() ignores the setting made with ReflectionProperty::setAccessible(TRUE). Reproduce code: --------------- <?php class A { protected $protected = 'a'; protected static $protectedStatic = 'b'; private $private = 'c'; private static $privateStatic = 'd'; } $a = new A; $protected = new ReflectionProperty($a, 'protected'); $protectedStatic = new ReflectionProperty('A', 'protectedStatic'); $private = new ReflectionProperty($a, 'private'); $privateStatic = new ReflectionProperty('A', 'privateStatic'); try { var_dump($protected->getValue($a)); } catch (ReflectionException $e) { var_dump($e->getMessage()); } try { var_dump($protectedStatic->getValue()); } catch (ReflectionException $e) { var_dump($e->getMessage()); } try { var_dump($private->getValue($a)); } catch (ReflectionException $e) { var_dump($e->getMessage()); } try { var_dump($privateStatic->getValue()); } catch (ReflectionException $e) { var_dump($e->getMessage()); } $protected->setAccessible(TRUE); $protectedStatic->setAccessible(TRUE); $private->setAccessible(TRUE); $privateStatic->setAccessible(TRUE); var_dump($protected->getValue($a)); var_dump($protectedStatic->getValue()); var_dump($private->getValue($a)); var_dump($privateStatic->getValue()); $protected->setValue($a, 'e'); $protectedStatic->setValue('f'); $private->setValue($a, 'g'); $privateStatic->setValue('h'); var_dump($protected->getValue($a)); var_dump($protectedStatic->getValue()); var_dump($private->getValue($a)); var_dump($privateStatic->getValue()); ?> Expected result: ---------------- string(44) "Cannot access non-public member A::protected" string(50) "Cannot access non-public member A::protectedStatic" string(42) "Cannot access non-public member A::private" string(48) "Cannot access non-public member A::privateStatic" string(1) "a" string(1) "b" string(1) "c" string(1) "d" string(1) "e" string(1) "f" string(1) "g" string(1) "h" Actual result: -------------- string(44) "Cannot access non-public member A::protected" string(50) "Cannot access non-public member A::protectedStatic" string(42) "Cannot access non-public member A::private" string(48) "Cannot access non-public member A::privateStatic" string(1) "a" string(1) "b" string(1) "c" string(1) "d" ReflectionException: Cannot access non-public member A::protected in /usr/local/src/php/php-5.3/reflectionProperty_setAccessible.php on line 57 Call Stack: 0.0010 355044 1. {main}() /usr/local/src/php/php-5.3/reflectionProperty_setAccessible.php:0 0.0294 365972 2. ReflectionProperty->setValue() /usr/local/src/php/php-5.3/reflectionProperty_setAccessible.php:57 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=46718&edit=1