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