Skip to content

Commit 7a52bf2

Browse files
committed
Add ReflectionProperty::getDefaultValue and ReflectionProperty::hasDefaultValue
1 parent 4766368 commit 7a52bf2

File tree

5 files changed

+229
-0
lines changed

5 files changed

+229
-0
lines changed

ext/reflection/php_reflection.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5686,6 +5686,90 @@ ZEND_METHOD(reflection_property, hasType)
56865686
}
56875687
/* }}} */
56885688

5689+
/* {{{ proto public bool ReflectionProperty::hasDefaultValue()
5690+
Returns whether property has a default value */
5691+
ZEND_METHOD(reflection_property, hasDefaultValue)
5692+
{
5693+
reflection_object *intern;
5694+
property_reference *ref;
5695+
zend_property_info *prop_info;
5696+
zval *prop;
5697+
zend_class_entry *ce;
5698+
5699+
if (zend_parse_parameters_none() == FAILURE) {
5700+
RETURN_THROWS();
5701+
}
5702+
5703+
GET_REFLECTION_OBJECT_PTR(ref);
5704+
5705+
prop_info = ref->prop;
5706+
5707+
if (prop_info == NULL) {
5708+
RETURN_FALSE;
5709+
}
5710+
5711+
ce = prop_info->ce;
5712+
5713+
if ((prop_info->flags & ZEND_ACC_STATIC) != 0) {
5714+
prop = &ce->default_static_members_table[prop_info->offset];
5715+
ZVAL_DEINDIRECT(prop);
5716+
} else {
5717+
prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
5718+
}
5719+
5720+
RETURN_BOOL(!Z_ISUNDEF_P(prop));
5721+
}
5722+
/* }}} */
5723+
5724+
/* {{{ proto public mixed ReflectionProperty::getDefaultValue()
5725+
Returns the default value of a property */
5726+
ZEND_METHOD(reflection_property, getDefaultValue)
5727+
{
5728+
reflection_object *intern;
5729+
property_reference *ref;
5730+
zend_property_info *prop_info;
5731+
zval *prop;
5732+
zend_class_entry *ce;
5733+
5734+
if (zend_parse_parameters_none() == FAILURE) {
5735+
RETURN_THROWS();
5736+
}
5737+
5738+
GET_REFLECTION_OBJECT_PTR(ref);
5739+
5740+
prop_info = ref->prop;
5741+
5742+
if (prop_info == NULL) {
5743+
return; // throw exception?
5744+
}
5745+
5746+
ce = prop_info->ce;
5747+
5748+
if ((prop_info->flags & ZEND_ACC_STATIC) != 0) {
5749+
prop = &ce->default_static_members_table[prop_info->offset];
5750+
ZVAL_DEINDIRECT(prop);
5751+
} else {
5752+
prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
5753+
}
5754+
5755+
if (Z_ISUNDEF_P(prop)) {
5756+
return;
5757+
}
5758+
5759+
/* copy: enforce read only access */
5760+
ZVAL_DEREF(prop);
5761+
ZVAL_COPY_OR_DUP(return_value, prop);
5762+
5763+
/* this is necessary to make it able to work with default array
5764+
* properties, returned to user */
5765+
if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
5766+
if (UNEXPECTED(zval_update_constant_ex(return_value, ce) != SUCCESS)) {
5767+
RETURN_THROWS();
5768+
}
5769+
}
5770+
}
5771+
/* }}} */
5772+
56895773
/* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException
56905774
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
56915775
ZEND_METHOD(reflection_extension, export)
@@ -6461,6 +6545,8 @@ static const zend_function_entry reflection_property_functions[] = {
64616545
ZEND_ME(reflection_property, setAccessible, arginfo_class_ReflectionProperty_setAccessible, 0)
64626546
ZEND_ME(reflection_property, getType, arginfo_class_ReflectionProperty_getType, 0)
64636547
ZEND_ME(reflection_property, hasType, arginfo_class_ReflectionProperty_hasType, 0)
6548+
ZEND_ME(reflection_property, hasDefaultValue, arginfo_class_ReflectionProperty_hasDefaultValue, 0)
6549+
ZEND_ME(reflection_property, getDefaultValue, arginfo_class_ReflectionProperty_getDefaultValue, 0)
64646550
PHP_FE_END
64656551
};
64666552

ext/reflection/reflection.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,11 @@ public function getType() {}
425425

426426
/** @return bool */
427427
public function hasType() {}
428+
429+
public function hasDefaultValue(): bool {}
430+
431+
/** @return mixed */
432+
public function getDefaultValue() {}
428433
}
429434

430435
class ReflectionClassConstant implements Reflector

ext/reflection/reflection_arginfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,11 @@ ZEND_END_ARG_INFO()
343343

344344
#define arginfo_class_ReflectionProperty_hasType arginfo_class_Reflector___toString
345345

346+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_hasDefaultValue, 0, 0, _IS_BOOL, 0)
347+
ZEND_END_ARG_INFO()
348+
349+
#define arginfo_class_ReflectionProperty_getDefaultValue arginfo_class_Reflector___toString
350+
346351
#define arginfo_class_ReflectionClassConstant___clone arginfo_class_Reflector___toString
347352

348353
#define arginfo_class_ReflectionClassConstant_export arginfo_class_ReflectionMethod_export
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
--TEST--
2+
reflection: ReflectionProperty::getDefaultValue
3+
--FILE--
4+
<?php
5+
6+
define('FOO', 42);
7+
8+
class TestClass
9+
{
10+
public $foo;
11+
public $bar = 'baz';
12+
13+
public static $static1;
14+
public static $static2 = 1234;
15+
16+
public int $val1;
17+
public int $val2 = 1234;
18+
19+
public ?int $nullable;
20+
public ?int $nullable2 = null;
21+
22+
public $constantAst = 2 * 2;
23+
public $constantRuntimeAst = FOO;
24+
}
25+
26+
$property = new ReflectionProperty(TestClass::class, 'foo');
27+
var_dump($property->getDefaultValue());
28+
29+
$property = new ReflectionProperty(TestClass::class, 'bar');
30+
var_dump($property->getDefaultValue());
31+
32+
$property = new ReflectionProperty(TestClass::class, 'static1');
33+
var_dump($property->getDefaultValue());
34+
35+
$property = new ReflectionProperty(TestClass::class, 'static2');
36+
var_dump($property->getDefaultValue());
37+
38+
$property = new ReflectionProperty(TestClass::class, 'val1');
39+
var_dump($property->getDefaultValue());
40+
41+
$property = new ReflectionProperty(TestClass::class, 'val2');
42+
var_dump($property->getDefaultValue());
43+
44+
$property = new ReflectionProperty(TestClass::class, 'nullable');
45+
var_dump($property->getDefaultValue());
46+
47+
$property = new ReflectionProperty(TestClass::class, 'nullable2');
48+
var_dump($property->getDefaultValue());
49+
50+
$property = new ReflectionProperty(TestClass::class, 'constantAst');
51+
var_dump($property->getDefaultValue());
52+
53+
$property = new ReflectionProperty(TestClass::class, 'constantRuntimeAst');
54+
var_dump($property->getDefaultValue());
55+
56+
$test = new TestClass;
57+
$test->dynamic = null;
58+
$property = new ReflectionProperty($test, 'dynamic');
59+
var_dump($property->getDefaultValue());
60+
61+
?>
62+
--EXPECT--
63+
NULL
64+
string(3) "baz"
65+
NULL
66+
int(1234)
67+
NULL
68+
int(1234)
69+
NULL
70+
NULL
71+
int(4)
72+
int(42)
73+
NULL
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
reflection: ReflectionProperty::hasDefaultValue
3+
--FILE--
4+
<?php
5+
6+
class TestClass
7+
{
8+
public $foo;
9+
public $bar = 'baz';
10+
11+
public static $static1;
12+
public static $static2 = 1234;
13+
14+
public int $val1;
15+
public int $val2 = 1234;
16+
17+
public ?int $nullable;
18+
public ?int $nullable2 = null;
19+
}
20+
21+
$property = new ReflectionProperty(TestClass::class, 'foo');
22+
var_dump($property->hasDefaultValue());
23+
24+
$property = new ReflectionProperty(TestClass::class, 'bar');
25+
var_dump($property->hasDefaultValue());
26+
27+
$property = new ReflectionProperty(TestClass::class, 'static1');
28+
var_dump($property->hasDefaultValue());
29+
30+
$property = new ReflectionProperty(TestClass::class, 'static2');
31+
var_dump($property->hasDefaultValue());
32+
33+
$property = new ReflectionProperty(TestClass::class, 'val1');
34+
var_dump($property->hasDefaultValue());
35+
36+
$property = new ReflectionProperty(TestClass::class, 'val2');
37+
var_dump($property->hasDefaultValue());
38+
39+
$property = new ReflectionProperty(TestClass::class, 'nullable');
40+
var_dump($property->hasDefaultValue());
41+
42+
$property = new ReflectionProperty(TestClass::class, 'nullable2');
43+
var_dump($property->hasDefaultValue());
44+
45+
$test = new TestClass;
46+
$test->dynamic = null;
47+
$property = new ReflectionProperty($test, 'dynamic');
48+
var_dump($property->hasDefaultValue());
49+
50+
?>
51+
--EXPECT--
52+
bool(true)
53+
bool(true)
54+
bool(true)
55+
bool(true)
56+
bool(false)
57+
bool(true)
58+
bool(false)
59+
bool(true)
60+
bool(false)

0 commit comments

Comments
 (0)