mirror of
https://github.com/php/php-src.git
synced 2024-10-02 07:16:11 +00:00
Merge branch 'PHP-5.4'
* PHP-5.4: Implemented FR #61602 Allow access to name of constant used as default value
This commit is contained in:
commit
026c161caf
@ -1457,6 +1457,54 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ _reflection_param_get_default_param */
|
||||||
|
static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAMETERS)
|
||||||
|
{
|
||||||
|
reflection_object *intern;
|
||||||
|
parameter_reference *param;
|
||||||
|
|
||||||
|
intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||||
|
if (intern == NULL || intern->ptr == NULL) {
|
||||||
|
if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object");
|
||||||
|
}
|
||||||
|
|
||||||
|
param = intern->ptr;
|
||||||
|
if (param->fptr->type != ZEND_USER_FUNCTION) {
|
||||||
|
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param->offset < param->required) {
|
||||||
|
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ _reflection_param_get_default_precv */
|
||||||
|
static zend_op *_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAMETERS, parameter_reference *param)
|
||||||
|
{
|
||||||
|
zend_op *precv;
|
||||||
|
|
||||||
|
if (param == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
|
||||||
|
if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
|
||||||
|
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return precv;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ Preventing __clone from being called */
|
/* {{{ Preventing __clone from being called */
|
||||||
ZEND_METHOD(reflection, __clone)
|
ZEND_METHOD(reflection, __clone)
|
||||||
{
|
{
|
||||||
@ -2535,27 +2583,20 @@ ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
|
|||||||
Returns the default value of this parameter or throws an exception */
|
Returns the default value of this parameter or throws an exception */
|
||||||
ZEND_METHOD(reflection_parameter, getDefaultValue)
|
ZEND_METHOD(reflection_parameter, getDefaultValue)
|
||||||
{
|
{
|
||||||
reflection_object *intern;
|
|
||||||
parameter_reference *param;
|
parameter_reference *param;
|
||||||
zend_op *precv;
|
zend_op *precv;
|
||||||
|
|
||||||
if (zend_parse_parameters_none() == FAILURE) {
|
if (zend_parse_parameters_none() == FAILURE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GET_REFLECTION_OBJECT_PTR(param);
|
|
||||||
|
|
||||||
if (param->fptr->type != ZEND_USER_FUNCTION)
|
param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||||
{
|
if (!param) {
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (param->offset < param->required) {
|
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional");
|
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||||
return;
|
if (!precv) {
|
||||||
}
|
|
||||||
precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
|
|
||||||
if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
|
|
||||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2569,6 +2610,54 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ proto public bool ReflectionParameter::isDefaultValueConstant()
|
||||||
|
Returns whether the default value of this parameter is constant */
|
||||||
|
ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
|
||||||
|
{
|
||||||
|
zend_op *precv;
|
||||||
|
parameter_reference *param;
|
||||||
|
|
||||||
|
if (zend_parse_parameters_none() == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||||
|
if (!param) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||||
|
if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
|
||||||
|
RETURN_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ proto public mixed ReflectionParameter::getDefaultValueConstantName()
|
||||||
|
Returns the default value's constant name if default value is constant or null */
|
||||||
|
ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
|
||||||
|
{
|
||||||
|
zend_op *precv;
|
||||||
|
parameter_reference *param;
|
||||||
|
|
||||||
|
if (zend_parse_parameters_none() == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||||
|
if (!param) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||||
|
if (precv && (Z_TYPE_P(precv->op2.zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
|
||||||
|
RETURN_STRINGL(Z_STRVAL_P(precv->op2.zv), Z_STRLEN_P(precv->op2.zv), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException
|
/* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException
|
||||||
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
|
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
|
||||||
ZEND_METHOD(reflection_method, export)
|
ZEND_METHOD(reflection_method, export)
|
||||||
@ -5912,6 +6001,8 @@ static const zend_function_entry reflection_parameter_functions[] = {
|
|||||||
ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
|
ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
|
||||||
ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
|
ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
|
||||||
ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
|
ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
|
||||||
|
ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0)
|
||||||
|
ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0)
|
||||||
PHP_FE_END
|
PHP_FE_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
--TEST--
|
||||||
|
ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName()
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
define("CONST_TEST_1", "const1");
|
||||||
|
|
||||||
|
function ReflectionParameterTest($test1=array(), $test2 = CONST_TEST_1) {
|
||||||
|
echo $test;
|
||||||
|
}
|
||||||
|
$reflect = new ReflectionFunction('ReflectionParameterTest');
|
||||||
|
foreach($reflect->getParameters() as $param) {
|
||||||
|
if($param->getName() == 'test1') {
|
||||||
|
var_dump($param->isDefaultValueConstant());
|
||||||
|
}
|
||||||
|
if($param->getName() == 'test2') {
|
||||||
|
var_dump($param->isDefaultValueConstant());
|
||||||
|
}
|
||||||
|
if($param->isDefaultValueAvailable() && $param->isDefaultValueConstant()) {
|
||||||
|
var_dump($param->getDefaultValueConstantName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo2 {
|
||||||
|
const bar = 'Foo2::bar';
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
const bar = 'Foo::bar';
|
||||||
|
|
||||||
|
public function baz($param1 = self::bar, $param2=Foo2::bar, $param3=CONST_TEST_1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = new ReflectionMethod('Foo', 'baz');
|
||||||
|
$params = $method->getParameters();
|
||||||
|
|
||||||
|
foreach ($params as $param) {
|
||||||
|
if ($param->isDefaultValueConstant()) {
|
||||||
|
var_dump($param->getDefaultValueConstantName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
==DONE==
|
||||||
|
--EXPECT--
|
||||||
|
bool(false)
|
||||||
|
bool(true)
|
||||||
|
string(12) "CONST_TEST_1"
|
||||||
|
string(9) "self::bar"
|
||||||
|
string(9) "Foo2::bar"
|
||||||
|
string(12) "CONST_TEST_1"
|
||||||
|
==DONE==
|
@ -0,0 +1,30 @@
|
|||||||
|
--TEST--
|
||||||
|
ReflectionParameter::isDefaultValueConstant() && getDefaultValueConstantName() for namespace
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace ReflectionTestNamespace {
|
||||||
|
CONST TEST_CONST_1 = "Test Const 1";
|
||||||
|
|
||||||
|
class TestClass {
|
||||||
|
const TEST_CONST_2 = "Test Const 2 in class";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
function ReflectionParameterTest($test=ReflectionTestNamespace\TestClass::TEST_CONST_2, $test2 = ReflectionTestNamespace\CONST_TEST_1) {
|
||||||
|
echo $test;
|
||||||
|
}
|
||||||
|
$reflect = new ReflectionFunction('ReflectionParameterTest');
|
||||||
|
foreach($reflect->getParameters() as $param) {
|
||||||
|
if($param->isDefaultValueAvailable() && $param->isDefaultValueConstant()) {
|
||||||
|
echo $param->getDefaultValueConstantName() . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "==DONE==";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
ReflectionTestNamespace\TestClass::TEST_CONST_2
|
||||||
|
ReflectionTestNamespace\CONST_TEST_1
|
||||||
|
==DONE==
|
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
ReflectionParameter::getDefaultValueConstant() should raise exception on non optional parameter
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
define("CONST_TEST_1", "const1");
|
||||||
|
|
||||||
|
function ReflectionParameterTest($test, $test2 = CONST_TEST_1) {
|
||||||
|
echo $test;
|
||||||
|
}
|
||||||
|
$reflect = new ReflectionFunction('ReflectionParameterTest');
|
||||||
|
foreach($reflect->getParameters() as $param) {
|
||||||
|
try {
|
||||||
|
echo $param->getDefaultValueConstantName() . "\n";
|
||||||
|
}
|
||||||
|
catch(ReflectionException $e) {
|
||||||
|
echo $e->getMessage() . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
==DONE==
|
||||||
|
--EXPECT--
|
||||||
|
Parameter is not optional
|
||||||
|
CONST_TEST_1
|
||||||
|
==DONE==
|
Loading…
Reference in New Issue
Block a user