diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | UPGRADING | 9 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 47 | ||||
-rw-r--r-- | ext/reflection/php_reflection.stub.php | 4 | ||||
-rw-r--r-- | ext/reflection/php_reflection_arginfo.h | 6 | ||||
-rw-r--r-- | ext/reflection/tests/ReflectionClass_getConstants_filter.phpt | 53 | ||||
-rw-r--r-- | ext/reflection/tests/ReflectionClass_getReflectionConstants_filter.phpt | 83 | ||||
-rw-r--r-- | ext/reflection/tests/ReflectionClass_toString_001.phpt | 6 |
8 files changed, 188 insertions, 22 deletions
@@ -139,6 +139,8 @@ PHP NEWS . Fixed bug #69180 (Reflection does not honor trait conflict resolution / method aliasing). (Nikita) . Fixed bug #74939 (Nested traits' aliased methods are lowercased). (Nikita) + . Implement #79628 (Add $filter parameter for ReflectionClass::getConstants + and ReflectionClass::getReflectionConstants) (carusogabriel) - Session: . Fixed bug #78624 (session_gc return value for user defined session @@ -620,6 +620,15 @@ PHP 8.0 UPGRADE NOTES 5. Changed Functions ======================================== +- Reflection: + . ReflectionClass::getConstants and ReflectionClass::getReflectionConstants results + can be now filtered via a new parameter `$filter`. 3 new constants were added to + be used with it: + + ReflectionClassConstant::IS_PUBLIC + ReflectionClassConstant::IS_PROTECTED + ReflectionClassConstant::IS_PRIVATE + - Zip . ZipArchive::addGlob and ZipArchive::addPattern methods accept more values in the "options" array argument: diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 9903863391..e7296b8008 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4502,33 +4502,39 @@ ZEND_METHOD(ReflectionClass, hasConstant) } /* }}} */ -/* {{{ proto public array ReflectionClass::getConstants() +/* {{{ proto public array ReflectionClass::getConstants([int $filter = ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE]) Returns an associative array containing this class' constants and their values */ ZEND_METHOD(ReflectionClass, getConstants) { reflection_object *intern; zend_class_entry *ce; zend_string *key; - zend_class_constant *c; + zend_class_constant *constant; zval val; + zend_long filter = ZEND_ACC_PPP_MASK; - if (zend_parse_parameters_none() == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &filter) == FAILURE) { RETURN_THROWS(); } + GET_REFLECTION_OBJECT_PTR(ce); + array_init(return_value); - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { - if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) { + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, constant) { + if (UNEXPECTED(zval_update_constant_ex(&constant->value, ce) != SUCCESS)) { zend_array_destroy(Z_ARRVAL_P(return_value)); RETURN_NULL(); } - ZVAL_COPY_OR_DUP(&val, &c->value); - zend_hash_add_new(Z_ARRVAL_P(return_value), key, &val); + + if (Z_ACCESS_FLAGS(constant->value) & filter) { + ZVAL_COPY_OR_DUP(&val, &constant->value); + zend_hash_add_new(Z_ARRVAL_P(return_value), key, &val); + } } ZEND_HASH_FOREACH_END(); } /* }}} */ -/* {{{ proto public array ReflectionClass::getReflectionConstants() +/* {{{ proto public ReflectionClassConstant[] ReflectionClass::getReflectionConstants([int $filter = ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE]) Returns an associative array containing this class' constants as ReflectionClassConstant objects */ ZEND_METHOD(ReflectionClass, getReflectionConstants) { @@ -4536,16 +4542,21 @@ ZEND_METHOD(ReflectionClass, getReflectionConstants) zend_class_entry *ce; zend_string *name; zend_class_constant *constant; + zend_long filter = ZEND_ACC_PPP_MASK; - if (zend_parse_parameters_none() == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &filter) == FAILURE) { RETURN_THROWS(); } + GET_REFLECTION_OBJECT_PTR(ce); + array_init(return_value); ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) { - zval class_const; - reflection_class_constant_factory(name, constant, &class_const); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &class_const); + if (Z_ACCESS_FLAGS(constant->value) & filter) { + zval class_const; + reflection_class_constant_factory(name, constant, &class_const); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &class_const); + } } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -6722,6 +6733,11 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED); + REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE); + INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClassConstant", class_ReflectionClassConstant_methods); reflection_init_class_handlers(&_reflection_entry); reflection_class_constant_ptr = zend_register_internal_class(&_reflection_entry); @@ -6729,10 +6745,9 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ zend_declare_property_string(reflection_class_constant_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_class_constant_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); - REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC); - REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC); - REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED); - REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE); + REGISTER_REFLECTION_CLASS_CONST_LONG(class_constant, "IS_PUBLIC", ZEND_ACC_PUBLIC); + REGISTER_REFLECTION_CLASS_CONST_LONG(class_constant, "IS_PROTECTED", ZEND_ACC_PROTECTED); + REGISTER_REFLECTION_CLASS_CONST_LONG(class_constant, "IS_PRIVATE", ZEND_ACC_PRIVATE); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", class_ReflectionExtension_methods); reflection_init_class_handlers(&_reflection_entry); diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index e3d3fee52c..49872137a4 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -263,10 +263,10 @@ class ReflectionClass implements Reflector public function hasConstant(string $name) {} /** @return array|null */ - public function getConstants() {} + public function getConstants(int $filter = ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE) {} /** @return ReflectionClassConstant[] */ - public function getReflectionConstants() {} + public function getReflectionConstants(int $filter = ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE) {} /** @return mixed */ public function getConstant(string $name) {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index e5ed4742ff..ce3c69de09 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -194,9 +194,11 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClass_hasConstant arginfo_class_ReflectionClass_hasMethod -#define arginfo_class_ReflectionClass_getConstants arginfo_class_ReflectionFunctionAbstract___clone +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionClass_getConstants, 0, 0, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filter, IS_LONG, 0, "ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE") +ZEND_END_ARG_INFO() -#define arginfo_class_ReflectionClass_getReflectionConstants arginfo_class_ReflectionFunctionAbstract___clone +#define arginfo_class_ReflectionClass_getReflectionConstants arginfo_class_ReflectionClass_getConstants #define arginfo_class_ReflectionClass_getConstant arginfo_class_ReflectionClass_hasMethod diff --git a/ext/reflection/tests/ReflectionClass_getConstants_filter.phpt b/ext/reflection/tests/ReflectionClass_getConstants_filter.phpt new file mode 100644 index 0000000000..00dd961b77 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getConstants_filter.phpt @@ -0,0 +1,53 @@ +--TEST-- +ReflectionClass::getConstants() with $filter +--FILE-- +<?php +class A { + public const PUBLIC_CONST = 'BAR'; + public const ANOTHER_PUBLIC_CONST = 'BAZ'; + protected const PROTECTED_CONST = 'FOO'; + private const PRIVATE_CONST = 'QUOZ'; +} + +class B { + public const PUBLIC_CONST = 'BAR'; + protected const ANOTHER_PROTECTED_CONST = 'BAZ'; + protected const PROTECTED_CONST = 'FOO'; + private const PRIVATE_CONST = 'QUOZ'; +} + +class C { + public const PUBLIC_CONST = 'BAR'; + protected const PROTECTED_CONST = 'FOO'; + private const PRIVATE_CONST = 'QUOZ'; + private const ANOTHER_PRIVATE_CONST = 'BAZ'; +} + +$reflectionClassA = new ReflectionClass(A::class); +var_dump($reflectionClassA->getConstants(ReflectionClassConstant::IS_PUBLIC)); + +$reflectionClassB = new ReflectionClass(B::class); +var_dump($reflectionClassB->getConstants(ReflectionClassConstant::IS_PROTECTED)); + +$reflectionClassC = new ReflectionClass(C::class); +var_dump($reflectionClassC->getConstants(ReflectionClassConstant::IS_PRIVATE)); +?> +--EXPECTF-- +array(%d) { + ["PUBLIC_CONST"]=> + string(%d) "BAR" + ["ANOTHER_PUBLIC_CONST"]=> + string(%d) "BAZ" +} +array(%d) { + ["ANOTHER_PROTECTED_CONST"]=> + string(%d) "BAZ" + ["PROTECTED_CONST"]=> + string(%d) "FOO" +} +array(%d) { + ["PRIVATE_CONST"]=> + string(%d) "QUOZ" + ["ANOTHER_PRIVATE_CONST"]=> + string(%d) "BAZ" +} diff --git a/ext/reflection/tests/ReflectionClass_getReflectionConstants_filter.phpt b/ext/reflection/tests/ReflectionClass_getReflectionConstants_filter.phpt new file mode 100644 index 0000000000..afff6b67ce --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getReflectionConstants_filter.phpt @@ -0,0 +1,83 @@ +--TEST-- +ReflectionClass::getReflectionConstants() with $filter +--FILE-- +<?php +class A { + public const PUBLIC_CONST = 'BAR'; + public const ANOTHER_PUBLIC_CONST = 'BAZ'; + protected const PROTECTED_CONST = 'FOO'; + private const PRIVATE_CONST = 'QUOZ'; +} + +class B { + public const PUBLIC_CONST = 'BAR'; + protected const ANOTHER_PROTECTED_CONST = 'BAZ'; + protected const PROTECTED_CONST = 'FOO'; + private const PRIVATE_CONST = 'QUOZ'; +} + +class C { + public const PUBLIC_CONST = 'BAR'; + protected const PROTECTED_CONST = 'FOO'; + private const PRIVATE_CONST = 'QUOZ'; + private const ANOTHER_PRIVATE_CONST = 'BAZ'; +} + +$reflectionClassA = new ReflectionClass(A::class); +var_dump($reflectionClassA->getReflectionConstants(ReflectionClassConstant::IS_PUBLIC)); + +$reflectionClassB = new ReflectionClass(B::class); +var_dump($reflectionClassB->getReflectionConstants(ReflectionClassConstant::IS_PROTECTED)); + +$reflectionClassC = new ReflectionClass(C::class); +var_dump($reflectionClassC->getReflectionConstants(ReflectionClassConstant::IS_PRIVATE)); +?> +--EXPECTF-- +array(2) { + [0]=> + object(ReflectionClassConstant)#%d (%d) { + ["name"]=> + string(%d) "PUBLIC_CONST" + ["class"]=> + string(%d) "A" + } + [1]=> + object(ReflectionClassConstant)#%d (%d) { + ["name"]=> + string(%d) "ANOTHER_PUBLIC_CONST" + ["class"]=> + string(%d) "A" + } +} +array(2) { + [0]=> + object(ReflectionClassConstant)#%d (%d) { + ["name"]=> + string(%d) "ANOTHER_PROTECTED_CONST" + ["class"]=> + string(%d) "B" + } + [1]=> + object(ReflectionClassConstant)#%d (%d) { + ["name"]=> + string(%d) "PROTECTED_CONST" + ["class"]=> + string(%d) "B" + } +} +array(2) { + [0]=> + object(ReflectionClassConstant)#%d (%d) { + ["name"]=> + string(%d) "PRIVATE_CONST" + ["class"]=> + string(%d) "C" + } + [1]=> + object(ReflectionClassConstant)#%d (%d) { + ["name"]=> + string(%d) "ANOTHER_PRIVATE_CONST" + ["class"]=> + string(%d) "C" + } +} diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index fb39bdb4de..e0860b2005 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -165,13 +165,15 @@ Class [ <internal:Reflection> class ReflectionClass implements Reflector, String Method [ <internal:Reflection> public method getConstants ] { - - Parameters [0] { + - Parameters [1] { + Parameter #0 [ <optional> int $filter = ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE ] } } Method [ <internal:Reflection> public method getReflectionConstants ] { - - Parameters [0] { + - Parameters [1] { + Parameter #0 [ <optional> int $filter = ReflectionClassConstant::IS_PUBLIC | ReflectionClassConstant::IS_PROTECTED | ReflectionClassConstant::IS_PRIVATE ] } } |