]> granicus.if.org Git - php/commitdiff
Deprecate alternative array access syntax
authorrjhdby <andrewgrom@rambler.ru>
Wed, 13 Mar 2019 10:51:31 +0000 (13:51 +0300)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 19 Jul 2019 08:06:10 +0000 (10:06 +0200)
RFC: https://wiki.php.net/rfc/deprecate_curly_braces_array_access

19 files changed:
UPGRADING
Zend/tests/036.phpt
Zend/tests/bug71572.phpt
Zend/tests/constant_expressions_coalesce.phpt
Zend/tests/str_offset_004.phpt
Zend/zend_ast.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y
ext/bz2/tests/005.phpt
ext/exif/tests/bug64739.phpt
ext/opcache/tests/phi_remove_001.phpt
ext/zlib/tests/005.phpt
ext/zlib/tests/006.phpt
run-tests.php
sapi/fpm/tests/fcgi.inc
tests/strings/offsets_chaining_2.phpt
tests/strings/offsets_chaining_4.phpt
tests/strings/offsets_general.phpt

index 696f44e4f795cae08683914e205751aa87a1c797..ff110affd3aa6565fe0d4b9a148fc92a772ef717 100644 (file)
--- 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
index 6feb23f679ba8128f05959d9f37f56853430338e..3ff522b16f06e782136713179026c286c2bc6657 100644 (file)
@@ -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
index 4eb16246a12e525a48f513058594db383d16a995..f4f44449cd6033b04f1c4277383407620b8242c0 100644 (file)
@@ -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==
index 425aba69c403ee589e5b262311f38f007a95546e..27740aa72e704d08cec6197419aeef01540ee228 100644 (file)
@@ -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)
index c8ce6075357525a754ec220c179cb991b11960bd..435ab235fa61dc963873b248ff67eb965c524534 100644 (file)
@@ -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--
index dcbe531323fadabf2d11dd2819067c09d0b4fd62..685189ed7d11429d94029a524e868aee3a60a132 100644 (file)
@@ -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);
index 59dea8664b4f362e93d4af7d143145ec08f97822..07a987aeef4de434abf97ad54a124557f390555f 100644 (file)
@@ -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]);
index c9b827041373f6a2983672d7961b0e1305a1a00c..2d7c18fc584e227da73e499c216d90fa283cd00f 100644 (file)
@@ -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 */
index 1ecbab0b3d307187291d6c37af211fe1f5e8aaeb..ab97c56bde46b48622907241caab91389489178b 100644 (file)
@@ -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; }
index da29a6d0b40795aa8a4c44502974a467f0b67628..27dffb9c1b7d60a14ce273d6a4a2f385bf313a55 100644 (file)
@@ -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));
index d47f8849a2c4ff63b6e31688fd5a584cb654f19d..de97e0db3c0d92bcffe6374db7791231961b6338 100644 (file)
@@ -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');
 
index 4be8dcfd6ad5c56e2b1a700ad08cb092816f2f81..3a76a9da5c6535a6aa718492afbc0db987185656 100644 (file)
@@ -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);
                                        }
index 6333612183086c230ae98241b7a096009c0e64ed..daa178ec69afd25c0d80e227e2d5e250debe7577 100644 (file)
@@ -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";
index 0d082092ca3775472d5246521c170c783dcaec3e..1caebd7a6245077d475084fd3d7b7add28fee583 100644 (file)
@@ -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";
index 44cfd299bbeaac97b9cd1fecbe76d8df64e14ccf..84dccd7380ab34b0ac1e09b10c706e22d98c5136 100755 (executable)
@@ -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);
index f31811aef6744cf0b6ae59b3f38fcfdbf3d71f59..721b94b504500892159c62cbd8e8014971dc8933 100644 (file)
@@ -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;
index bbc170a6e66215985ba0c318ff7b26b66735948d..0c3c0074b138bd4b50fb8a9f909669f790a2648b 100644 (file)
@@ -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"
index d1f3de26af4fe557aaaf26502c8418ae5cea09d7..fc11b8d797907fc2e0705446659af7d1d4f7b86c 100644 (file)
@@ -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)
index 4ec6aa5b86b9b8357a1768fb41296f3957fca218..b2ceea088a2f56929461fab7f84364c2f698a47a 100644 (file)
@@ -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)