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

Reply via email to