Skip to content

Commit 6e16e1d

Browse files
Ocramiusnikic
authored andcommitted
Make ReflectionProperty/Method always accessible
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. RFC: https://wiki.php.net/rfc/make-reflection-setaccessible-no-op Closes GH-5412.
1 parent 2763f14 commit 6e16e1d

19 files changed

+122
-274
lines changed

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ PHP 8.1 UPGRADE NOTES
371371
. PDO::getAttributes() with PDO::ATTR_SERVER_INFO and PDO::ATTR_SERVER_VERSION
372372
now return values instead of throwing PDOException.
373373

374+
- Reflection:
375+
. ReflectionProperty::setAccessible() and ReflectionMethod::setAccessible()
376+
no longer have an effect. Properties and methods are always considered
377+
accessible through reflection.
378+
RFC: https://wiki.php.net/rfc/make-reflection-setaccessible-no-op
379+
374380
========================================
375381
6. New Functions
376382
========================================

Zend/tests/bug63762.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ Bug #63762 - Sigsegv when Exception::$trace is changed by user
55
$e = new Exception();
66

77
$ref = new ReflectionProperty($e, 'trace');
8-
$ref->setAccessible(TRUE);
98

109
echo "Array of NULL:\n";
1110
$ref->setValue($e, array(NULL));

Zend/tests/bug72177.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class Parnt
2121
$this->child = new Child();
2222

2323
$prop = new \ReflectionProperty($this, 'child');
24-
$prop->setAccessible(true);
2524
$prop->setValue($this, null);
2625
}
2726
}

Zend/tests/bug72177_2.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class Bar extends Foo
2727

2828
$r = new ReflectionProperty(Foo::class, 'bar');
2929

30-
$r->setAccessible(true);
3130
echo "OK\n";
3231
?>
3332
--EXPECT--

Zend/tests/bug78921.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class OtherClass
2727

2828
$reflectionClass = new ReflectionClass('OtherClass');
2929
$reflectionProperty = $reflectionClass->getProperty('prop');
30-
$reflectionProperty->setAccessible(true);
3130
$value = $reflectionProperty->getValue();
3231
echo "Value is $value\n";
3332

ext/reflection/php_reflection.c

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ typedef struct {
171171
void *ptr;
172172
zend_class_entry *ce;
173173
reflection_type_t ref_type;
174-
unsigned int ignore_visibility:1;
175174
zend_object zo;
176175
} reflection_object;
177176

@@ -1440,7 +1439,6 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
14401439
intern->ptr = reference;
14411440
intern->ref_type = REF_TYPE_PROPERTY;
14421441
intern->ce = ce;
1443-
intern->ignore_visibility = 0;
14441442
ZVAL_STR_COPY(reflection_prop_name(object), name);
14451443
ZVAL_STR_COPY(reflection_prop_class(object), prop ? prop->ce->name : ce->name);
14461444
}
@@ -1463,7 +1461,6 @@ static void reflection_class_constant_factory(zend_string *name_str, zend_class_
14631461
intern->ptr = constant;
14641462
intern->ref_type = REF_TYPE_CLASS_CONSTANT;
14651463
intern->ce = constant->ce;
1466-
intern->ignore_visibility = 0;
14671464

14681465
ZVAL_STR_COPY(reflection_prop_name(object), name_str);
14691466
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
14821479
intern->ptr = constant;
14831480
intern->ref_type = REF_TYPE_CLASS_CONSTANT;
14841481
intern->ce = constant->ce;
1485-
intern->ignore_visibility = 0;
14861482

14871483
ZVAL_STR_COPY(reflection_prop_name(object), name_str);
14881484
ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name);
@@ -3313,15 +3309,6 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic)
33133309
RETURN_THROWS();
33143310
}
33153311

3316-
if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
3317-
zend_throw_exception_ex(reflection_exception_ptr, 0,
3318-
"Trying to invoke %s method %s::%s() from scope %s",
3319-
mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
3320-
ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name),
3321-
ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
3322-
RETURN_THROWS();
3323-
}
3324-
33253312
if (variadic) {
33263313
ZEND_PARSE_PARAMETERS_START(1, -1)
33273314
Z_PARAM_OBJECT_OR_NULL(object)
@@ -3696,16 +3683,11 @@ ZEND_METHOD(ReflectionMethod, getPrototype)
36963683
/* {{{ Sets whether non-public methods can be invoked */
36973684
ZEND_METHOD(ReflectionMethod, setAccessible)
36983685
{
3699-
reflection_object *intern;
37003686
bool visible;
37013687

37023688
if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) {
37033689
RETURN_THROWS();
37043690
}
3705-
3706-
intern = Z_REFLECTION_P(ZEND_THIS);
3707-
3708-
intern->ignore_visibility = visible;
37093691
}
37103692
/* }}} */
37113693

@@ -3745,7 +3727,6 @@ ZEND_METHOD(ReflectionClassConstant, __construct)
37453727
intern->ptr = constant;
37463728
intern->ref_type = REF_TYPE_CLASS_CONSTANT;
37473729
intern->ce = constant->ce;
3748-
intern->ignore_visibility = 0;
37493730
ZVAL_STR_COPY(reflection_prop_name(object), constname);
37503731
ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name);
37513732
}
@@ -5453,7 +5434,6 @@ ZEND_METHOD(ReflectionProperty, __construct)
54535434
intern->ptr = reference;
54545435
intern->ref_type = REF_TYPE_PROPERTY;
54555436
intern->ce = ce;
5456-
intern->ignore_visibility = 0;
54575437
}
54585438
/* }}} */
54595439

@@ -5580,13 +5560,6 @@ ZEND_METHOD(ReflectionProperty, getValue)
55805560

55815561
GET_REFLECTION_OBJECT_PTR(ref);
55825562

5583-
if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
5584-
zend_throw_exception_ex(reflection_exception_ptr, 0,
5585-
"Cannot access non-public property %s::$%s",
5586-
ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name));
5587-
RETURN_THROWS();
5588-
}
5589-
55905563
if (prop_get_flags(ref) & ZEND_ACC_STATIC) {
55915564
member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 0);
55925565
if (member_p) {
@@ -5630,13 +5603,6 @@ ZEND_METHOD(ReflectionProperty, setValue)
56305603

56315604
GET_REFLECTION_OBJECT_PTR(ref);
56325605

5633-
if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
5634-
zend_throw_exception_ex(reflection_exception_ptr, 0,
5635-
"Cannot access non-public property %s::$%s",
5636-
ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name));
5637-
RETURN_THROWS();
5638-
}
5639-
56405606
if (prop_get_flags(ref) & ZEND_ACC_STATIC) {
56415607
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) {
56425608
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) {
@@ -5669,13 +5635,6 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
56695635

56705636
GET_REFLECTION_OBJECT_PTR(ref);
56715637

5672-
if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
5673-
zend_throw_exception_ex(reflection_exception_ptr, 0,
5674-
"Cannot access non-public property %s::$%s",
5675-
ZSTR_VAL(intern->ce->name), ZSTR_VAL(ref->unmangled_name));
5676-
RETURN_THROWS();
5677-
}
5678-
56795638
if (prop_get_flags(ref) & ZEND_ACC_STATIC) {
56805639
member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 1);
56815640
if (member_p) {
@@ -5762,16 +5721,11 @@ ZEND_METHOD(ReflectionProperty, getAttributes)
57625721
/* {{{ Sets whether non-public properties can be requested */
57635722
ZEND_METHOD(ReflectionProperty, setAccessible)
57645723
{
5765-
reflection_object *intern;
57665724
bool visible;
57675725

57685726
if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) {
57695727
RETURN_THROWS();
57705728
}
5771-
5772-
intern = Z_REFLECTION_P(ZEND_THIS);
5773-
5774-
intern->ignore_visibility = visible;
57755729
}
57765730
/* }}} */
57775731

ext/reflection/tests/ReflectionClass_getProperty_003.phpt

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,9 @@ function showInfo($name) {
4949
echo $e->getMessage() . "\n";
5050
return;
5151
}
52-
try {
53-
var_dump($rp);
54-
var_dump($rp->getValue($myC));
55-
} catch (Exception $e) {
56-
echo $e->getMessage() . "\n";
57-
return;
58-
}
52+
53+
var_dump($rp);
54+
var_dump($rp->getValue($myC));
5955
}
6056

6157

@@ -110,7 +106,7 @@ object(ReflectionProperty)#%d (2) {
110106
["class"]=>
111107
string(1) "A"
112108
}
113-
Cannot access non-public property C::$protA
109+
string(10) "protA in A"
114110
--- (Reflecting on privA) ---
115111
Property C::$privA does not exist
116112
--- (Reflecting on pubB) ---
@@ -128,7 +124,7 @@ object(ReflectionProperty)#%d (2) {
128124
["class"]=>
129125
string(1) "B"
130126
}
131-
Cannot access non-public property C::$protB
127+
string(10) "protB in B"
132128
--- (Reflecting on privB) ---
133129
Property C::$privB does not exist
134130
--- (Reflecting on pubC) ---
@@ -146,15 +142,15 @@ object(ReflectionProperty)#%d (2) {
146142
["class"]=>
147143
string(1) "C"
148144
}
149-
Cannot access non-public property C::$protC
145+
string(10) "protC in C"
150146
--- (Reflecting on privC) ---
151147
object(ReflectionProperty)#%d (2) {
152148
["name"]=>
153149
string(5) "privC"
154150
["class"]=>
155151
string(1) "C"
156152
}
157-
Cannot access non-public property C::$privC
153+
string(10) "privC in C"
158154
--- (Reflecting on doesNotExist) ---
159155
Property C::$doesNotExist does not exist
160156
--- (Reflecting on A::pubC) ---
@@ -172,15 +168,15 @@ object(ReflectionProperty)#%d (2) {
172168
["class"]=>
173169
string(1) "A"
174170
}
175-
Cannot access non-public property A::$protC
171+
string(10) "protC in A"
176172
--- (Reflecting on A::privC) ---
177173
object(ReflectionProperty)#%d (2) {
178174
["name"]=>
179175
string(5) "privC"
180176
["class"]=>
181177
string(1) "A"
182178
}
183-
Cannot access non-public property A::$privC
179+
string(10) "privC in A"
184180
--- (Reflecting on B::pubC) ---
185181
object(ReflectionProperty)#%d (2) {
186182
["name"]=>
@@ -196,15 +192,15 @@ object(ReflectionProperty)#%d (2) {
196192
["class"]=>
197193
string(1) "B"
198194
}
199-
Cannot access non-public property B::$protC
195+
string(10) "protC in B"
200196
--- (Reflecting on B::privC) ---
201197
object(ReflectionProperty)#%d (2) {
202198
["name"]=>
203199
string(5) "privC"
204200
["class"]=>
205201
string(1) "B"
206202
}
207-
Cannot access non-public property B::$privC
203+
string(10) "privC in B"
208204
--- (Reflecting on c::pubC) ---
209205
object(ReflectionProperty)#%d (2) {
210206
["name"]=>
@@ -230,15 +226,15 @@ object(ReflectionProperty)#%d (2) {
230226
["class"]=>
231227
string(1) "C"
232228
}
233-
Cannot access non-public property C::$protC
229+
string(10) "protC in C"
234230
--- (Reflecting on C::privC) ---
235231
object(ReflectionProperty)#%d (2) {
236232
["name"]=>
237233
string(5) "privC"
238234
["class"]=>
239235
string(1) "C"
240236
}
241-
Cannot access non-public property C::$privC
237+
string(10) "privC in C"
242238
--- (Reflecting on X::pubC) ---
243239
Fully qualified property name X::$pubC does not specify a base class of C
244240
--- (Reflecting on X::protC) ---

ext/reflection/tests/ReflectionClass_getProperty_004.phpt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ object(ReflectionProperty)#%d (2) {
110110
["class"]=>
111111
string(1) "A"
112112
}
113-
Cannot access non-public property C::$protA
113+
string(10) "protA in A"
114114
--- (Reflecting on privA) ---
115115
Property C::$privA does not exist
116116
--- (Reflecting on pubB) ---
@@ -128,7 +128,7 @@ object(ReflectionProperty)#%d (2) {
128128
["class"]=>
129129
string(1) "B"
130130
}
131-
Cannot access non-public property C::$protB
131+
string(10) "protB in B"
132132
--- (Reflecting on privB) ---
133133
Property C::$privB does not exist
134134
--- (Reflecting on pubC) ---
@@ -146,15 +146,15 @@ object(ReflectionProperty)#%d (2) {
146146
["class"]=>
147147
string(1) "C"
148148
}
149-
Cannot access non-public property C::$protC
149+
string(10) "protC in C"
150150
--- (Reflecting on privC) ---
151151
object(ReflectionProperty)#%d (2) {
152152
["name"]=>
153153
string(5) "privC"
154154
["class"]=>
155155
string(1) "C"
156156
}
157-
Cannot access non-public property C::$privC
157+
string(10) "privC in C"
158158
--- (Reflecting on doesNotExist) ---
159159
Property C::$doesNotExist does not exist
160160
--- (Reflecting on A::pubC) ---
@@ -172,15 +172,15 @@ object(ReflectionProperty)#%d (2) {
172172
["class"]=>
173173
string(1) "A"
174174
}
175-
Cannot access non-public property A::$protC
175+
string(10) "protC in C"
176176
--- (Reflecting on A::privC) ---
177177
object(ReflectionProperty)#%d (2) {
178178
["name"]=>
179179
string(5) "privC"
180180
["class"]=>
181181
string(1) "A"
182182
}
183-
Cannot access non-public property A::$privC
183+
string(10) "privC in A"
184184
--- (Reflecting on B::pubC) ---
185185
object(ReflectionProperty)#%d (2) {
186186
["name"]=>
@@ -196,15 +196,15 @@ object(ReflectionProperty)#%d (2) {
196196
["class"]=>
197197
string(1) "B"
198198
}
199-
Cannot access non-public property B::$protC
199+
string(10) "protC in C"
200200
--- (Reflecting on B::privC) ---
201201
object(ReflectionProperty)#%d (2) {
202202
["name"]=>
203203
string(5) "privC"
204204
["class"]=>
205205
string(1) "B"
206206
}
207-
Cannot access non-public property B::$privC
207+
string(10) "privC in B"
208208
--- (Reflecting on c::pubC) ---
209209
object(ReflectionProperty)#%d (2) {
210210
["name"]=>
@@ -230,15 +230,15 @@ object(ReflectionProperty)#%d (2) {
230230
["class"]=>
231231
string(1) "C"
232232
}
233-
Cannot access non-public property C::$protC
233+
string(10) "protC in C"
234234
--- (Reflecting on C::privC) ---
235235
object(ReflectionProperty)#%d (2) {
236236
["name"]=>
237237
string(5) "privC"
238238
["class"]=>
239239
string(1) "C"
240240
}
241-
Cannot access non-public property C::$privC
241+
string(10) "privC in C"
242242
--- (Reflecting on X::pubC) ---
243243
Fully qualified property name X::$pubC does not specify a base class of C
244244
--- (Reflecting on X::protC) ---

0 commit comments

Comments
 (0)