php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #50003 Allow constructions like func()[0]
Submitted: 2009-10-26 18:45 UTC Modified: 2009-11-09 11:39 UTC
Votes:2
Avg. Score:3.0 ± 2.0
Reproduced:1 of 2 (50.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: melfar at gmail dot com Assigned:
Status: Not a bug Package: Feature/Change Request
PHP Version: 5.3.0 OS: *
Private report: No CVE-ID: None
 [2009-10-26 18:45 UTC] melfar at gmail dot com
Description:
------------
PHP parser doesn't allow for array index operation to be used on a 
result of a function call.  I propose a patch to allow such a 
construction.

Reproduce code:
---------------
<?php
  function car_brands() {
    return array("chevy", "hummer");
  }
  print car_brands()[1] . "\n";
?>


Expected result:
----------------
"hummer"



Actual result:
--------------
Parse error: syntax error, unexpected '[' in test.php on line 5

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-10-26 18:47 UTC] melfar at gmail dot com
Not sure how to attach a file.  The proposed patch is as follows.



--- a/Zend/zend_language_parser.y.orig	2009-10-26 18:13:56.000000000 
+0300
+++ b/Zend/zend_language_parser.y	2009-10-26 21:20:19.000000000 
+0300
@@ -47,7 +47,7 @@
 %}
 
 %pure_parser
-%expect 2
+%expect 6
 
 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
 %left ','
@@ -874,6 +874,11 @@ variable_class_name:
 ;
 
 base_variable_with_function_calls:
+    raw_base_variable_with_function_calls		{ $$ = $1; }
+  | raw_base_variable_with_function_calls	'[' dim_offset ']'	
{ fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+;
+
+raw_base_variable_with_function_calls:
 		base_variable		{ $$ = $1; }
 	|	function_call { 
zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.u.EA.type = 
ZEND_PARSED_FUNCTION_CALL; }
 ;
 [2009-10-26 20:58 UTC] johannes@php.net
The idea was often discussed, but nobody found a fully satisfying solution, yet.

Yours is limited to one array dimension.

<?php
function foo() {
    return array(array(42));
}

echo foo()[0][0];
?>

Will for instance not work but should be supported.

I also think it's likely to cause memory problems in edge cases while I wasn't able to create one in my quick tests.

Anyidea aobut the above problem?
 [2009-10-26 22:13 UTC] melfar at gmail dot com
How about this?

<?php
  function car_brands() {
    return array("gm"     => array("chevy" => 1, "hummer"  => 2), 
                 "toyota" => array("prius" => 1, "corolla" => 2));
  }
  var_dump(car_brands()["toyota"]["corolla"]);
?>

New patch is as follows:

--- a/Zend/zend_language_parser.y.orig	2009-10-26 18:13:56.000000000 
+0300
+++ b/Zend/zend_language_parser.y	2009-10-27 01:02:08.000000000 
+0300
@@ -47,7 +47,7 @@
 %}
 
 %pure_parser
-%expect 2
+%expect 6
 
 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
 %left ','
@@ -874,6 +874,11 @@ variable_class_name:
 ;
 
 base_variable_with_function_calls:
+    raw_base_variable_with_function_calls		{ $$ = $1; }
+  | base_variable_with_function_calls	'[' dim_offset ']'	{ 
fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+;
+
+raw_base_variable_with_function_calls:
 		base_variable		{ $$ = $1; }
 	|	function_call { 
zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.u.EA.type = 
ZEND_PARSED_FUNCTION_CALL; }
 ;
 [2009-11-07 23:19 UTC] melfar at gmail dot com
Actually, scratch the previous patch since it only worked on functions 
.  Here is the fixed version, and it also prevents someone from 
modifying the temporary return value, as in:

  car_brands()["toyota"]["corolla"] = 4;

The patch is as follows: 

--- a/Zend/zend_language_parser.y.orig	2009-10-26 18:13:56.000000000 
+0300
+++ b/Zend/zend_language_parser.y	2009-11-08 02:06:20.000000000 
+0300
@@ -47,7 +47,7 @@
 %}
 
 %pure_parser
-%expect 2
+%expect 7
 
 %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
 %left ','
@@ -834,6 +834,11 @@
 ;
 
 variable:
+    raw_variable		{ $$ = $1; }
+    | variable	'[' dim_offset ']'	{ fetch_array_dim(&$$, &$1, 
&$3 TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_FUNCTION_CALL; }
+;
+
+raw_variable:
 		base_variable_with_function_calls T_OBJECT_OPERATOR { 
zend_do_push_object(&$1 TSRMLS_CC); }
 			object_property { zend_do_push_object(&$4 
TSRMLS_CC); } method_or_not variable_properties
 			{ zend_do_pop_object(&$$ TSRMLS_CC); 
$$.u.EA.type = $1.u.EA.type | ($7.u.EA.type ? $7.u.EA.type : 
$6.u.EA.type); }
 [2009-11-09 11:39 UTC] jani@php.net
http://wiki.php.net/summits/pdmnotesmay09 (see Day 2, PHP 6, #13).

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 14:01:29 2024 UTC