}
/* }}} */
+/* {{{ proto public bool ReflectionProperty::hasDefaultValue()
+ Returns whether property has a default value */
+ZEND_METHOD(reflection_property, hasDefaultValue)
+{
+ reflection_object *intern;
+ property_reference *ref;
+ zend_property_info *prop_info;
+ zval *prop;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ prop_info = ref->prop;
+
+ if (prop_info == NULL) {
+ RETURN_FALSE;
+ }
+
+ ce = prop_info->ce;
+
+ if ((prop_info->flags & ZEND_ACC_STATIC) != 0) {
+ prop = &ce->default_static_members_table[prop_info->offset];
+ ZVAL_DEINDIRECT(prop);
+ } else {
+ prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
+ }
+
+ RETURN_BOOL(!Z_ISUNDEF_P(prop));
+}
+/* }}} */
+
+/* {{{ proto public mixed ReflectionProperty::getDefaultValue()
+ Returns the default value of a property */
+ZEND_METHOD(reflection_property, getDefaultValue)
+{
+ reflection_object *intern;
+ property_reference *ref;
+ zend_property_info *prop_info;
+ zval *prop;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ prop_info = ref->prop;
+
+ if (prop_info == NULL) {
+ return; // throw exception?
+ }
+
+ ce = prop_info->ce;
+
+ if ((prop_info->flags & ZEND_ACC_STATIC) != 0) {
+ prop = &ce->default_static_members_table[prop_info->offset];
+ ZVAL_DEINDIRECT(prop);
+ } else {
+ prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
+ }
+
+ if (Z_ISUNDEF_P(prop)) {
+ return;
+ }
+
+ /* copy: enforce read only access */
+ ZVAL_DEREF(prop);
+ ZVAL_COPY_OR_DUP(return_value, prop);
+
+ /* this is necessary to make it able to work with default array
+ * properties, returned to user */
+ if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
+ if (UNEXPECTED(zval_update_constant_ex(return_value, ce) != SUCCESS)) {
+ RETURN_THROWS();
+ }
+ }
+}
+/* }}} */
+
/* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
ZEND_METHOD(reflection_extension, export)
ZEND_ME(reflection_property, setAccessible, arginfo_class_ReflectionProperty_setAccessible, 0)
ZEND_ME(reflection_property, getType, arginfo_class_ReflectionProperty_getType, 0)
ZEND_ME(reflection_property, hasType, arginfo_class_ReflectionProperty_hasType, 0)
+ ZEND_ME(reflection_property, hasDefaultValue, arginfo_class_ReflectionProperty_hasDefaultValue, 0)
+ ZEND_ME(reflection_property, getDefaultValue, arginfo_class_ReflectionProperty_getDefaultValue, 0)
PHP_FE_END
};
/** @return bool */
public function hasType() {}
+
+ public function hasDefaultValue(): bool {}
+
+ /** @return mixed */
+ public function getDefaultValue() {}
}
class ReflectionClassConstant implements Reflector
#define arginfo_class_ReflectionProperty_hasType arginfo_class_Reflector___toString
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_hasDefaultValue, 0, 0, _IS_BOOL, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_ReflectionProperty_getDefaultValue arginfo_class_Reflector___toString
+
#define arginfo_class_ReflectionClassConstant___clone arginfo_class_Reflector___toString
#define arginfo_class_ReflectionClassConstant_export arginfo_class_ReflectionMethod_export
--- /dev/null
+--TEST--
+reflection: ReflectionProperty::getDefaultValue
+--FILE--
+<?php
+
+define('FOO', 42);
+
+class TestClass
+{
+ public $foo;
+ public $bar = 'baz';
+
+ public static $static1;
+ public static $static2 = 1234;
+
+ public int $val1;
+ public int $val2 = 1234;
+
+ public ?int $nullable;
+ public ?int $nullable2 = null;
+
+ public $constantAst = 2 * 2;
+ public $constantRuntimeAst = FOO;
+}
+
+$property = new ReflectionProperty(TestClass::class, 'foo');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'bar');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'static1');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'static2');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'val1');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'val2');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'nullable');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'nullable2');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'constantAst');
+var_dump($property->getDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'constantRuntimeAst');
+var_dump($property->getDefaultValue());
+
+$test = new TestClass;
+$test->dynamic = null;
+$property = new ReflectionProperty($test, 'dynamic');
+var_dump($property->getDefaultValue());
+
+?>
+--EXPECT--
+NULL
+string(3) "baz"
+NULL
+int(1234)
+NULL
+int(1234)
+NULL
+NULL
+int(4)
+int(42)
+NULL
--- /dev/null
+--TEST--
+reflection: ReflectionProperty::hasDefaultValue
+--FILE--
+<?php
+
+class TestClass
+{
+ public $foo;
+ public $bar = 'baz';
+
+ public static $static1;
+ public static $static2 = 1234;
+
+ public int $val1;
+ public int $val2 = 1234;
+
+ public ?int $nullable;
+ public ?int $nullable2 = null;
+}
+
+$property = new ReflectionProperty(TestClass::class, 'foo');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'bar');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'static1');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'static2');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'val1');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'val2');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'nullable');
+var_dump($property->hasDefaultValue());
+
+$property = new ReflectionProperty(TestClass::class, 'nullable2');
+var_dump($property->hasDefaultValue());
+
+$test = new TestClass;
+$test->dynamic = null;
+$property = new ReflectionProperty($test, 'dynamic');
+var_dump($property->hasDefaultValue());
+
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)