Skip to content

Commit 4238b93

Browse files
committed
Store parameter default values in arginfo
1 parent 51a305d commit 4238b93

File tree

139 files changed

+1895
-1344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+1895
-1344
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ PHP NEWS
9999
. Fixed bug #69180 (Reflection does not honor trait conflict resolution /
100100
method aliasing). (Nikita)
101101
. Fixed bug #74939 (Nested traits' aliased methods are lowercased). (Nikita)
102+
. Implement ReflectionParameter::getDefaultValueString (kocsismate)
102103

103104
- Session:
104105
. Fixed bug #78624 (session_gc return value for user defined session

UPGRADING

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,14 @@ PHP 8.0 UPGRADE NOTES
304304
result will include a nullability indicator for nullable types. The format
305305
of the return value is not stable and may change between PHP versions.
306306
. Reflection export() methods have been removed.
307+
. The following methods can now return information about default values of
308+
parameters of internal functions:
309+
ReflectionParameter::isDefaultValueAvailable()
310+
ReflectionParameter::getDefaultValue()
311+
ReflectionParameter::isDefaultValueConstant()
312+
ReflectionParameter::getDefaultValueConstantName()
313+
. The ReflectionParameter::isDefaultValueConstant() and
314+
ReflectionParameter::getDefaultValueConstantName() methods have been deprecated.
307315

308316
- Socket:
309317
. The deprecated AI_IDN_ALLOW_UNASSIGNED and AI_IDN_USE_STD3_ASCII_RULES

Zend/tests/argument_restriction_001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ class Sub extends Base {
1313
}
1414
?>
1515
--EXPECTF--
16-
Fatal error: Declaration of & Sub::test() must be compatible with & Base::test($foo, array $bar, $option = NULL, $extra = 'llllllllll...') in %sargument_restriction_001.php on line %d
16+
Fatal error: Declaration of & Sub::test() must be compatible with & Base::test($foo, array $bar, $option = NULL, $extra = 'lllllllllllllllllllllllllllllllllllllllllllllllllll') in %sargument_restriction_001.php on line %d

Zend/tests/argument_restriction_003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ class Sub extends Base {
1616
}
1717
?>
1818
--EXPECTF--
19-
Fatal error: Declaration of Sub::test() must be compatible with Base::test(Foo $foo, array $bar, $option = NULL, $extra = 'llllllllll...') in %sargument_restriction_003.php on line %d
19+
Fatal error: Declaration of Sub::test() must be compatible with Base::test(Foo $foo, array $bar, $option = NULL, $extra = 'lllllllllllllllllllllllllllllllllllllllllllllllllll') in %sargument_restriction_003.php on line %d

Zend/tests/argument_restriction_006.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ class Sub extends Base {
1313
}
1414
?>
1515
--EXPECTF--
16-
Fatal error: Declaration of Sub::test($foo, $extra) must be compatible with Base::test($foo, $extra = Array) in %sargument_restriction_006.php on line %d
16+
Fatal error: Declaration of Sub::test($foo, $extra) must be compatible with Base::test($foo, $extra = ['test']) in %sargument_restriction_006.php on line %d

Zend/tests/bug64988.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ $o = new Smooth1();
2626
echo "okey";
2727
?>
2828
--EXPECTF--
29-
Fatal error: Declaration of Smooth1::insert(array $data) must be compatible with Noisy1::insert(array $data, $option1 = NULL) in %sbug64988.php on line 17
29+
Fatal error: Declaration of Smooth1::insert(array $data) must be compatible with Noisy1::insert(array $data, $option1 = Null) in %sbug64988.php on line 17

Zend/tests/bug70957.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ class B extends Foo
1919
}
2020
?>
2121
--EXPECTF--
22-
Fatal error: Declaration of T::bar() must be compatible with Foo::bar($a = 'Foo') in %sbug70957.php on line %d
22+
Fatal error: Declaration of T::bar() must be compatible with Foo::bar($a = self::class) in %sbug70957.php on line %d

Zend/tests/bug71428.1.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ class B extends A {
99
public function m(array $a = []) {}
1010
}
1111
--EXPECTF--
12-
Fatal error: Declaration of B::m(array $a = Array) must be compatible with A::m(?array $a = NULL) in %sbug71428.1.php on line 6
12+
Fatal error: Declaration of B::m(array $a = []) must be compatible with A::m(?array $a = null) in %sbug71428.1.php on line 6

Zend/tests/bug72119.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ class Hello implements Foo {
1515
echo "OK\n";
1616
?>
1717
--EXPECTF--
18-
Fatal error: Declaration of Hello::bar(array $baz = Array) must be compatible with Foo::bar(?array $baz = NULL) in %s on line %d
18+
Fatal error: Declaration of Hello::bar(array $baz = []) must be compatible with Foo::bar(?array $baz = null) in %s on line %d

Zend/tests/bug73987.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ class B extends A {
1515

1616
?>
1717
--EXPECTF--
18-
Fatal error: Declaration of B::example($a, $b, $c = NULL) must be compatible with A::example($a, $b = NULL, $c = NULL) in %s
18+
Fatal error: Declaration of B::example($a, $b, $c = null) must be compatible with A::example($a, $b = null, $c = null) in %s

Zend/tests/bug73987_2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ class C extends B {
1717

1818
?>
1919
--EXPECTF--
20-
Fatal error: Declaration of C::example($a, $b, $c = NULL) must be compatible with B::example($a, $b = NULL, $c = NULL) in %s
20+
Fatal error: Declaration of C::example($a, $b, $c = null) must be compatible with B::example($a, $b = null, $c = null) in %s

Zend/tests/closures/closure_from_callable_basic.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ $foo = new SubFoo;
8181
$fn = $foo->getSelfColonParentPublicInstanceMethod();
8282
echo $fn(" OK".PHP_EOL);
8383

84-
echo 'Access proteced instance method of parent object through "self::" to parent method';
84+
echo 'Access protected instance method of parent object through "self::" to parent method';
8585
$foo = new SubFoo;
8686
$fn = $foo->getSelfColonParentProtectedInstanceMethod();
8787
echo $fn(" OK".PHP_EOL);
@@ -114,6 +114,6 @@ Subclass closure over parent class static protected method OK
114114
Access public instance method of parent object through "parent::" OK
115115
Access public instance method of self object through "self::" OK
116116
Access public instance method of parent object through "self::" to parent method OK
117-
Access proteced instance method of parent object through "self::" to parent method OK
117+
Access protected instance method of parent object through "self::" to parent method OK
118118
MagicCall __call instance method __call,nonExistentMethod, OK
119119
MagicCall __callStatic static method __callStatic,nonExistentMethod, OK
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
The default value is a class constant in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
class MyDateTimeZone extends DateTimeZone
6+
{
7+
public static function listIdentifiers()
8+
{
9+
}
10+
}
11+
--EXPECTF--
12+
Fatal error: Declaration of MyDateTimeZone::listIdentifiers() must be compatible with DateTimeZone::listIdentifiers(int $what = DateTimeZone::ALL, ?string $country = null) in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
The default value is a constant in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
class MyDateTimeZone extends DateTimeZone
6+
{
7+
public function getTransitions()
8+
{
9+
}
10+
}
11+
--EXPECTF--
12+
Fatal error: Declaration of MyDateTimeZone::getTransitions() must be compatible with DateTimeZone::getTransitions(int $timestamp_begin = PHP_INT_MIN, int $timestamp_end = PHP_INT_MAX) in %s on line %d
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
The default value is false in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
6+
interface MyDateTimeInterface extends DateTimeInterface
7+
{
8+
public function diff();
9+
}
10+
--EXPECTF--
11+
Fatal error: Declaration of MyDateTimeInterface::diff() must be compatible with DateTimeInterface::diff(DateTimeInterface $object, bool $absolute = false) in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
The default value is an integer in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
class MyDateTime extends DateTime
6+
{
7+
public function setTime(int $hour, int $minute, int $second = 0, bool $microseconds = false)
8+
{
9+
}
10+
}
11+
--EXPECTF--
12+
Fatal error: Declaration of MyDateTime::setTime(int $hour, int $minute, int $second = 0, bool $microseconds = false) must be compatible with DateTime::setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0) in %s on line %d
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
The default value is null in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
class MyDateTime extends DateTime
6+
{
7+
public static function createFromFormat()
8+
{
9+
}
10+
}
11+
--EXPECTF--
12+
Fatal error: Declaration of MyDateTime::createFromFormat() must be compatible with DateTime::createFromFormat(string $format, string $time, ?DateTimeZone $timezone = null) in %s on line %d
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
The default value is a constant in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
6+
use Foo\Bar;
7+
8+
class A
9+
{
10+
public function foo(
11+
$param1 = \Foo\Bar::CONSTANT,
12+
$param2 = Foo\Bar::CONSTANT,
13+
$param3 = Bar::CONSTANT
14+
) {
15+
}
16+
}
17+
18+
class B extends A
19+
{
20+
public function foo()
21+
{
22+
}
23+
}
24+
--EXPECTF--
25+
Fatal error: Declaration of B::foo() must be compatible with A::foo($param1 = \Foo\Bar::CONSTANT, $param2 = Foo\Bar::CONSTANT, $param3 = Bar::CONSTANT) in %s on line %d
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
The default value is a constant in the parent class method's signature.
3+
--FILE--
4+
<?php
5+
6+
use const Foo\CONSTANT;
7+
8+
class A
9+
{
10+
public function foo(
11+
$param1 = \Foo\CONSTANT,
12+
$param2 = Foo\CONSTANT,
13+
$param3 = CONSTANT
14+
) {
15+
}
16+
}
17+
18+
class B extends A
19+
{
20+
public function foo()
21+
{
22+
}
23+
}
24+
--EXPECTF--
25+
Fatal error: Declaration of B::foo() must be compatible with A::foo($param1 = \Foo\CONSTANT, $param2 = Foo\CONSTANT, $param3 = CONSTANT) in %s on line %d

Zend/tests/type_declarations/variance/internal_parent.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ class Test extends DateTime {
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: Could not check compatibility between Test::createFromFormat($format, $time, ?Wrong $timezone = NULL) and DateTime::createFromFormat(string $format, string $time, ?DateTimeZone $timezone = NULL), because class Wrong is not available in %s on line %d
12+
Fatal error: Could not check compatibility between Test::createFromFormat($format, $time, ?Wrong $timezone = null) and DateTime::createFromFormat(string $format, string $time, ?DateTimeZone $timezone = null), because class Wrong is not available in %s on line %d

Zend/tests/variadic/adding_additional_optional_parameter_error.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ class MySQL implements DB {
1313

1414
?>
1515
--EXPECTF--
16-
Fatal error: Declaration of MySQL::query($query, ?int $extraParam = NULL, string ...$params) must be compatible with DB::query($query, string ...$params) in %s on line %d
16+
Fatal error: Declaration of MySQL::query($query, ?int $extraParam = null, string ...$params) must be compatible with DB::query($query, string ...$params) in %s on line %d

Zend/zend_API.h

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,50 +105,61 @@ typedef struct _zend_fcall_info_cache {
105105
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic) \
106106
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0))
107107

108+
/* Arginfo structures without type information */
108109
#define ZEND_ARG_INFO(pass_by_ref, name) \
109-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0))},
110-
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
111-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
112-
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
113-
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
114-
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
115-
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
116-
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
117-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
118-
#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask) \
119-
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
110+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
111+
#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
112+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
120113
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
121-
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
114+
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
115+
/* Arginfo structures with simple type information */
116+
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
117+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
118+
#define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
119+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
122120
#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
123-
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
121+
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
122+
/* Arginfo structures with complex type information */
123+
#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \
124+
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
125+
/* Arginfo structures with object type information */
126+
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
127+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
128+
#define ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, classname, allow_null, default_value) \
129+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
124130
#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
125-
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
131+
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
132+
/* Legacy arginfo structures */
133+
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
134+
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
135+
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
136+
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
126137

127138
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
128139
static const zend_internal_arg_info name[] = { \
129140
{ (const char*)(zend_uintptr_t)(required_num_args), \
130-
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
141+
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
131142

132143
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
133144
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
134145

135146
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
136147
static const zend_internal_arg_info name[] = { \
137-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
148+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
138149

139150
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
140151
static const zend_internal_arg_info name[] = { \
141-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
152+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
142153

143154
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
144155
static const zend_internal_arg_info name[] = { \
145-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
156+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
146157
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
147158
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
148159

149160
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
150161
static const zend_internal_arg_info name[] = { \
151-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
162+
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
152163
#define ZEND_BEGIN_ARG_INFO(name, _unused) \
153164
ZEND_BEGIN_ARG_INFO_EX(name, {}, ZEND_RETURN_VALUE, -1)
154165
#define ZEND_END_ARG_INFO() };

0 commit comments

Comments
 (0)