summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-01-09 12:21:02 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-02-18 14:35:58 +0100
commit3b08f53c97b2aa1bdd132d0f715e9db20fefad5d (patch)
treec8988278de53ba78fa472a83812d64745ce6ec69 /Zend
parent9d79e510d593f5ea098e4633278d0ecd07e1b351 (diff)
downloadphp-git-3b08f53c97b2aa1bdd132d0f715e9db20fefad5d.tar.gz
Deprecate required param after optional
As an exception, we allow "Type $foo = null" to occur before a required parameter, because this pattern was used as a replacement for nullable types in PHP versions older than 7.1. Closes GH-5067.
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/call_user_func_005.phpt1
-rw-r--r--Zend/tests/required_param_after_optional.phpt14
-rw-r--r--Zend/tests/traits/bug60717.phpt4
-rw-r--r--Zend/zend_compile.c15
4 files changed, 32 insertions, 2 deletions
diff --git a/Zend/tests/call_user_func_005.phpt b/Zend/tests/call_user_func_005.phpt
index fd130eb773..2f5220db62 100644
--- a/Zend/tests/call_user_func_005.phpt
+++ b/Zend/tests/call_user_func_005.phpt
@@ -18,6 +18,7 @@ var_dump(call_user_func(array('foo', 'teste')));
?>
--EXPECTF--
+Deprecated: Required parameter $b follows optional parameter $a in %s on line %d
string(1) "x"
array(1) {
[0]=>
diff --git a/Zend/tests/required_param_after_optional.phpt b/Zend/tests/required_param_after_optional.phpt
new file mode 100644
index 0000000000..cd715e77d4
--- /dev/null
+++ b/Zend/tests/required_param_after_optional.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Required parameter after optional is deprecated
+--FILE--
+<?php
+
+function test($testA = null, $testB = null, $testC) {}
+function test2(Type $test2A = null, $test2B = null, $test2C) {}
+function test3(Type $test3A = null, Type2 $test3B = null, $test3C) {}
+
+?>
+--EXPECTF--
+Deprecated: Required parameter $testC follows optional parameter $testA in %s on line %d
+
+Deprecated: Required parameter $test2C follows optional parameter $test2B in %s on line %d
diff --git a/Zend/tests/traits/bug60717.phpt b/Zend/tests/traits/bug60717.phpt
index 0f5cadb066..1ea146c5a0 100644
--- a/Zend/tests/traits/bug60717.phpt
+++ b/Zend/tests/traits/bug60717.phpt
@@ -9,7 +9,7 @@ namespace HTML
{
function text($text);
function attributes(array $attributes = null);
- function textArea(array $attributes = null, $value);
+ function textArea(?array $attributes, $value);
}
trait TextUTF8
@@ -19,7 +19,7 @@ namespace HTML
trait TextArea
{
- function textArea(array $attributes = null, $value) {}
+ function textArea(?array $attributes, $value) {}
abstract function attributes(array $attributes = null);
abstract function text($text);
}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index bc0a7dfdae..7ec740ae4e 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5720,6 +5720,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
uint32_t i;
zend_op_array *op_array = CG(active_op_array);
zend_arg_info *arg_infos;
+ zend_string *optional_param = NULL;
if (return_type_ast) {
/* Use op_array->arg_info[-1] for return type */
@@ -5788,10 +5789,24 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
default_node.op_type = IS_CONST;
zend_const_expr_to_zval(&default_node.u.constant, default_ast);
CG(compiler_options) = cops;
+
+ if (!optional_param) {
+ /* Ignore parameters of the form "Type $param = null".
+ * This is the PHP 5 style way of writing "?Type $param", so allow it for now. */
+ zend_bool is_implicit_nullable =
+ type_ast && Z_TYPE(default_node.u.constant) == IS_NULL;
+ if (!is_implicit_nullable) {
+ optional_param = name;
+ }
+ }
} else {
opcode = ZEND_RECV;
default_node.op_type = IS_UNUSED;
op_array->required_num_args = i + 1;
+ if (optional_param) {
+ zend_error(E_DEPRECATED, "Required parameter $%s follows optional parameter $%s",
+ ZSTR_VAL(name), ZSTR_VAL(optional_param));
+ }
}
arg_info = &arg_infos[i];