diff options
author | rjhdby <andrewgrom@rambler.ru> | 2019-03-13 13:51:31 +0300 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-07-19 10:06:10 +0200 |
commit | d574df63dc375f5fc9202ce5afde23f866b6450a (patch) | |
tree | 5fd118cf3045f46cef4de60235a6bc9e980ac4a9 | |
parent | d5943f5a11976ffbe89b9634b86d9a0b2adda30a (diff) | |
download | php-git-d574df63dc375f5fc9202ce5afde23f866b6450a.tar.gz |
Deprecate alternative array access syntax
RFC: https://wiki.php.net/rfc/deprecate_curly_braces_array_access
-rw-r--r-- | UPGRADING | 3 | ||||
-rw-r--r-- | Zend/tests/036.phpt | 3 | ||||
-rw-r--r-- | Zend/tests/bug71572.phpt | 8 | ||||
-rw-r--r-- | Zend/tests/constant_expressions_coalesce.phpt | 26 | ||||
-rw-r--r-- | Zend/tests/str_offset_004.phpt | 18 | ||||
-rw-r--r-- | Zend/zend_ast.c | 2 | ||||
-rw-r--r-- | Zend/zend_compile.c | 15 | ||||
-rw-r--r-- | Zend/zend_compile.h | 3 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 2 | ||||
-rw-r--r-- | ext/bz2/tests/005.phpt | 2 | ||||
-rw-r--r-- | ext/exif/tests/bug64739.phpt | 4 | ||||
-rw-r--r-- | ext/opcache/tests/phi_remove_001.phpt | 2 | ||||
-rw-r--r-- | ext/zlib/tests/005.phpt | 2 | ||||
-rw-r--r-- | ext/zlib/tests/006.phpt | 2 | ||||
-rwxr-xr-x | run-tests.php | 8 | ||||
-rw-r--r-- | sapi/fpm/tests/fcgi.inc | 30 | ||||
-rw-r--r-- | tests/strings/offsets_chaining_2.phpt | 2 | ||||
-rw-r--r-- | tests/strings/offsets_chaining_4.phpt | 2 | ||||
-rw-r--r-- | tests/strings/offsets_general.phpt | 38 |
19 files changed, 120 insertions, 52 deletions
@@ -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) |