fix(parser): 修复数组元素引用赋值写回问题 #33
Merged
韩天峰
merged 3 commits from parser-fix-array-element-ref-assign-writeback into master 1 month ago
4 changed files with 136 additions and 3 deletions
@ -0,0 +1,29 @@ |
|||||||
|
--TEST-- |
||||||
|
array reference assignment: append and element assignment write back through reference |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function main() |
||||||
|
{ |
||||||
|
$arr1 = [1, 2, 3]; |
||||||
|
$arr2 = [&$arr1[0]]; |
||||||
|
$arr2[0] = 123; |
||||||
|
$arr2[] = &$arr1[1]; |
||||||
|
$arr2[1] = 456; |
||||||
|
var_dump($arr1, $arr2); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
&int(123) |
||||||
|
[1]=> |
||||||
|
&int(456) |
||||||
|
[2]=> |
||||||
|
int(3) |
||||||
|
} |
||||||
|
array(2) { |
||||||
|
[0]=> |
||||||
|
&int(123) |
||||||
|
[1]=> |
||||||
|
&int(456) |
||||||
|
} |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
--TEST-- |
||||||
|
array reference assignment to element: $arr[$k] = &$v writes back through reference |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
class RefSource |
||||||
|
{ |
||||||
|
public $value = 30; |
||||||
|
public static $staticValue = 40; |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
$x = 10; |
||||||
|
$y = 20; |
||||||
|
$arr = [1, 2, 3]; |
||||||
|
$arr[0] = &$x; // 覆盖已有元素为引用 |
||||||
|
$arr[5] = &$y; // 新建元素为引用 |
||||||
|
$x = 100; |
||||||
|
$y = 200; |
||||||
|
var_dump($arr[0], $arr[5]); // 100, 200 |
||||||
|
|
||||||
|
// 通过元素引用写回 |
||||||
|
$arr[0] = 111; |
||||||
|
$arr[5] = 222; |
||||||
|
var_dump($x, $y); // 111, 222 |
||||||
|
|
||||||
|
// 嵌套:引用赋值到多维数组元素 |
||||||
|
$z = 7; |
||||||
|
$m = [[1], [2]]; |
||||||
|
$m[0][0] = &$z; |
||||||
|
$z = 77; |
||||||
|
var_dump($m[0][0]); // 77 |
||||||
|
|
||||||
|
// 左侧数组追加/元素写入不可因右侧是属性引用而被重新按读取解析 |
||||||
|
$source = new RefSource(); |
||||||
|
$propertyRefs = []; |
||||||
|
$propertyRefs[] = &$source->value; |
||||||
|
$propertyRefs[2] = &RefSource::$staticValue; |
||||||
|
$propertyRefs[0] = 333; |
||||||
|
$propertyRefs[2] = 444; |
||||||
|
var_dump($source->value, RefSource::$staticValue); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(100) |
||||||
|
int(200) |
||||||
|
int(111) |
||||||
|
int(222) |
||||||
|
int(77) |
||||||
|
int(333) |
||||||
|
int(444) |
||||||
@ -0,0 +1,37 @@ |
|||||||
|
--TEST-- |
||||||
|
dynamically typed array element assignment preserves references and ArrayAccess writes |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function writeElement(mixed $container, mixed $key, mixed $value): void |
||||||
|
{ |
||||||
|
$container[$key] = $value; |
||||||
|
} |
||||||
|
|
||||||
|
function writeReferencedContainer(mixed &$container, mixed $value): void |
||||||
|
{ |
||||||
|
$container[0] = $value; |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
$referenced = 10; |
||||||
|
$array = [&$referenced]; |
||||||
|
writeElement($array, 0, 123); |
||||||
|
var_dump($referenced, $array[0]); |
||||||
|
|
||||||
|
$referencedAgain = 20; |
||||||
|
$arrayByReference = [&$referencedAgain]; |
||||||
|
writeReferencedContainer($arrayByReference, 234); |
||||||
|
var_dump($referencedAgain, $arrayByReference[0]); |
||||||
|
|
||||||
|
$object = new ArrayObject(); |
||||||
|
writeElement($object, 'key', 456); |
||||||
|
var_dump($object['key']); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(123) |
||||||
|
int(123) |
||||||
|
int(234) |
||||||
|
int(234) |
||||||
|
int(456) |
||||||
Loading…
Reference in new issue