felipe Tue, 08 Jun 2010 00:05:29 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=300266
Log:
- Added array dereferencing support [DOC]
# http://wiki.php.net/rfc/functionarraydereferencing
Changed paths:
U php/php-src/trunk/NEWS
U php/php-src/trunk/UPGRADING
A php/php-src/trunk/Zend/tests/dereference_001.phpt
A php/php-src/trunk/Zend/tests/dereference_002.phpt
A php/php-src/trunk/Zend/tests/dereference_003.phpt
A php/php-src/trunk/Zend/tests/dereference_004.phpt
A php/php-src/trunk/Zend/tests/dereference_005.phpt
A php/php-src/trunk/Zend/tests/dereference_006.phpt
A php/php-src/trunk/Zend/tests/dereference_007.phpt
A php/php-src/trunk/Zend/tests/dereference_008.phpt
A php/php-src/trunk/Zend/tests/dereference_009.phpt
A php/php-src/trunk/Zend/tests/dereference_010.phpt
A php/php-src/trunk/Zend/tests/dereference_011.phpt
U php/php-src/trunk/Zend/zend_language_parser.y
Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS 2010-06-07 23:10:56 UTC (rev 300265)
+++ php/php-src/trunk/NEWS 2010-06-08 00:05:29 UTC (rev 300266)
@@ -22,6 +22,7 @@
- Added an optimization which saves memory and emalloc/efree calls for empty
HashTables (Stas, Dmitry)
+- Added array dereferencing support. (Felipe)
- Added DTrace support. (David Soria Parra)
- Added Tokyo Cabinet abstract DB support to ext/dba. (Michael Maclean)
- Added Jenkins's one-at-a-time hash support to ext/hash. (Martin Jansen)
Modified: php/php-src/trunk/UPGRADING
===================================================================
--- php/php-src/trunk/UPGRADING 2010-06-07 23:10:56 UTC (rev 300265)
+++ php/php-src/trunk/UPGRADING 2010-06-08 00:05:29 UTC (rev 300266)
@@ -185,7 +185,10 @@
11. Syntax additions
====================
--
+- Array dereferencing.
+ e.g.
+ foo()[0]
+ $foo->bar()[0]
===================
12. Windows support
Added: php/php-src/trunk/Zend/tests/dereference_001.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_001.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_001.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,51 @@
+--TEST--
+Testing array dereference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+function a() {
+ return array(1,array(5));
+}
+var_dump(a()[1][0]); // int(5)
+
+function b() {
+ return array();
+}
+var_dump(b()[0]); // Notice: Undefined offset: 0
+
+class foo {
+ public $y = 1;
+
+ public function test() {
+ return array(array(array('foobar')));
+ }
+}
+
+function c() {
+ return array(new foo);
+}
+var_dump(c()[0]->y); // int(1)
+
+function d() {
+ $obj = new foo;
+ return $obj->test();
+}
+var_dump(d()[0][0][0][3]); // string(1) "b"
+
+function e() {
+ $y = 'bar';
+ $x = array('a' => 'foo', 'b' => $y);
+ return $x;
+}
+var_dump(e()['b']); // string(3) "bar"
+
+?>
+--EXPECTF--
+int(5)
+
+Notice: Undefined offset: 0 in %s on line %d
+NULL
+int(1)
+string(1) "b"
+string(3) "bar"
Property changes on: php/php-src/trunk/Zend/tests/dereference_001.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_002.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_002.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_002.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,79 @@
+--TEST--
+Testing array dereference on method calls
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class foo {
+ public function bar() {
+ $x = array();
+ $x[] = 3;
+ $x[] = array(1, 5);
+ $x[] = new foo;
+ return $x;
+ }
+}
+
+$foo = new foo;
+
+var_dump($x = $foo->bar()[1]);
+var_dump($foo->bar()[1][1]);
+var_dump($x[0]);
+var_dump($x = $foo->bar()[2]);
+var_dump($x->bar());
+var_dump($x->bar()[0]);
+
+$x = array();
+$x[] = new foo;
+var_dump($x[0]->bar()[2]);
+var_dump($foo->bar()[2]->bar()[1]);
+var_dump($foo->bar()[2]->bar()[2]->bar()[1][0]);
+var_dump($foo->bar()[2]->bar()[2]->bar()[1][0][1]);
+var_dump($foo->bar()[2]->bar()[2]->bar()[4]);
+var_dump($foo->bar()[3]->bar());
+
+?>
+--EXPECTF--
+array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(5)
+}
+int(5)
+int(1)
+object(foo)#2 (0) {
+}
+array(3) {
+ [0]=>
+ int(3)
+ [1]=>
+ array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(5)
+ }
+ [2]=>
+ object(foo)#3 (0) {
+ }
+}
+int(3)
+object(foo)#3 (0) {
+}
+array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(5)
+}
+int(1)
+NULL
+
+Notice: Undefined offset: 4 in %s on line %d
+NULL
+
+Notice: Undefined offset: 3 in %s on line %d
+
+Fatal error: Call to a member function bar() on a non-object in %s on line %d
Property changes on: php/php-src/trunk/Zend/tests/dereference_002.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_003.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_003.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_003.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,46 @@
+--TEST--
+Testing array dereference on method calls
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class foo {
+ public $x = 2;
+ public function a() {
+ $x = array();
+ $x[] = new foo;
+ return $x;
+ }
+ public function b() {
+ return array(1.2, array(new self));
+ }
+ public function c() {
+ $a = array();
+ $b = &$a;
+ $b[] = true;
+ return $a;
+ }
+ public function d() {
+ return $this->b();
+ }
+}
+
+$foo = new foo;
+
+var_dump($foo->a()[0]->x);
+var_dump($foo->a()[0]);
+var_dump($foo->b()[1][0]->a()[0]->x);
+var_dump($foo->c()[0]);
+var_dump($foo->d()[0]);
+
+?>
+--EXPECTF--
+int(2)
+object(foo)#%d (1) {
+ ["x"]=>
+ int(2)
+}
+int(2)
+bool(true)
+float(1.2)
Property changes on: php/php-src/trunk/Zend/tests/dereference_003.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_004.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_004.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_004.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,27 @@
+--TEST--
+Testing array dereference on __invoke() result
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class foo {
+ public $x = array();
+ public function __construct() {
+ $h = array();
+ $h[] = new stdclass;
+ $this->x = $h;
+ }
+ public function __invoke() {
+ return $this->x;
+ }
+}
+
+
+$fo = new foo;
+var_dump($fo()[0]);
+
+?>
+--EXPECTF--
+object(stdClass)#%d (0) {
+}
Property changes on: php/php-src/trunk/Zend/tests/dereference_004.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_005.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_005.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_005.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,38 @@
+--TEST--
+Testing array dereference on object that implements ArrayAccess
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class obj implements arrayaccess {
+ private $container = array();
+ public function __construct() {
+ $this->container = array(
+ "one" => 1,
+ "two" => 2,
+ "three" => 3,
+ );
+ }
+ public function offsetSet($offset, $value) {
+ $this->container[$offset] = $value;
+ }
+ public function offsetExists($offset) {
+ return isset($this->container[$offset]);
+ }
+ public function offsetUnset($offset) {
+ unset($this->container[$offset]);
+ }
+ public function offsetGet($offset) {
+ return isset($this->container[$offset]) ? $this->container[$offset] : null;
+ }
+}
+
+function x() {
+ return new obj;
+}
+var_dump(x()['two']);
+
+?>
+--EXPECT--
+int(2)
Property changes on: php/php-src/trunk/Zend/tests/dereference_005.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_006.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_006.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_006.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,30 @@
+--TEST--
+Testing array dereference and references
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+function &foo(&$foo) {
+ return $foo;
+}
+
+$a = array(1);
+foo($a)[0] = 2;
+var_dump($a);
+
+foo($a)[] = 3;
+var_dump($a);
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ int(2)
+}
+array(2) {
+ [0]=>
+ int(2)
+ [1]=>
+ int(3)
+}
Property changes on: php/php-src/trunk/Zend/tests/dereference_006.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_007.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_007.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_007.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,22 @@
+--TEST--
+Trying to write on method return
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class foo {
+ public $x = array();
+
+ public function b() {
+ return $this->x;
+ }
+}
+
+$foo = new foo;
+
+$foo->b()[0] = 1;
+
+?>
+--EXPECTF--
+Fatal error: Can't use method return value in write context in %s on line %d
Property changes on: php/php-src/trunk/Zend/tests/dereference_007.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_008.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_008.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_008.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,33 @@
+--TEST--
+Testing array dereference with dynamic method name and references
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class foo {
+ public $x = array(1);
+
+ public function &b() {
+ return $this->x;
+ }
+}
+
+$foo = new foo;
+
+$a = 'b';
+var_dump($foo->$a()[0]);
+
+$h = &$foo->$a();
+$h[] = 2;
+var_dump($foo->$a());
+
+?>
+--EXPECT--
+int(1)
+array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+}
Property changes on: php/php-src/trunk/Zend/tests/dereference_008.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_009.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_009.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_009.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,26 @@
+--TEST--
+Testing array dereference with references
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+$a = array();
+
+function &a() {
+ return $GLOBALS['a'];
+}
+
+var_dump($h =& a());
+$h[] = 1;
+var_dump(a()[0]);
+
+$h[] = array($h);
+var_dump(a()[1][0][0]);
+
+?>
+--EXPECT--
+array(0) {
+}
+int(1)
+int(1)
Property changes on: php/php-src/trunk/Zend/tests/dereference_009.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_010.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_010.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_010.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,27 @@
+--TEST--
+Testing dereference in non-array values
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+function a() {
+ return 1;
+}
+
+$a = 1;
+var_dump($a[1]);
+var_dump(a()[1]);
+
+function b() {
+ return new stdClass;
+}
+
+var_dump(b()[1]);
+
+?>
+--EXPECTF--
+NULL
+NULL
+
+Fatal error: Cannot use object of type stdClass as array in %s on line %d
Property changes on: php/php-src/trunk/Zend/tests/dereference_010.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Added: php/php-src/trunk/Zend/tests/dereference_011.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/dereference_011.phpt (rev 0)
+++ php/php-src/trunk/Zend/tests/dereference_011.phpt 2010-06-08 00:05:29 UTC (rev 300266)
@@ -0,0 +1,45 @@
+--TEST--
+Testing array dereference with chaining
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+class foo {
+ public $arr;
+
+ public function &a() {
+ return $this->arr;
+ }
+}
+
+$foo = new foo;
+
+$h = &$foo->a();
+$h[] = 1;
+$h[] = $foo;
+var_dump($foo->a()[1]->arr[1]->a()[1]->arr[1]->arr[0]);
+var_dump($foo->a()[1]);
+var_dump($foo->a()[1]->arr[1]);
+
+?>
+--EXPECTF--
+int(1)
+object(foo)#%d (1) {
+ ["arr"]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ *RECURSION*
+ }
+}
+object(foo)#%d (1) {
+ ["arr"]=>
+ &array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ *RECURSION*
+ }
+}
Property changes on: php/php-src/trunk/Zend/tests/dereference_011.phpt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Revision
Added: svn:eol-style
+ native
Modified: php/php-src/trunk/Zend/zend_language_parser.y
===================================================================
--- php/php-src/trunk/Zend/zend_language_parser.y 2010-06-07 23:10:56 UTC (rev 300265)
+++ php/php-src/trunk/Zend/zend_language_parser.y 2010-06-08 00:05:29 UTC (rev 300266)
@@ -930,11 +930,20 @@
T_OBJECT_OPERATOR object_property { zend_do_push_object(&$2 TSRMLS_CC); } method_or_not { $$.EA = $4.EA; }
;
-method_or_not:
+array_method_dereference:
+ array_method_dereference '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+ | method '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+;
+
+method:
'(' { zend_do_pop_object(&$1 TSRMLS_CC); zend_do_begin_method_call(&$1 TSRMLS_CC); }
function_call_parameter_list ')'
- { zend_do_end_function_call(&$1, &$$, &$3, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);
- zend_do_push_object(&$$ TSRMLS_CC); $$.EA = ZEND_PARSED_METHOD_CALL; }
+ { zend_do_end_function_call(&$1, &$$, &$3, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+;
+
+method_or_not:
+ method { $$ = $1; zend_do_push_object(&$$ TSRMLS_CC); $$.EA = ZEND_PARSED_METHOD_CALL; }
+ | array_method_dereference { $$ = $1; zend_do_push_object(&$$ TSRMLS_CC); $$.EA = ZEND_PARSED_METHOD_CALL; }
| /* empty */ { $$.EA = ZEND_PARSED_MEMBER; }
;
@@ -953,8 +962,15 @@
reference_variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$=$1;; }
;
+array_function_dereference:
+ array_function_dereference '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+ | function_call { zend_do_begin_variable_parse(TSRMLS_C); $$.EA = ZEND_PARSED_FUNCTION_CALL; }
+ '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$4 TSRMLS_CC); }
+;
+
base_variable_with_function_calls:
- base_variable { $$ = $1; }
+ base_variable { $$ = $1; }
+ | array_function_dereference { $$ = $1; }
| function_call { zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.EA = ZEND_PARSED_FUNCTION_CALL; }
;
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php