mirror of
https://github.com/php/php-src.git
synced 2024-11-23 01:44:06 +08:00
Add ReflectionConstant::getFileName()
Allow determining the name of the file that defined a constant, when the constant was defined in userland code via const or define(). For constants defined by PHP core or extensions, false is returned, matching the existing getFileName() methods on other reflection classes. Fixes GH-15723 Closes GH-15847
This commit is contained in:
parent
94ac1cd1df
commit
f5e743a520
@ -88,6 +88,9 @@ PHP 8.5 UPGRADE NOTES
|
||||
statement from the DEALLOCATE sql command in that we can reuse
|
||||
its name afterwards.
|
||||
|
||||
- Reflection:
|
||||
. ReflectionConstant::getFileName() was introduced.
|
||||
|
||||
========================================
|
||||
7. New Classes and Interfaces
|
||||
========================================
|
||||
|
@ -46,12 +46,18 @@ void free_zend_constant(zval *zv)
|
||||
if (c->name) {
|
||||
zend_string_release_ex(c->name, 0);
|
||||
}
|
||||
if (c->filename) {
|
||||
zend_string_release_ex(c->filename, 0);
|
||||
}
|
||||
efree(c);
|
||||
} else {
|
||||
zval_internal_ptr_dtor(&c->value);
|
||||
if (c->name) {
|
||||
zend_string_release_ex(c->name, 1);
|
||||
}
|
||||
if (c->filename) {
|
||||
zend_string_release_ex(c->filename, 1);
|
||||
}
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
@ -68,6 +74,9 @@ static void copy_zend_constant(zval *zv)
|
||||
|
||||
c = Z_PTR_P(zv);
|
||||
c->name = zend_string_copy(c->name);
|
||||
if (c->filename != NULL) {
|
||||
c->filename = zend_string_copy(c->filename);
|
||||
}
|
||||
if (Z_TYPE(c->value) == IS_STRING) {
|
||||
Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1);
|
||||
}
|
||||
@ -495,6 +504,13 @@ ZEND_API zend_result zend_register_constant(zend_constant *c)
|
||||
name = c->name;
|
||||
}
|
||||
|
||||
zend_string *filename = zend_get_executed_filename_ex();
|
||||
if (filename == NULL) {
|
||||
c->filename = NULL;
|
||||
} else {
|
||||
c->filename = zend_string_copy(filename);
|
||||
}
|
||||
|
||||
/* Check if the user is trying to define any special constant */
|
||||
if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__")
|
||||
|| (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)))
|
||||
@ -502,6 +518,10 @@ ZEND_API zend_result zend_register_constant(zend_constant *c)
|
||||
) {
|
||||
zend_error(E_WARNING, "Constant %s already defined", ZSTR_VAL(name));
|
||||
zend_string_release(c->name);
|
||||
if (c->filename) {
|
||||
zend_string_release(c->filename);
|
||||
c->filename = NULL;
|
||||
}
|
||||
if (!persistent) {
|
||||
zval_ptr_dtor_nogc(&c->value);
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
typedef struct _zend_constant {
|
||||
zval value;
|
||||
zend_string *name;
|
||||
zend_string *filename;
|
||||
} zend_constant;
|
||||
|
||||
#define ZEND_CONSTANT_FLAGS(c) \
|
||||
|
@ -299,6 +299,9 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
|
||||
if (c->name) {
|
||||
zend_string_release_ex(c->name, 0);
|
||||
}
|
||||
if (c->filename) {
|
||||
zend_string_release_ex(c->filename, 0);
|
||||
}
|
||||
efree(c);
|
||||
zend_string_release_ex(key, 0);
|
||||
} ZEND_HASH_MAP_FOREACH_END_DEL();
|
||||
|
@ -7553,6 +7553,20 @@ ZEND_METHOD(ReflectionConstant, isDeprecated)
|
||||
RETURN_BOOL(ZEND_CONSTANT_FLAGS(const_) & CONST_DEPRECATED);
|
||||
}
|
||||
|
||||
ZEND_METHOD(ReflectionConstant, getFileName)
|
||||
{
|
||||
reflection_object *intern;
|
||||
zend_constant *const_;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(const_);
|
||||
if (const_->filename != NULL) {
|
||||
RETURN_STR_COPY(const_->filename);
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ZEND_METHOD(ReflectionConstant, __toString)
|
||||
{
|
||||
reflection_object *intern;
|
||||
|
@ -916,5 +916,7 @@ final class ReflectionConstant implements Reflector
|
||||
|
||||
public function isDeprecated(): bool {}
|
||||
|
||||
public function getFileName(): string|false {}
|
||||
|
||||
public function __toString(): string {}
|
||||
}
|
||||
|
7
ext/reflection/php_reflection_arginfo.h
generated
7
ext/reflection/php_reflection_arginfo.h
generated
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: e6a47b9a496c588bd6f4611cd9a1226bb93052b4 */
|
||||
* Stub hash: 603181d7e1d8292ef694913d4495d3cbb9dd7798 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
|
||||
@ -705,6 +705,9 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionConstant_isDeprecated arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionConstant_getFileName, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionConstant___toString arginfo_class_ReflectionFunction___toString
|
||||
|
||||
ZEND_METHOD(Reflection, getModifierNames);
|
||||
@ -971,6 +974,7 @@ ZEND_METHOD(ReflectionConstant, getNamespaceName);
|
||||
ZEND_METHOD(ReflectionConstant, getShortName);
|
||||
ZEND_METHOD(ReflectionConstant, getValue);
|
||||
ZEND_METHOD(ReflectionConstant, isDeprecated);
|
||||
ZEND_METHOD(ReflectionConstant, getFileName);
|
||||
ZEND_METHOD(ReflectionConstant, __toString);
|
||||
|
||||
static const zend_function_entry class_Reflection_methods[] = {
|
||||
@ -1336,6 +1340,7 @@ static const zend_function_entry class_ReflectionConstant_methods[] = {
|
||||
ZEND_ME(ReflectionConstant, getShortName, arginfo_class_ReflectionConstant_getShortName, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionConstant, getValue, arginfo_class_ReflectionConstant_getValue, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionConstant, isDeprecated, arginfo_class_ReflectionConstant_isDeprecated, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionConstant, getFileName, arginfo_class_ReflectionConstant_getFileName, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionConstant, __toString, arginfo_class_ReflectionConstant___toString, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
44
ext/reflection/tests/ReflectionConstant_getFileName.phpt
Normal file
44
ext/reflection/tests/ReflectionConstant_getFileName.phpt
Normal file
@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
ReflectionConstant::getFileName()
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "included5.inc";
|
||||
|
||||
function testConstant(string $name): void {
|
||||
$ref = new ReflectionConstant($name);
|
||||
echo "$name: ";
|
||||
var_dump($ref->getFileName());
|
||||
}
|
||||
|
||||
define('IN_CURRENT_FILE_DEFINED', 42);
|
||||
const IN_CURRENT_FILE_AST = 123;
|
||||
|
||||
echo "From PHP:\n";
|
||||
testConstant('PHP_VERSION');
|
||||
testConstant('STDIN');
|
||||
testConstant('STDOUT');
|
||||
testConstant('STDERR');
|
||||
|
||||
echo "\nFrom the current file:\n";
|
||||
testConstant('IN_CURRENT_FILE_DEFINED');
|
||||
testConstant('IN_CURRENT_FILE_AST');
|
||||
|
||||
echo "\nFrom an included file:\n";
|
||||
testConstant('INCLUDED_CONSTANT_DEFINED');
|
||||
testConstant('INCLUDED_CONSTANT_AST');
|
||||
?>
|
||||
--EXPECTF--
|
||||
From PHP:
|
||||
PHP_VERSION: bool(false)
|
||||
STDIN: bool(false)
|
||||
STDOUT: bool(false)
|
||||
STDERR: bool(false)
|
||||
|
||||
From the current file:
|
||||
IN_CURRENT_FILE_DEFINED: string(%d) "%sReflectionConstant_getFileName.php"
|
||||
IN_CURRENT_FILE_AST: string(%d) "%sReflectionConstant_getFileName.php"
|
||||
|
||||
From an included file:
|
||||
INCLUDED_CONSTANT_DEFINED: string(%d) "%sincluded5.inc"
|
||||
INCLUDED_CONSTANT_AST: string(%d) "%sincluded5.inc"
|
5
ext/reflection/tests/included5.inc
Normal file
5
ext/reflection/tests/included5.inc
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
define('INCLUDED_CONSTANT_DEFINED', 'Foo');
|
||||
|
||||
const INCLUDED_CONSTANT_AST = 'Bar';
|
||||
?>
|
Loading…
Reference in New Issue
Block a user