Skip to content

Commit cab3331

Browse files
committed
Support static properties
1 parent 318627b commit cab3331

File tree

3 files changed

+95
-6
lines changed

3 files changed

+95
-6
lines changed

ext/reflection/php_reflection.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6695,6 +6695,10 @@ ZEND_METHOD(ReflectionProperty, isReadable)
66956695

66966696
zend_property_info *prop = ref->prop;
66976697
if (prop && obj) {
6698+
if (prop->flags & ZEND_ACC_STATIC) {
6699+
_DO_THROW("null is expected as object argument for static properties");
6700+
RETURN_THROWS();
6701+
}
66986702
if (!instanceof_function(obj->ce, prop->ce)) {
66996703
_DO_THROW("Given object is not an instance of the class this property was declared in");
67006704
RETURN_THROWS();
@@ -6733,7 +6737,10 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67336737
}
67346738

67356739
if (!check_visibility(prop->flags & ZEND_ACC_PPP_MASK, prop->ce, scope)) {
6736-
goto handle_magic_get;
6740+
if (!(prop->flags & ZEND_ACC_STATIC)) {
6741+
goto handle_magic_get;
6742+
}
6743+
RETURN_FALSE;
67376744
}
67386745

67396746
if (prop->flags & ZEND_ACC_VIRTUAL) {
@@ -6749,6 +6756,12 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67496756
}
67506757
RETURN_FALSE;
67516758
}
6759+
} else if (prop->flags & ZEND_ACC_STATIC) {
6760+
if (ce->default_static_members_count && !CE_STATIC_MEMBERS(ce)) {
6761+
zend_class_init_statics(ce);
6762+
}
6763+
zval *prop_val = CE_STATIC_MEMBERS(ce) + prop->offset;
6764+
RETURN_BOOL(!Z_ISUNDEF_P(prop_val));
67526765
}
67536766

67546767
RETURN_TRUE;
@@ -6771,6 +6784,10 @@ ZEND_METHOD(ReflectionProperty, isWritable)
67716784

67726785
zend_property_info *prop = ref->prop;
67736786
if (prop && obj) {
6787+
if (prop->flags & ZEND_ACC_STATIC) {
6788+
_DO_THROW("null is expected as object argument for static properties");
6789+
RETURN_THROWS();
6790+
}
67746791
if (!instanceof_function(obj->ce, prop->ce)) {
67756792
_DO_THROW("Given object is not an instance of the class this property was declared in");
67766793
RETURN_THROWS();
@@ -6797,7 +6814,10 @@ ZEND_METHOD(ReflectionProperty, isWritable)
67976814
}
67986815

67996816
if (!check_visibility(prop->flags & ZEND_ACC_PPP_MASK, prop->ce, scope)) {
6800-
goto handle_magic_set;
6817+
if (!(prop->flags & ZEND_ACC_STATIC)) {
6818+
goto handle_magic_set;
6819+
}
6820+
RETURN_FALSE;
68016821
}
68026822
uint32_t set_visibility = prop->flags & ZEND_ACC_PPP_SET_MASK;
68036823
if (!set_visibility) {
@@ -6812,10 +6832,7 @@ ZEND_METHOD(ReflectionProperty, isWritable)
68126832
if (!prop->hooks[ZEND_PROPERTY_HOOK_SET]) {
68136833
RETURN_FALSE;
68146834
}
6815-
}
6816-
6817-
if (obj && (prop->flags & ZEND_ACC_READONLY)) {
6818-
ZEND_ASSERT(prop->offset != ZEND_VIRTUAL_PROPERTY_OFFSET);
6835+
} else if (obj && (prop->flags & ZEND_ACC_READONLY)) {
68196836
zval *prop_val = OBJ_PROP(obj, prop->offset);
68206837
if (Z_TYPE_P(prop_val) != IS_UNDEF && !(Z_PROP_FLAG_P(prop_val) & IS_PROP_REINITABLE)) {
68216838
RETURN_FALSE;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Test ReflectionProperty::isReadable() static
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public static $a;
8+
public static int $b;
9+
public static int $c = 42;
10+
protected static int $d = 42;
11+
private static int $e = 42;
12+
public private(set) static int $f = 42;
13+
}
14+
15+
$r = new ReflectionProperty('A', 'a');
16+
try {
17+
$r->isReadable(null, new A);
18+
} catch (Exception $e) {
19+
echo $e::class, ': ', $e->getMessage(), "\n";
20+
}
21+
22+
$rc = new ReflectionClass('A');
23+
foreach ($rc->getProperties() as $rp) {
24+
echo $rp->getName() . ' from global: ';
25+
var_dump($rp->isReadable(null));
26+
}
27+
28+
?>
29+
--EXPECT--
30+
ReflectionException: null is expected as object argument for static properties
31+
a from global: bool(true)
32+
b from global: bool(false)
33+
c from global: bool(true)
34+
d from global: bool(false)
35+
e from global: bool(false)
36+
f from global: bool(true)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Test ReflectionProperty::isWritable() static
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public static $a;
8+
public static int $b;
9+
public static int $c = 42;
10+
protected static int $d = 42;
11+
private static int $e = 42;
12+
public private(set) static int $f = 42;
13+
}
14+
15+
$r = new ReflectionProperty('A', 'a');
16+
try {
17+
$r->isWritable(null, new A);
18+
} catch (Exception $e) {
19+
echo $e::class, ': ', $e->getMessage(), "\n";
20+
}
21+
22+
$rc = new ReflectionClass('A');
23+
foreach ($rc->getProperties() as $rp) {
24+
echo $rp->getName() . ' from global: ';
25+
var_dump($rp->isWritable(null));
26+
}
27+
28+
?>
29+
--EXPECT--
30+
ReflectionException: null is expected as object argument for static properties
31+
a from global: bool(true)
32+
b from global: bool(true)
33+
c from global: bool(true)
34+
d from global: bool(false)
35+
e from global: bool(false)
36+
f from global: bool(false)

0 commit comments

Comments
 (0)