summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrjhdby <andrewgrom@rambler.ru>2019-03-13 13:51:31 +0300
committerNikita Popov <nikita.ppv@gmail.com>2019-07-19 10:06:10 +0200
commitd574df63dc375f5fc9202ce5afde23f866b6450a (patch)
tree5fd118cf3045f46cef4de60235a6bc9e980ac4a9
parentd5943f5a11976ffbe89b9634b86d9a0b2adda30a (diff)
downloadphp-git-d574df63dc375f5fc9202ce5afde23f866b6450a.tar.gz
Deprecate alternative array access syntax
RFC: https://wiki.php.net/rfc/deprecate_curly_braces_array_access
-rw-r--r--UPGRADING3
-rw-r--r--Zend/tests/036.phpt3
-rw-r--r--Zend/tests/bug71572.phpt8
-rw-r--r--Zend/tests/constant_expressions_coalesce.phpt26
-rw-r--r--Zend/tests/str_offset_004.phpt18
-rw-r--r--Zend/zend_ast.c2
-rw-r--r--Zend/zend_compile.c15
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_language_parser.y2
-rw-r--r--ext/bz2/tests/005.phpt2
-rw-r--r--ext/exif/tests/bug64739.phpt4
-rw-r--r--ext/opcache/tests/phi_remove_001.phpt2
-rw-r--r--ext/zlib/tests/005.phpt2
-rw-r--r--ext/zlib/tests/006.phpt2
-rwxr-xr-xrun-tests.php8
-rw-r--r--sapi/fpm/tests/fcgi.inc30
-rw-r--r--tests/strings/offsets_chaining_2.phpt2
-rw-r--r--tests/strings/offsets_chaining_4.phpt2
-rw-r--r--tests/strings/offsets_general.phpt38
19 files changed, 120 insertions, 52 deletions
diff --git a/UPGRADING b/UPGRADING
index 696f44e4f7..ff110affd3 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -348,6 +348,9 @@ PHP 7.4 UPGRADE NOTES
$a ? $b : ($c ? $d : $e)
RFC: https://wiki.php.net/rfc/ternary_associativity
+ . The array and string offset access syntax using curly braces is deprecated.
+ Use $str[$idx] instead of $str{$idx}.
+ RFC: https://wiki.php.net/rfc/deprecate_curly_braces_array_access
. Unbinding $this of a non-static method through a combination of
ReflectionMethod::getClosure() and closure rebinding is deprecated. Doing
so is equivalent to calling a non-static method statically, which has been
diff --git a/Zend/tests/036.phpt b/Zend/tests/036.phpt
index 6feb23f679..3ff522b16f 100644
--- a/Zend/tests/036.phpt
+++ b/Zend/tests/036.phpt
@@ -8,6 +8,9 @@ $a{function() { }} = 1;
?>
--EXPECTF--
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
Warning: Illegal offset type in %s on line %d
Warning: Illegal offset type in %s on line %d
diff --git a/Zend/tests/bug71572.phpt b/Zend/tests/bug71572.phpt
index 4eb16246a1..f4f44449cd 100644
--- a/Zend/tests/bug71572.phpt
+++ b/Zend/tests/bug71572.phpt
@@ -4,10 +4,10 @@ Bug #71572: String offset assignment from an empty string inserts null byte
<?php
$str = "abc";
-var_dump($str{0} = "");
-var_dump($str{1} = "");
-var_dump($str{3} = "");
-var_dump($str{10} = "");
+var_dump($str[0] = "");
+var_dump($str[1] = "");
+var_dump($str[3] = "");
+var_dump($str[10] = "");
var_dump($str);
?>
==DONE==
diff --git a/Zend/tests/constant_expressions_coalesce.phpt b/Zend/tests/constant_expressions_coalesce.phpt
index 425aba69c4..27740aa72e 100644
--- a/Zend/tests/constant_expressions_coalesce.phpt
+++ b/Zend/tests/constant_expressions_coalesce.phpt
@@ -5,6 +5,12 @@ Constant expressions with null coalescing operator ??
const A = [1 => [[]]];
+// should produce deprecation notices
+const D_1 = null ?? A[1]{'undefined'}['index'] ?? 1;
+const D_2 = null ?? A['undefined']{'index'} ?? 2;
+const D_3 = null ?? A[1]{0}{2} ?? 3; // 2 deprecation notices
+const D_4 = A[1]{0} ?? 4;
+
const T_1 = null ?? A[1]['undefined']['index'] ?? 1;
const T_2 = null ?? A['undefined']['index'] ?? 2;
const T_3 = null ?? A[1][0][2] ?? 3;
@@ -12,6 +18,11 @@ const T_4 = A[1][0][2] ?? 4;
const T_5 = null ?? __LINE__;
const T_6 = __LINE__ ?? "bar";
+var_dump(D_1);
+var_dump(D_2);
+var_dump(D_3);
+var_dump(D_4);
+
var_dump(T_1);
var_dump(T_2);
var_dump(T_3);
@@ -31,6 +42,21 @@ var_dump((new class { public $var = A[1][0][2] ?? 4; })->var);
?>
--EXPECTF--
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+int(1)
+int(2)
+int(3)
+array(0) {
+}
int(1)
int(2)
int(3)
diff --git a/Zend/tests/str_offset_004.phpt b/Zend/tests/str_offset_004.phpt
index c8ce607535..435ab235fa 100644
--- a/Zend/tests/str_offset_004.phpt
+++ b/Zend/tests/str_offset_004.phpt
@@ -8,31 +8,31 @@ $str = "abcdefghijklmno";
$i = 3;
$j = -4;
-$str{2} = 'C';
+$str[2] = 'C';
var_dump($str);
-$str{$i} = 'Z';
+$str[$i] = 'Z';
var_dump($str);
-$str{-5} = 'P';
+$str[-5] = 'P';
var_dump($str);
-$str{$j} = 'Q';
+$str[$j] = 'Q';
var_dump($str);
-$str{-20} = 'Y';
+$str[-20] = 'Y';
var_dump($str);
-$str{-strlen($str)} = strtoupper($str{0}); /* An exotic ucfirst() ;) */
+$str[-strlen($str)] = strtoupper($str[0]); /* An exotic ucfirst() ;) */
var_dump($str);
-$str{20} = 'N';
+$str[20] = 'N';
var_dump($str);
-$str{-2} = 'UFO';
+$str[-2] = 'UFO';
var_dump($str);
-$str{-$i} = $str{$j*2};
+$str[-$i] = $str[$j*2];
var_dump($str);
?>
--EXPECTF--
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c
index dcbe531323..685189ed7d 100644
--- a/Zend/zend_ast.c
+++ b/Zend/zend_ast.c
@@ -714,7 +714,7 @@ ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_c
zval_ptr_dtor_nogc(&op1);
ret = FAILURE;
} else {
- zend_fetch_dimension_const(result, &op1, &op2, (ast->attr == ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R);
+ zend_fetch_dimension_const(result, &op1, &op2, (ast->attr & ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R);
zval_ptr_dtor_nogc(&op1);
zval_ptr_dtor_nogc(&op2);
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 59dea8664b..07a987aeef 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2371,6 +2371,10 @@ static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node)
static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
{
+ if (ast->attr == ZEND_DIM_ALTERNATIVE_SYNTAX) {
+ zend_error(E_DEPRECATED, "Array and string offset access syntax with curly braces is deprecated");
+ }
+
zend_ast *var_ast = ast->child[0];
zend_ast *dim_ast = ast->child[1];
zend_op *opline;
@@ -8745,7 +8749,7 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
case ZEND_AST_COALESCE:
/* Set isset fetch indicator here, opcache disallows runtime altering of the AST */
if (ast->child[0]->kind == ZEND_AST_DIM) {
- ast->child[0]->attr = ZEND_DIM_IS;
+ ast->child[0]->attr |= ZEND_DIM_IS;
}
zend_eval_const_expr(&ast->child[0]);
@@ -8799,9 +8803,14 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
}
+ if (ast->attr & ZEND_DIM_ALTERNATIVE_SYNTAX) {
+ ast->attr &= ~ZEND_DIM_ALTERNATIVE_SYNTAX; /* remove flag to avoid duplicate warning */
+ zend_error(E_DEPRECATED, "Array and string offset access syntax with curly braces is deprecated");
+ }
+
/* Set isset fetch indicator here, opcache disallows runtime altering of the AST */
- if (ast->attr == ZEND_DIM_IS && ast->child[0]->kind == ZEND_AST_DIM) {
- ast->child[0]->attr = ZEND_DIM_IS;
+ if (ast->attr & ZEND_DIM_IS && ast->child[0]->kind == ZEND_AST_DIM) {
+ ast->child[0]->attr |= ZEND_DIM_IS;
}
zend_eval_const_expr(&ast->child[0]);
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index c9b8270413..2d7c18fc58 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -924,7 +924,8 @@ void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_SEND_BY_REF 1u
#define ZEND_SEND_PREFER_REF 2u
-#define ZEND_DIM_IS 1
+#define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce */
+#define ZEND_DIM_ALTERNATIVE_SYNTAX (1 << 1) /* deprecated curly brace usage */
#define IS_CONSTANT_UNQUALIFIED 0x010
#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 1ecbab0b3d..ab97c56bde 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -1155,7 +1155,7 @@ callable_variable:
| constant '[' optional_expr ']'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| dereferencable '{' expr '}'
- { $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
+ { $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_DIM_ALTERNATIVE_SYNTAX, $1, $3); }
| dereferencable T_OBJECT_OPERATOR property_name argument_list
{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
| function_call { $$ = $1; }
diff --git a/ext/bz2/tests/005.phpt b/ext/bz2/tests/005.phpt
index da29a6d0b4..27dffb9c1b 100644
--- a/ext/bz2/tests/005.phpt
+++ b/ext/bz2/tests/005.phpt
@@ -21,7 +21,7 @@ $data = bzcompress($string);
$data2 = bzcompress($string, 1, 10);
$data3 = $data2;
-$data3{3} = 0;
+$data3[3] = 0;
var_dump(bzdecompress());
var_dump(bzdecompress(1,1,1));
diff --git a/ext/exif/tests/bug64739.phpt b/ext/exif/tests/bug64739.phpt
index d47f8849a2..de97e0db3c 100644
--- a/ext/exif/tests/bug64739.phpt
+++ b/ext/exif/tests/bug64739.phpt
@@ -16,8 +16,8 @@ if ($headers1 === false) {
exit;
}
-var_dump($headers1['Title']{0} === '?');
-var_dump($headers1['Author']{0} === '?');
+var_dump($headers1['Title'][0] === '?');
+var_dump($headers1['Author'][0] === '?');
ini_set('exif.decode_unicode_motorola', 'UCS-2LE');
diff --git a/ext/opcache/tests/phi_remove_001.phpt b/ext/opcache/tests/phi_remove_001.phpt
index 4be8dcfd6a..3a76a9da5c 100644
--- a/ext/opcache/tests/phi_remove_001.phpt
+++ b/ext/opcache/tests/phi_remove_001.phpt
@@ -31,7 +31,7 @@ function getOnlyMPEGaudioInfoBruteForce($info) {
if ($MPEGaudioHeaderLengthCache[$head4] > 4) {
$WhereWeWere = mftell();
$next4 = test(4);
- if ($next4{0} == "\xFF") {
+ if ($next4[0] == "\xFF") {
if (!isset($MPEGaudioHeaderDecodeCache[$next4])) {
$MPEGaudioHeaderDecodeCache[$next4] = MPEGaudioHeaderDecode($next4);
}
diff --git a/ext/zlib/tests/005.phpt b/ext/zlib/tests/005.phpt
index 6333612183..daa178ec69 100644
--- a/ext/zlib/tests/005.phpt
+++ b/ext/zlib/tests/005.phpt
@@ -28,7 +28,7 @@ var_dump(gzuncompress("", 9));
var_dump(gzuncompress($data1));
var_dump(gzuncompress($data2));
-$data2{4} = 0;
+$data2[4] = 0;
var_dump(gzuncompress($data2));
echo "Done\n";
diff --git a/ext/zlib/tests/006.phpt b/ext/zlib/tests/006.phpt
index 0d082092ca..1caebd7a62 100644
--- a/ext/zlib/tests/006.phpt
+++ b/ext/zlib/tests/006.phpt
@@ -29,7 +29,7 @@ var_dump(gzinflate("asdf", 9));
var_dump(gzinflate($data1));
var_dump(gzinflate($data2));
-$data2{4} = 0;
+$data2[4] = 0;
var_dump(gzinflate($data2));
echo "Done\n";
diff --git a/run-tests.php b/run-tests.php
index 44cfd299bb..84dccd7380 100755
--- a/run-tests.php
+++ b/run-tests.php
@@ -2944,12 +2944,12 @@ function settings2params($ini_settings)
$settings .= " -d \"$name=$val\"";
}
} else {
- if (substr(PHP_OS, 0, 3) == "WIN" && !empty($value) && $value{0} == '"') {
+ if (substr(PHP_OS, 0, 3) == "WIN" && !empty($value) && $value[0] == '"') {
$len = strlen($value);
- if ($value{$len - 1} == '"') {
- $value{0} = "'";
- $value{$len - 1} = "'";
+ if ($value[$len - 1] == '"') {
+ $value[0] = "'";
+ $value[$len - 1] = "'";
}
} else {
$value = addslashes($value);
diff --git a/sapi/fpm/tests/fcgi.inc b/sapi/fpm/tests/fcgi.inc
index f31811aef6..721b94b504 100644
--- a/sapi/fpm/tests/fcgi.inc
+++ b/sapi/fpm/tests/fcgi.inc
@@ -362,19 +362,19 @@ class Client
while ($p != $length) {
- $nlen = ord($data{$p++});
+ $nlen = ord($data[$p++]);
if ($nlen >= 128) {
$nlen = ($nlen & 0x7F << 24);
- $nlen |= (ord($data{$p++}) << 16);
- $nlen |= (ord($data{$p++}) << 8);
- $nlen |= (ord($data{$p++}));
+ $nlen |= (ord($data[$p++]) << 16);
+ $nlen |= (ord($data[$p++]) << 8);
+ $nlen |= (ord($data[$p++]));
}
- $vlen = ord($data{$p++});
+ $vlen = ord($data[$p++]);
if ($vlen >= 128) {
$vlen = ($nlen & 0x7F << 24);
- $vlen |= (ord($data{$p++}) << 16);
- $vlen |= (ord($data{$p++}) << 8);
- $vlen |= (ord($data{$p++}));
+ $vlen |= (ord($data[$p++]) << 16);
+ $vlen |= (ord($data[$p++]) << 8);
+ $vlen |= (ord($data[$p++]));
}
$array[substr($data, $p, $nlen)] = substr($data, $p+$nlen, $vlen);
$p += ($nlen + $vlen);
@@ -392,12 +392,12 @@ class Client
private function decodePacketHeader($data)
{
$ret = array();
- $ret['version'] = ord($data{0});
- $ret['type'] = ord($data{1});
- $ret['requestId'] = (ord($data{2}) << 8) + ord($data{3});
- $ret['contentLength'] = (ord($data{4}) << 8) + ord($data{5});
- $ret['paddingLength'] = ord($data{6});
- $ret['reserved'] = ord($data{7});
+ $ret['version'] = ord($data[0]);
+ $ret['type'] = ord($data[1]);
+ $ret['requestId'] = (ord($data[2]) << 8) + ord($data[3]);
+ $ret['contentLength'] = (ord($data[4]) << 8) + ord($data[5]);
+ $ret['paddingLength'] = ord($data[6]);
+ $ret['reserved'] = ord($data[7]);
return $ret;
}
@@ -634,7 +634,7 @@ class Client
// Reset timeout
$this->set_ms_timeout($this->_readWriteTimeout);
- switch (ord($resp['content']{4})) {
+ switch (ord($resp['content'][4])) {
case self::CANT_MPX_CONN:
throw new \Exception('This app can\'t multiplex [CANT_MPX_CONN]');
break;
diff --git a/tests/strings/offsets_chaining_2.phpt b/tests/strings/offsets_chaining_2.phpt
index bbc170a6e6..0c3c0074b1 100644
--- a/tests/strings/offsets_chaining_2.phpt
+++ b/tests/strings/offsets_chaining_2.phpt
@@ -5,7 +5,7 @@ error_reporting=E_ALL | E_DEPRECATED
--FILE--
<?php
$string = "foobar";
-var_dump($string{0}{0}[0][0]);
+var_dump($string[0][0][0][0]);
?>
--EXPECT--
string(1) "f"
diff --git a/tests/strings/offsets_chaining_4.phpt b/tests/strings/offsets_chaining_4.phpt
index d1f3de26af..fc11b8d797 100644
--- a/tests/strings/offsets_chaining_4.phpt
+++ b/tests/strings/offsets_chaining_4.phpt
@@ -5,7 +5,7 @@ error_reporting=E_ALL | E_DEPRECATED
--FILE--
<?php
$string = "foobar";
-var_dump(isset($string{0}{0}[0][0]));
+var_dump(isset($string[0][0][0][0]));
?>
--EXPECT--
bool(true)
diff --git a/tests/strings/offsets_general.phpt b/tests/strings/offsets_general.phpt
index 4ec6aa5b86..b2ceea088a 100644
--- a/tests/strings/offsets_general.phpt
+++ b/tests/strings/offsets_general.phpt
@@ -1,24 +1,46 @@
--TEST--
testing the behavior of string offsets
---INI--
-error_reporting=E_ALL | E_DEPRECATED
--FILE--
<?php
$string = "foobar";
+const FOO = "BAR"[0];
+var_dump(FOO);
var_dump($string[0]);
var_dump($string[1]);
var_dump(isset($string[0]));
var_dump(isset($string[0][0]));
var_dump($string["foo"]);
var_dump(isset($string["foo"]["bar"]));
-var_dump($string{0});
+
+const FOO_DEPRECATED = "BAR"{0};
+var_dump(FOO_DEPRECATED);
+var_dump([$string{0}]); // 1 notice
var_dump($string{1});
var_dump(isset($string{0}));
-var_dump(isset($string{0}{0}));
+var_dump(isset($string{0}{0})); // 2 notices
var_dump($string{"foo"});
-var_dump(isset($string{"foo"}{"bar"}));
+var_dump(isset($string{"foo"}{"bar"})); // 2 notices
?>
--EXPECTF--
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+
+Deprecated: Array and string offset access syntax with curly braces is deprecated in %s line %d
+string(1) "B"
string(1) "f"
string(1) "o"
bool(true)
@@ -27,7 +49,11 @@ bool(true)
Warning: Illegal string offset 'foo' in %s line %d
string(1) "f"
bool(false)
-string(1) "f"
+string(1) "B"
+array(1) {
+ [0]=>
+ string(1) "f"
+}
string(1) "o"
bool(true)
bool(true)