Skip to content

Commit 37480d3

Browse files
committed
Add object to isReadable, fetch child property
1 parent 8503fa7 commit 37480d3

File tree

4 files changed

+37
-18
lines changed

4 files changed

+37
-18
lines changed

ext/reflection/php_reflection.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6709,10 +6709,12 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67096709
{
67106710
reflection_object *intern;
67116711
property_reference *ref;
6712+
zend_object *obj = NULL;
67126713
zend_string *scope_name = ZSTR_KNOWN(ZEND_STR_STATIC);
67136714

6714-
ZEND_PARSE_PARAMETERS_START(0, 1)
6715+
ZEND_PARSE_PARAMETERS_START(0, 2)
67156716
Z_PARAM_OPTIONAL
6717+
Z_PARAM_OBJ_OR_NULL(obj)
67166718
Z_PARAM_STR_OR_NULL(scope_name)
67176719
ZEND_PARSE_PARAMETERS_END();
67186720

@@ -6723,6 +6725,14 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67236725
RETURN_THROWS();
67246726
}
67256727

6728+
if (obj) {
6729+
if (!instanceof_function(obj->ce, prop->ce)) {
6730+
_DO_THROW("Given object is not an instance of the class this property was declared in");
6731+
RETURN_THROWS();
6732+
}
6733+
prop = reflection_property_get_effective_prop(ref, intern->ce, obj);
6734+
}
6735+
67266736
zend_class_entry *scope;
67276737
if (get_ce_from_scope_name(&scope, scope_name, execute_data) == FAILURE) {
67286738
RETURN_THROWS();
@@ -6739,37 +6749,48 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67396749
}
67406750
}
67416751

6752+
if (obj) {
6753+
zval *prop_val = OBJ_PROP(obj, prop->offset);
6754+
if (Z_TYPE_P(prop_val) != IS_UNDEF && !(Z_PROP_FLAG_P(prop_val) & IS_PROP_REINITABLE)) {
6755+
RETURN_FALSE;
6756+
}
6757+
}
6758+
67426759
RETURN_TRUE;
67436760
}
67446761

67456762
ZEND_METHOD(ReflectionProperty, isWritable)
67466763
{
67476764
reflection_object *intern;
67486765
property_reference *ref;
6749-
zend_object *obj;
6766+
zend_object *obj = NULL;
67506767
zend_string *scope_name = ZSTR_KNOWN(ZEND_STR_STATIC);
67516768

6752-
ZEND_PARSE_PARAMETERS_START(1, 2)
6753-
Z_PARAM_OBJ(obj)
6769+
ZEND_PARSE_PARAMETERS_START(0, 2)
67546770
Z_PARAM_OPTIONAL
6771+
Z_PARAM_OBJ_OR_NULL(obj)
67556772
Z_PARAM_STR_OR_NULL(scope_name)
67566773
ZEND_PARSE_PARAMETERS_END();
67576774

67586775
GET_REFLECTION_OBJECT_PTR(ref);
67596776
zend_property_info *prop = ref->prop;
67606777
if (!prop) {
6761-
_DO_THROW("May not use isReadable on dynamic properties");
6778+
_DO_THROW("May not use isWritable on dynamic properties");
67626779
RETURN_THROWS();
67636780
}
67646781

6782+
if (obj) {
6783+
if (!instanceof_function(obj->ce, prop->ce)) {
6784+
_DO_THROW("Given object is not an instance of the class this property was declared in");
6785+
RETURN_THROWS();
6786+
}
6787+
prop = reflection_property_get_effective_prop(ref, intern->ce, obj);
6788+
}
6789+
67656790
zend_class_entry *scope;
67666791
if (get_ce_from_scope_name(&scope, scope_name, execute_data) == FAILURE) {
67676792
RETURN_THROWS();
67686793
}
6769-
if (!instanceof_function(obj->ce, prop->ce)) {
6770-
_DO_THROW("Given object is not an instance of the class this property was declared in");
6771-
RETURN_THROWS();
6772-
}
67736794

67746795
uint32_t set_visibility = prop->flags & ZEND_ACC_PPP_SET_MASK;
67756796
if (!set_visibility) {
@@ -6786,7 +6807,7 @@ ZEND_METHOD(ReflectionProperty, isWritable)
67866807
}
67876808
}
67886809

6789-
if (prop->flags & ZEND_ACC_READONLY) {
6810+
if (obj && (prop->flags & ZEND_ACC_READONLY)) {
67906811
ZEND_ASSERT(prop->offset != ZEND_VIRTUAL_PROPERTY_OFFSET);
67916812
zval *prop_val = OBJ_PROP(obj, prop->offset);
67926813
if (Z_TYPE_P(prop_val) != IS_UNDEF && !(Z_PROP_FLAG_P(prop_val) & IS_PROP_REINITABLE)) {

ext/reflection/php_reflection.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,9 @@ public function getHook(PropertyHookType $type): ?ReflectionMethod {}
572572

573573
public function isFinal(): bool {}
574574

575-
public function isReadable(?string $scope = 'static'): bool {}
575+
public function isReadable(?object $object = null, ?string $scope = 'static'): bool {}
576576

577-
public function isWritable(object $object, ?string $scope = 'static'): bool {}
577+
public function isWritable(?object $object = null, ?string $scope = 'static'): bool {}
578578
}
579579

580580
/** @not-serializable */

ext/reflection/php_reflection_arginfo.h

Lines changed: 3 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/reflection/tests/ReflectionProperty_isReadable.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ $test = static function ($scope) {
2020
$rc = new ReflectionClass(B::class);
2121
foreach ($rc->getProperties() as $rp) {
2222
echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': ';
23-
var_dump($rp->isReadable($scope));
23+
var_dump($rp->isReadable(null, $scope));
2424
}
2525
};
2626

0 commit comments

Comments
 (0)