Skip to content

Commit 6a6e387

Browse files
committed
Implement reflection constant
Fixes phpGH-13570
1 parent d667e73 commit 6a6e387

6 files changed

+163
-1
lines changed

ext/reflection/php_reflection.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ PHPAPI zend_class_entry *reflection_enum_ptr;
9797
PHPAPI zend_class_entry *reflection_enum_unit_case_ptr;
9898
PHPAPI zend_class_entry *reflection_enum_backed_case_ptr;
9999
PHPAPI zend_class_entry *reflection_fiber_ptr;
100+
PHPAPI zend_class_entry *reflection_constant_ptr;
100101

101102
/* Exception throwing macro */
102103
#define _DO_THROW(msg) \
@@ -7207,6 +7208,68 @@ static zval *_reflection_write_property(zend_object *object, zend_string *name,
72077208
}
72087209
/* }}} */
72097210

7211+
ZEND_METHOD(ReflectionConstant, __construct)
7212+
{
7213+
zend_string *const_name;
7214+
7215+
zval *object = ZEND_THIS;
7216+
reflection_object *intern = Z_REFLECTION_P(object);
7217+
7218+
ZEND_PARSE_PARAMETERS_START(1, 1)
7219+
Z_PARAM_STR(const_name)
7220+
ZEND_PARSE_PARAMETERS_END();
7221+
7222+
zval *const_zv = zend_get_constant(const_name);
7223+
if (!const_zv) {
7224+
zend_throw_exception_ex(reflection_exception_ptr, 0, "Constant \"%s\" does not exist", ZSTR_VAL(const_name));
7225+
RETURN_THROWS();
7226+
}
7227+
7228+
zend_constant *const_ = (zend_constant*)((uintptr_t)const_zv - XtOffsetOf(zend_constant, value));
7229+
7230+
intern->ptr = const_;
7231+
intern->ref_type = REF_TYPE_OTHER;
7232+
}
7233+
7234+
ZEND_METHOD(ReflectionConstant, getName)
7235+
{
7236+
reflection_object *intern;
7237+
zend_constant *const_;
7238+
7239+
if (zend_parse_parameters_none() == FAILURE) {
7240+
RETURN_THROWS();
7241+
}
7242+
7243+
GET_REFLECTION_OBJECT_PTR(const_);
7244+
RETURN_STR_COPY(const_->name);
7245+
}
7246+
7247+
ZEND_METHOD(ReflectionConstant, getValue)
7248+
{
7249+
reflection_object *intern;
7250+
zend_constant *const_;
7251+
7252+
if (zend_parse_parameters_none() == FAILURE) {
7253+
RETURN_THROWS();
7254+
}
7255+
7256+
GET_REFLECTION_OBJECT_PTR(const_);
7257+
RETURN_COPY(&const_->value);
7258+
}
7259+
7260+
ZEND_METHOD(ReflectionConstant, isDeprecated)
7261+
{
7262+
reflection_object *intern;
7263+
zend_constant *const_;
7264+
7265+
if (zend_parse_parameters_none() == FAILURE) {
7266+
RETURN_THROWS();
7267+
}
7268+
7269+
GET_REFLECTION_OBJECT_PTR(const_);
7270+
RETURN_BOOL(ZEND_CONSTANT_FLAGS(const_) & CONST_DEPRECATED);
7271+
}
7272+
72107273
PHP_MINIT_FUNCTION(reflection) /* {{{ */
72117274
{
72127275
memcpy(&reflection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
@@ -7306,6 +7369,10 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
73067369
reflection_fiber_ptr->create_object = reflection_objects_new;
73077370
reflection_fiber_ptr->default_object_handlers = &reflection_object_handlers;
73087371

7372+
reflection_constant_ptr = register_class_ReflectionConstant();
7373+
reflection_constant_ptr->create_object = reflection_objects_new;
7374+
reflection_constant_ptr->default_object_handlers = &reflection_object_handlers;
7375+
73097376
REFLECTION_G(key_initialized) = 0;
73107377

73117378
return SUCCESS;

ext/reflection/php_reflection.stub.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,3 +829,15 @@ public function getCallable(): callable {}
829829

830830
public function getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT): array {}
831831
}
832+
833+
/** @not-serializable */
834+
final class ReflectionConstant
835+
{
836+
public function __construct(string $name) {}
837+
838+
public function getName(): string {}
839+
840+
public function getValue(): mixed {}
841+
842+
public function isDeprecated(): bool {}
843+
}

ext/reflection/php_reflection_arginfo.h

Lines changed: 33 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
ReflectionConstant::getName()
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
$reflectionConstant = new ReflectionConstant('ZEND_CONSTANT_A');
9+
var_dump($reflectionConstant->getName());
10+
11+
$reflectionConstant = new ReflectionConstant('ZEND_TEST_DEPRECATED');
12+
var_dump($reflectionConstant->getName());
13+
14+
?>
15+
--EXPECT--
16+
string(15) "ZEND_CONSTANT_A"
17+
string(20) "ZEND_TEST_DEPRECATED"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
ReflectionConstant::getValue()
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
$reflectionConstant = new ReflectionConstant('ZEND_CONSTANT_A');
9+
var_dump($reflectionConstant->getValue());
10+
11+
$reflectionConstant = new ReflectionConstant('ZEND_TEST_DEPRECATED');
12+
var_dump($reflectionConstant->getValue());
13+
14+
?>
15+
--EXPECT--
16+
string(6) "global"
17+
int(42)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
ReflectionConstant::isDeprecated()
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
$reflectionConstant = new ReflectionConstant('ZEND_CONSTANT_A');
9+
var_dump($reflectionConstant->isDeprecated());
10+
11+
$reflectionConstant = new ReflectionConstant('ZEND_TEST_DEPRECATED');
12+
var_dump($reflectionConstant->isDeprecated());
13+
14+
?>
15+
--EXPECT--
16+
bool(false)
17+
bool(true)

0 commit comments

Comments
 (0)