|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2006-11-09 13:43 UTC] pstradomski at gmail dot com
Description:
------------
It is now impossible to implement overloaded array properties. Array returned via __get is now a copy (not a reference as in 5.1.x) and it is impossible to force getter to pass a reference.
Reproduce code:
---------------
<?php
class A {
public function & __get($val) {
return $this->keys[$val];
}
public function __set($k, $v) {
$this->keys[$k] = $v;
}
private $keys = array();
}
$a =new A();
$a->arr = array('a','b','c');
$b = &$a->arr;
$b[]= 'd';
foreach ($a->arr as $k => $v) {
echo "$k => $v\n";
}
$a->arr[]='d';
foreach ($a->arr as $k => $v) {
echo "$k => $v\n";
}
?>
Expected result:
----------------
0 => a
1 => b
2 => c
3 => d
0 => a
1 => b
2 => c
3 => d
4 => d
Actual result:
--------------
Notice: Indirect modification of overloaded property A::$arr has no effect in /home/pawel/tmp/a.php on line 18
Notice: Indirect modification of overloaded property A::$arr has no effect in /home/pawel/tmp/a.php on line 21
0 => a
1 => b
2 => c
Notice: Indirect modification of overloaded property A::$arr has no effect in /home/pawel/tmp/a.php on line 25
Notice: Indirect modification of overloaded property A::$arr has no effect in /home/pawel/tmp/a.php on line 27
0 => a
1 => b
2 => c
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 07:00:02 2025 UTC |
Reopening. This should never be "expected behaviour". This way encapsulation got severly broken - __get was introduced to allow dynamic creation of properties - and therefore implementation of record-like classes. Such properties were meant to be indistinguishable from standard properties - but aren't. Neither passing by reference works, nor array elements do. Developer can expect to be able to modify object properties for example in such a way: $x->arr = array('a'); array_push($x->arr, 'b'); Now it is impossible - although it should be. I understand previous behaviour could be considered improper, bu now developers don't even get a chance to choose between passing by value and passing by reference.Reproduce code: --------------- <?php class A{ private $test = array(1,2,3,4,5); public function __get($v){ return $this->test; } } $a = new A; foreach( $a->overloaded_property as $val ) echo $val."<br />\n"; ?> Expected result: ---------------- 1 2 3 4 5 Actual result: -------------- Notice: Indirect modification of overloaded property A::$overloaded_property has no effect in C:\Apache\htdocs\dancho\index.php on line 15 1 2 3 4 5I think the warning should be raised only when someone is trying to write the overloaded property. Foreach and other loop constructs are readonly constructs except when they are using references of the overloaded properties. For example: <?php class A{ private $test = array(1,2,3,4,5); public function __get($v){ return $this->test; } } $a = new A; // This should not raise notice foreach( $a->overloaded_property as $val ) echo $val."<br />\n"; // This should raise notice $a->overloaded_property[] = 6; ?> Thank you, Denis"// This should not raise notice foreach( $a->overloaded_property as $val ) echo $val."<br />\n"; // This should raise notice $a->overloaded_property[] = 6;" I do not agree with that. Neither of the examples should raise a notice. There is no reason for $a->overloadedprop = $bar to work, but not $a->overloadedprop[$foo] = $bar or foreach($a->overloadedprop){} Either properties can be overloaded and therefore read, assigned and iterated over, or not. Overloaded properties should behave the same way as ordinary properties, or else the object's behaviour is unpredictable. Perhaps the solution of using __get() to return a reference is unsatisfactory in some way, but the behaviour should still be there. /Brj?nn