From cad43f4f4eb17917956eed96b3130cb3c1fbc50c Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 17 Apr 2020 19:02:59 +0200 Subject: [PATCH] Make `ReflectionProperty` and `ReflectionMethod` access `private`/`protected` symbols by default With this patch, it is no longer required to call `ReflectionProperty#setAccessible()` or `ReflectionMethod#setAccessible()` with `true`. If a userland consumer already got to the point of accessing object/class information via reflection, it makes little sense for `ext/reflection` to disallow accessing `private`/`protected` symbols by default. After this patch, calling `ReflectionProperty#setAccessible(true)` or `ReflectionMethod#setAccessible(true)` on newly instantiated `ReflectionProperty` or `ReflectionMethod` respectively will have no effect. Full RFC text for the voted upon https://wiki.php.net/rfc/make-reflection-setaccessible-no-op is as follows: ``` ====== PHP RFC: Make reflection setAccessible() no-op ====== * Version: 1.0 * Date: 2021-06-13 * Author: Marco Pivetta * Status: Accepted * First Published at: https://wiki.php.net/rfc/make-reflection-setaccessible-no-op ===== Introduction ===== The `ext-reflection` API is designed to inspect static details of a code-base, as well as reading and manipulating runtime state and calling internal details of objects that are otherwise inaccessible. These methods are most notably: * `ReflectionMethod#invoke(): mixed` * `ReflectionMethod#invokeArgs(mixed ...$args): mixed` * `ReflectionProperty#getValue(object $object): mixed` * `ReflectionProperty#setValue(object $object, mixed $value): void` While breaking encapsulation principles that allow for safe coding practices, these methods are extremely valuable to tools like: * mappers * serializers * debuggers * etc. Infrastructural instrumentation is often required to do things that are in direct conflict with encapsulation itself. The 4 methods listed above change behavior depending on the only mutable state within the scope of `ext-reflection` classes, which is an "accessible" flag. This "accessibility" flag is steered by: * `ReflectionMethod#setAccessible(bool $accessible): void` * `ReflectionProperty#setAccessible(bool $accessible): void` Attempting to use any of the above listed methods without configuring accessibility first will lead to an exception being thrown. For example: class Foo { private $bar = 'a'; } (new ReflectionProperty(Foo::class, 'bar'))->getValue(); https://3v4l.org/ousrD : Fatal error: Uncaught ReflectionException: Cannot access non-public property Foo::$bar in ==== The problem with mutability ==== By having `ReflectionProperty#setAccessible()` and `ReflectionMethod#setAccessible()`, any consumer of a `ReflectionMethod` or `ReflectionProperty` that is given by a third party must ensure that `#setAccessible()` is called: function doSomethingWithState(MyObject $o, ReflectionProperty $p) : void { $p->setAccessible(true); // wasteful safety check doSomethingWith($p->getValue($o)); } In addition to that, any developer that is intentionally using the reflection API (after having evaluated its trade-off) will have to use this obnoxious syntax in order to use it at its fullest: $p = new ReflectionProperty(MyClass::class, 'propertyName'); $p->setAccessible(true); // now $p is usable ===== Proposal ===== This RFC proposes to: * make `ReflectionProperty` and `ReflectionMethod` behave as if `#setAccessible(true)` had been called upfront * make `ReflectionProperty#setAccessible()` and `ReflectionMethod#setAccessible()` no-op operations, with no side-effects nor state mutation involved After the RFC is successfully accepted/implemented, the following code should no longer throw, improving therefore the ergonomics around reflection. class Foo { private $bar = 'a'; } (new ReflectionProperty(Foo::class, 'bar'))->getValue(); ==== Deprecations ==== In order to ease migration to PHP 8.1, and minimize runtime side-effects, a deprecation is explicitly avoided in this RFC. Instead, a deprecation should be introduced when a new/separate RFC plans for the removal of `ReflectionProperty#setAccessible()` and `ReflectionMethod#setAccessible()`. Such RFC will be raised **after** the release of PHP 8.1, if this RFC is accepted. ===== Backward Incompatible Changes ===== Although of minimal concern, it is true that some behavior will change: * `ReflectionProperty#getValue()` will no longer throw an exception when used against a protected/private property * `ReflectionProperty#setValue()` will no longer throw an exception when used against a protected/private property * `ReflectionMethod#invoke()` will no longer throw an exception when used against a protected/private method * `ReflectionMethod#invokeArgs()` will no longer throw an exception when used against a protected/private method * for extensions developers, `reflection_object->ignore_visibility` no longer exists ===== Proposed PHP Version(s) ===== 8.1 ===== RFC Impact ===== ==== To SAPIs ==== None ==== To Existing Extensions ==== None ==== To Opcache ==== None ==== New Constants ==== None ==== php.ini Defaults ==== None ===== Open Issues ===== None ===== Proposed Voting Choices ===== Accept turning `ReflectionProperty#setAccessible()` and `ReflectionMethod#setAccessible()` into a no-op? (yes/no) ===== Patches and Tests ===== https://github.com/php/php-src/pull/5412 ===== Vote ===== This is a Yes/No vote, requiring a 2/3 majority. Voting started on 2021-06-23 and ends on 2021-07-07. * Yes * No ``` --- Zend/tests/bug63762.phpt | 1 - Zend/tests/bug72177.phpt | 1 - Zend/tests/bug72177_2.phpt | 1 - Zend/tests/bug78921.phpt | 1 - ext/reflection/php_reflection.c | 46 ------- .../ReflectionClass_getProperty_003.phpt | 30 ++--- .../ReflectionClass_getProperty_004.phpt | 20 +-- .../ReflectionMethod_invokeArgs_error3.phpt | 9 +- .../tests/ReflectionMethod_invoke_error1.phpt | 9 +- ...n_abstract_method_after_setAccessible.phpt | 3 +- .../tests/ReflectionMethod_setAccessible.phpt | 97 +++----------- .../ReflectionProperty_getValue_error.phpt | 12 +- .../ReflectionProperty_isInitialized.phpt | 9 +- .../ReflectionProperty_setAccessible.phpt | 124 +++++++----------- .../ReflectionProperty_setValue_error.phpt | 14 +- ext/reflection/tests/bug37816.phpt | 11 +- ext/reflection/tests/bug49719.phpt | 1 - ext/reflection/tests/bug72174.phpt | 1 - 18 files changed, 116 insertions(+), 274 deletions(-) diff --git a/Zend/tests/bug63762.phpt b/Zend/tests/bug63762.phpt index 9e486c43f7711..33a5f06d75643 100644 --- a/Zend/tests/bug63762.phpt +++ b/Zend/tests/bug63762.phpt @@ -5,7 +5,6 @@ Bug #63762 - Sigsegv when Exception::$trace is changed by user $e = new Exception(); $ref = new ReflectionProperty($e, 'trace'); -$ref->setAccessible(TRUE); echo "Array of NULL:\n"; $ref->setValue($e, array(NULL)); diff --git a/Zend/tests/bug72177.phpt b/Zend/tests/bug72177.phpt index b5658d354ac28..18505197fdea5 100644 --- a/Zend/tests/bug72177.phpt +++ b/Zend/tests/bug72177.phpt @@ -21,7 +21,6 @@ class Parnt $this->child = new Child(); $prop = new \ReflectionProperty($this, 'child'); - $prop->setAccessible(true); $prop->setValue($this, null); } } diff --git a/Zend/tests/bug72177_2.phpt b/Zend/tests/bug72177_2.phpt index 718d6c061e248..1683d265ac347 100644 --- a/Zend/tests/bug72177_2.phpt +++ b/Zend/tests/bug72177_2.phpt @@ -27,7 +27,6 @@ class Bar extends Foo $r = new ReflectionProperty(Foo::class, 'bar'); -$r->setAccessible(true); echo "OK\n"; ?> --EXPECT-- diff --git a/Zend/tests/bug78921.phpt b/Zend/tests/bug78921.phpt index a36878808123f..698e816856061 100644 --- a/Zend/tests/bug78921.phpt +++ b/Zend/tests/bug78921.phpt @@ -27,7 +27,6 @@ class OtherClass $reflectionClass = new ReflectionClass('OtherClass'); $reflectionProperty = $reflectionClass->getProperty('prop'); -$reflectionProperty->setAccessible(true); $value = $reflectionProperty->getValue(); echo "Value is $value\n"; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 7a3bdf51419b6..7255eef358129 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -171,7 +171,6 @@ typedef struct { void *ptr; zend_class_entry *ce; reflection_type_t ref_type; - unsigned int ignore_visibility:1; zend_object zo; } reflection_object; @@ -1440,7 +1439,6 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name, intern->ptr = reference; intern->ref_type = REF_TYPE_PROPERTY; intern->ce = ce; - intern->ignore_visibility = 0; ZVAL_STR_COPY(reflection_prop_name(object), name); ZVAL_STR_COPY(reflection_prop_class(object), prop ? prop->ce->name : ce->name); } @@ -1463,7 +1461,6 @@ static void reflection_class_constant_factory(zend_string *name_str, zend_class_ intern->ptr = constant; intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; - intern->ignore_visibility = 0; ZVAL_STR_COPY(reflection_prop_name(object), name_str); ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name); @@ -1482,7 +1479,6 @@ static void reflection_enum_case_factory(zend_class_entry *ce, zend_string *name intern->ptr = constant; intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; - intern->ignore_visibility = 0; ZVAL_STR_COPY(reflection_prop_name(object), name_str); ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name); @@ -3313,15 +3309,6 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) RETURN_THROWS(); } - if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Trying to invoke %s method %s::%s() from scope %s", - mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private", - ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name), - ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); - RETURN_THROWS(); - } - if (variadic) { ZEND_PARSE_PARAMETERS_START(1, -1) Z_PARAM_OBJECT_OR_NULL(object) @@ -3696,16 +3683,11 @@ ZEND_METHOD(ReflectionMethod, getPrototype) /* {{{ Sets whether non-public methods can be invoked */ ZEND_METHOD(ReflectionMethod, setAccessible) { - reflection_object *intern; bool visible; if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) { RETURN_THROWS(); } - - intern = Z_REFLECTION_P(ZEND_THIS); - - intern->ignore_visibility = visible; } /* }}} */ @@ -3745,7 +3727,6 @@ ZEND_METHOD(ReflectionClassConstant, __construct) intern->ptr = constant; intern->ref_type = REF_TYPE_CLASS_CONSTANT; intern->ce = constant->ce; - intern->ignore_visibility = 0; ZVAL_STR_COPY(reflection_prop_name(object), constname); ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name); } @@ -5453,7 +5434,6 @@ ZEND_METHOD(ReflectionProperty, __construct) intern->ptr = reference; intern->ref_type = REF_TYPE_PROPERTY; intern->ce = ce; - intern->ignore_visibility = 0; } /* }}} */ @@ -5580,13 +5560,6 @@ ZEND_METHOD(ReflectionProperty, getValue) GET_REFLECTION_OBJECT_PTR(ref); - if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Cannot access non-public property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); - } - if (prop_get_flags(ref) & ZEND_ACC_STATIC) { member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 0); if (member_p) { @@ -5630,13 +5603,6 @@ ZEND_METHOD(ReflectionProperty, setValue) GET_REFLECTION_OBJECT_PTR(ref); - if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Cannot access non-public property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); - } - if (prop_get_flags(ref) & ZEND_ACC_STATIC) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) { @@ -5669,13 +5635,6 @@ ZEND_METHOD(ReflectionProperty, isInitialized) GET_REFLECTION_OBJECT_PTR(ref); - if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Cannot access non-public property %s::$%s", - ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name)); - RETURN_THROWS(); - } - if (prop_get_flags(ref) & ZEND_ACC_STATIC) { member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 1); if (member_p) { @@ -5762,16 +5721,11 @@ ZEND_METHOD(ReflectionProperty, getAttributes) /* {{{ Sets whether non-public properties can be requested */ ZEND_METHOD(ReflectionProperty, setAccessible) { - reflection_object *intern; bool visible; if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) { RETURN_THROWS(); } - - intern = Z_REFLECTION_P(ZEND_THIS); - - intern->ignore_visibility = visible; } /* }}} */ diff --git a/ext/reflection/tests/ReflectionClass_getProperty_003.phpt b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt index b3c2ceb88ade1..c47f9e4fffd7c 100644 --- a/ext/reflection/tests/ReflectionClass_getProperty_003.phpt +++ b/ext/reflection/tests/ReflectionClass_getProperty_003.phpt @@ -49,13 +49,9 @@ function showInfo($name) { echo $e->getMessage() . "\n"; return; } - try { - var_dump($rp); - var_dump($rp->getValue($myC)); - } catch (Exception $e) { - echo $e->getMessage() . "\n"; - return; - } + + var_dump($rp); + var_dump($rp->getValue($myC)); } @@ -110,7 +106,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "A" } -Cannot access non-public property C::$protA +string(10) "protA in A" --- (Reflecting on privA) --- Property C::$privA does not exist --- (Reflecting on pubB) --- @@ -128,7 +124,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "B" } -Cannot access non-public property C::$protB +string(10) "protB in B" --- (Reflecting on privB) --- Property C::$privB does not exist --- (Reflecting on pubC) --- @@ -146,7 +142,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$protC +string(10) "protC in C" --- (Reflecting on privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -154,7 +150,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$privC +string(10) "privC in C" --- (Reflecting on doesNotExist) --- Property C::$doesNotExist does not exist --- (Reflecting on A::pubC) --- @@ -172,7 +168,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "A" } -Cannot access non-public property A::$protC +string(10) "protC in A" --- (Reflecting on A::privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -180,7 +176,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "A" } -Cannot access non-public property A::$privC +string(10) "privC in A" --- (Reflecting on B::pubC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -196,7 +192,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "B" } -Cannot access non-public property B::$protC +string(10) "protC in B" --- (Reflecting on B::privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -204,7 +200,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "B" } -Cannot access non-public property B::$privC +string(10) "privC in B" --- (Reflecting on c::pubC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -230,7 +226,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$protC +string(10) "protC in C" --- (Reflecting on C::privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -238,7 +234,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$privC +string(10) "privC in C" --- (Reflecting on X::pubC) --- Fully qualified property name X::$pubC does not specify a base class of C --- (Reflecting on X::protC) --- diff --git a/ext/reflection/tests/ReflectionClass_getProperty_004.phpt b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt index bbc9963d8ae84..32e2d7876f6d5 100644 --- a/ext/reflection/tests/ReflectionClass_getProperty_004.phpt +++ b/ext/reflection/tests/ReflectionClass_getProperty_004.phpt @@ -110,7 +110,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "A" } -Cannot access non-public property C::$protA +string(10) "protA in A" --- (Reflecting on privA) --- Property C::$privA does not exist --- (Reflecting on pubB) --- @@ -128,7 +128,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "B" } -Cannot access non-public property C::$protB +string(10) "protB in B" --- (Reflecting on privB) --- Property C::$privB does not exist --- (Reflecting on pubC) --- @@ -146,7 +146,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$protC +string(10) "protC in C" --- (Reflecting on privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -154,7 +154,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$privC +string(10) "privC in C" --- (Reflecting on doesNotExist) --- Property C::$doesNotExist does not exist --- (Reflecting on A::pubC) --- @@ -172,7 +172,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "A" } -Cannot access non-public property A::$protC +string(10) "protC in C" --- (Reflecting on A::privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -180,7 +180,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "A" } -Cannot access non-public property A::$privC +string(10) "privC in A" --- (Reflecting on B::pubC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -196,7 +196,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "B" } -Cannot access non-public property B::$protC +string(10) "protC in C" --- (Reflecting on B::privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -204,7 +204,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "B" } -Cannot access non-public property B::$privC +string(10) "privC in B" --- (Reflecting on c::pubC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -230,7 +230,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$protC +string(10) "protC in C" --- (Reflecting on C::privC) --- object(ReflectionProperty)#%d (2) { ["name"]=> @@ -238,7 +238,7 @@ object(ReflectionProperty)#%d (2) { ["class"]=> string(1) "C" } -Cannot access non-public property C::$privC +string(10) "privC in C" --- (Reflecting on X::pubC) --- Fully qualified property name X::$pubC does not specify a base class of C --- (Reflecting on X::protC) --- diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt index c3bab48d6f6ad..1c405600f161b 100644 --- a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt +++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt @@ -49,11 +49,7 @@ echo "\nStatic method:\n"; var_dump($staticMethod->invokeArgs(null, array())); echo "\nPrivate method:\n"; -try { - var_dump($privateMethod->invokeArgs($testClassInstance, array())); -} catch (ReflectionException $e) { - var_dump($e->getMessage()); -} +var_dump($privateMethod->invokeArgs($testClassInstance, array())); echo "\nAbstract method:\n"; $abstractMethod = new ReflectionMethod("AbstractClass::foo"); @@ -79,7 +75,8 @@ Exception: Using $this when not in object context NULL Private method: -string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod" +Called privateMethod() +NULL Abstract method: string(53) "Trying to invoke abstract method AbstractClass::foo()" diff --git a/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt index 64a38e18a198a..620f993325e06 100644 --- a/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt +++ b/ext/reflection/tests/ReflectionMethod_invoke_error1.phpt @@ -42,11 +42,7 @@ try { } echo "\nPrivate method:\n"; -try { - var_dump($privateMethod->invoke($testClassInstance)); -} catch (ReflectionException $e) { - var_dump($e->getMessage()); -} +var_dump($privateMethod->invoke($testClassInstance)); echo "\nAbstract method:\n"; $abstractMethod = new ReflectionMethod("AbstractClass::foo"); @@ -65,7 +61,8 @@ invoke() on a non-instance: string(72) "Given object is not an instance of the class this method was declared in" Private method: -string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod" +Called privateMethod() +NULL Abstract method: string(53) "Trying to invoke abstract method AbstractClass::foo()" diff --git a/ext/reflection/tests/ReflectionMethod_invoke_on_abstract_method_after_setAccessible.phpt b/ext/reflection/tests/ReflectionMethod_invoke_on_abstract_method_after_setAccessible.phpt index c564d6c16b367..67f6fe5dca42e 100644 --- a/ext/reflection/tests/ReflectionMethod_invoke_on_abstract_method_after_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionMethod_invoke_on_abstract_method_after_setAccessible.phpt @@ -1,5 +1,5 @@ --TEST-- -ReflectionMethod::invoke() on an abstract method should fail even after calling setAccessible(true) +ReflectionMethod::invoke() on an abstract method should fail --FILE-- setAccessible(true); try { var_dump($rm->invoke(null)); } catch (ReflectionException $e) { diff --git a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt index 79a8fbe8ae05b..92312528a0419 100644 --- a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt @@ -1,5 +1,5 @@ --TEST-- -Test ReflectionMethod::setAccessible(). +Test that ReflectionMethod::setAccessible() has no effects --FILE-- invoke(new A, NULL); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $private->invokeArgs(new A, array(NULL)); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $privateStatic->invoke(NULL, NULL); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $privateStatic->invokeArgs(NULL, array(NULL)); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $protected->invoke(new A, NULL); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $protected->invokeArgs(new A, array(NULL)); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $protectedStatic->invoke(NULL, NULL); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - $protectedStatic->invokeArgs(NULL, array(NULL)); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} +$private->invoke(new A, NULL); +$private->invokeArgs(new A, array(NULL)); +$privateStatic->invoke(NULL, NULL); +$privateStatic->invokeArgs(NULL, array(NULL)); +$protected->invoke(new A, NULL); +$protected->invokeArgs(new A, array(NULL)); +$protectedStatic->invoke(NULL, NULL); +$protectedStatic->invokeArgs(NULL, array(NULL)); -$private->setAccessible(TRUE); -$privateStatic->setAccessible(TRUE); -$protected->setAccessible(TRUE); -$protectedStatic->setAccessible(TRUE); +$private->setAccessible(FALSE); +$privateStatic->setAccessible(FALSE); +$protected->setAccessible(FALSE); +$protectedStatic->setAccessible(FALSE); $private->invoke(new A, NULL); $private->invokeArgs(new A, array(NULL)); @@ -93,14 +38,14 @@ $protectedStatic->invoke(NULL, NULL); $protectedStatic->invokeArgs(NULL, array(NULL)); ?> --EXPECT-- -string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod" -string(73) "Trying to invoke private method A::aPrivate() from scope ReflectionMethod" -string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod" -string(79) "Trying to invoke private method A::aPrivateStatic() from scope ReflectionMethod" -string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod" -string(77) "Trying to invoke protected method A::aProtected() from scope ReflectionMethod" -string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod" -string(83) "Trying to invoke protected method A::aProtectedStatic() from scope ReflectionMethod" +A::aPrivate +A::aPrivate +A::aPrivateStatic +A::aPrivateStatic +A::aProtected +A::aProtected +A::aProtectedStatic +A::aProtectedStatic A::aPrivate A::aPrivate A::aPrivateStatic diff --git a/ext/reflection/tests/ReflectionProperty_getValue_error.phpt b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt index 544c1d6b254f7..a898eea6bea0e 100644 --- a/ext/reflection/tests/ReflectionProperty_getValue_error.phpt +++ b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt @@ -29,13 +29,8 @@ try { } echo "\nProtected property:\n"; -try { - $propInfo = new ReflectionProperty('TestClass', 'prot'); - var_dump($propInfo->getValue($instance)); -} -catch(Exception $exc) { - echo $exc->getMessage(); -} +$propInfo = new ReflectionProperty('TestClass', 'prot'); +var_dump($propInfo->getValue($instance)); echo "\n\nInvalid instance:\n"; $propInfo = new ReflectionProperty('TestClass', 'pub2'); @@ -60,7 +55,8 @@ Static property / too many args: ReflectionProperty::getValue() expects at most 1 argument, 2 given Protected property: -Cannot access non-public property TestClass::$prot +int(4) + Invalid instance: Given object is not an instance of the class this property was declared in diff --git a/ext/reflection/tests/ReflectionProperty_isInitialized.phpt b/ext/reflection/tests/ReflectionProperty_isInitialized.phpt index 74e25252d1a0e..cf0903d98cb73 100644 --- a/ext/reflection/tests/ReflectionProperty_isInitialized.phpt +++ b/ext/reflection/tests/ReflectionProperty_isInitialized.phpt @@ -44,12 +44,7 @@ var_dump($rp->isInitialized($a)); echo "Visibility handling:\n"; $rp = new ReflectionProperty('A', 'p'); -try { - var_dump($rp->isInitialized($a)); -} catch (ReflectionException $e) { - echo $e->getMessage(), "\n"; -} -$rp->setAccessible(true); +var_dump($rp->isInitialized($a)); var_dump($rp->isInitialized($a)); echo "Object type:\n"; @@ -109,7 +104,7 @@ Dynamic properties: bool(true) bool(false) Visibility handling: -Cannot access non-public property A::$p +bool(false) bool(false) Object type: bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt index f0d49a56cb25d..80ed15d690362 100644 --- a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt @@ -1,5 +1,5 @@ --TEST-- -Test ReflectionProperty::setAccessible(). +Test that ReflectionProperty::setAccessible() has no effects --FILE-- 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)); @@ -69,57 +32,61 @@ var_dump($protectedStatic->getValue()); var_dump($private->getValue($a)); var_dump($privateStatic->getValue()); +$protected->setAccessible(FALSE); +$protectedStatic->setAccessible(FALSE); +$private->setAccessible(FALSE); +$privateStatic->setAccessible(FALSE); + +var_dump($protected->getValue($a)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($a)); +var_dump($privateStatic->getValue()); + +$protected->setValue($a, 'i'); +$protectedStatic->setValue('j'); +$private->setValue($a, 'k'); +$privateStatic->setValue('l'); + +var_dump($protected->getValue($a)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($a)); +var_dump($privateStatic->getValue()); + $a = new A; $b = new B; $protected = new ReflectionProperty($b, 'protected'); $protectedStatic = new ReflectionProperty('B', 'protectedStatic'); $private = new ReflectionProperty($a, 'private'); -try { - var_dump($protected->getValue($b)); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} - -try { - var_dump($protectedStatic->getValue()); -} - -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} +var_dump($protected->getValue($b)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($b)); -try { - var_dump($private->getValue($b)); -} +$protected->setValue($b, 'e'); +$protectedStatic->setValue('f'); +$private->setValue($b, 'g'); -catch (ReflectionException $e) { - var_dump($e->getMessage()); -} +var_dump($protected->getValue($b)); +var_dump($protectedStatic->getValue()); +var_dump($private->getValue($b)); -$protected->setAccessible(TRUE); -$protectedStatic->setAccessible(TRUE); -$private->setAccessible(TRUE); +$protected->setAccessible(FALSE); +$protectedStatic->setAccessible(FALSE); +$private->setAccessible(FALSE); var_dump($protected->getValue($b)); var_dump($protectedStatic->getValue()); var_dump($private->getValue($b)); -$protected->setValue($b, 'e'); -$protectedStatic->setValue('f'); -$private->setValue($b, 'g'); +$protected->setValue($b, 'h'); +$protectedStatic->setValue('i'); +$private->setValue($b, 'j'); var_dump($protected->getValue($b)); var_dump($protectedStatic->getValue()); var_dump($private->getValue($b)); ?> --EXPECT-- -string(47) "Cannot access non-public property A::$protected" -string(53) "Cannot access non-public property A::$protectedStatic" -string(45) "Cannot access non-public property A::$private" -string(51) "Cannot access non-public property A::$privateStatic" string(1) "a" string(1) "b" string(1) "c" @@ -128,12 +95,23 @@ string(1) "e" string(1) "f" string(1) "g" string(1) "h" -string(47) "Cannot access non-public property B::$protected" -string(53) "Cannot access non-public property B::$protectedStatic" -string(45) "Cannot access non-public property A::$private" -string(1) "a" +string(1) "e" string(1) "f" +string(1) "g" +string(1) "h" +string(1) "i" +string(1) "j" +string(1) "k" +string(1) "l" +string(1) "a" +string(1) "j" string(1) "c" string(1) "e" string(1) "f" string(1) "g" +string(1) "e" +string(1) "f" +string(1) "g" +string(1) "h" +string(1) "i" +string(1) "j" diff --git a/ext/reflection/tests/ReflectionProperty_setValue_error.phpt b/ext/reflection/tests/ReflectionProperty_setValue_error.phpt index 4b29be8f73e6c..24fd8d1aaccb8 100644 --- a/ext/reflection/tests/ReflectionProperty_setValue_error.phpt +++ b/ext/reflection/tests/ReflectionProperty_setValue_error.phpt @@ -19,13 +19,10 @@ $instanceWithNoProperties = new AnotherClass(); $propInfo = new ReflectionProperty('TestClass', 'pub2'); echo "\nProtected property:\n"; -try { - $propInfo = new ReflectionProperty('TestClass', 'prot'); - var_dump($propInfo->setValue($instance, "NewValue")); -} -catch(Exception $exc) { - echo $exc->getMessage(); -} + +$propInfo = new ReflectionProperty('TestClass', 'prot'); +$propInfo->setValue($instance, "NewValue"); +var_dump($propInfo->getValue($instance)); echo "\n\nInstance without property:\n"; $propInfo = new ReflectionProperty('TestClass', 'pub2'); @@ -34,7 +31,8 @@ var_dump($instanceWithNoProperties->pub2); ?> --EXPECT-- Protected property: -Cannot access non-public property TestClass::$prot +string(8) "NewValue" + Instance without property: NULL diff --git a/ext/reflection/tests/bug37816.phpt b/ext/reflection/tests/bug37816.phpt index 42be0e6ede1b1..df61569ae330d 100644 --- a/ext/reflection/tests/bug37816.phpt +++ b/ext/reflection/tests/bug37816.phpt @@ -12,15 +12,8 @@ $o = new TestClass; $r = new ReflectionProperty($o, 'p'); -try -{ - $x = $r->getValue($o); -} -catch (Exception $e) -{ - echo 'Caught: ' . $e->getMessage() . "\n"; -} +var_dump($r->getValue($o)); ?> --EXPECT-- -Caught: Cannot access non-public property TestClass::$p +int(2) diff --git a/ext/reflection/tests/bug49719.phpt b/ext/reflection/tests/bug49719.phpt index b39ca3481c55c..1a0ffca4bd2dc 100644 --- a/ext/reflection/tests/bug49719.phpt +++ b/ext/reflection/tests/bug49719.phpt @@ -32,7 +32,6 @@ class B2 extends A2 { $b2 = new ReflectionClass('B2'); $prop = $b2->getProperty('a'); -$prop->setAccessible(true); var_dump($prop->getValue(new b2)); ?> diff --git a/ext/reflection/tests/bug72174.phpt b/ext/reflection/tests/bug72174.phpt index dacfc0e55e096..810b914692d70 100644 --- a/ext/reflection/tests/bug72174.phpt +++ b/ext/reflection/tests/bug72174.phpt @@ -27,7 +27,6 @@ class Foo $instance = new Foo(); $reflectionBar = (new ReflectionProperty(Foo::class, 'bar')); -$reflectionBar->setAccessible(true); var_dump($reflectionBar->getValue($instance)); ?>