Req #43239 [Opn->Wfx]: read/write for __get and __set like in C#
| From: | nikic@php.net | Date: | Sat, 09 Dec 2017 14:32:27 +0000 |
| Subject: | Req #43239 [Opn->Wfx]: read/write for __get and __set like in C# | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-213032@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=43239&edit=1
ID: 43239
Updated by: nikic@php.net
Reported by: bugs dot php dot net-V29nHf1_z-nsp at cvogt dot org
Summary: read/write for __get and __set like in C#
-Status: Open
+Status: Wont fix
Type: Feature/Change Request
Package: Class/Object related
Operating System: *
PHP Version: 5.3.0
Block user comment: N
Private report: N
New Comment:
The desired behavior can already be achieved by returning from __get() by reference. For simple
operations (like +=) we do support desugaring compound assignments into a __get() followed by
__set(). However, for array operations this would be very inefficient, as it would require copying
the entire array, performing the operation and then replacing the original array with a copy. This
is why array operations only work with __get() returning by reference, which allows to do this
efficiently.
Previous Comments:
------------------------------------------------------------------------
[2007-11-11 15:06:37] bugs dot php dot net-V29nHf1_z-nsp at cvogt dot org
The Problem occurs for non-object data types only. string, array, int, float
------------------------------------------------------------------------
[2007-11-11 00:49:36] bugs dot php dot net-V29nHf1_z-nsp at cvogt dot org
Description:
------------
This was already reported 'fixed' in
http://bugs.php.net/bug.php?id=38102
http://bugs.php.net/bug.php?id=37667
but I think the 'fix' is wrong.
It renders __get and __set a LOT less useful then they could be.
__get and __set should provide a means to replace public fields while maintaining the interface.
With the provided 'fix' this is not possible. Code like
$r->Property[] = new Class2();
works fine for Property as a public field but breaks if Property is replaced using __get and __set.
We all agree __get should not return a reference. Instead I think that cases that involve read and
write operations like [] and += and .= should equal a call to __get and a subsequent call to __set.
More specificially:
$r->Property[] = new Class2();
should equal
$x = $r->__get('Property');
$x[] = new Class2();
$r->__set('Property',$x);
This is exactly the way C# does it. See http://www.geocities.com/csharpfaq/properties.html
Reproduce code:
---------------
class Class1 {
protected $property = array();
function __get($name) {
return $this->property;
}
}
class Class2 {}
$r = new Class1();
$r->Property[] = new Class2();
$r->Property[] = new Class2();
var_dump($r);
Expected result:
----------------
object(Class1)#1 (1) {
["property:protected"]=>
array(1) {
[0]=>
object(Class2)#2 (0) {
}
[0]=>
object(Class2)#3 (0) {
}
}
}
Actual result:
--------------
In PHP 5.3.0-dev (cli) (built: Oct 30 2007 08:45:02):
object(Class1)#1 (1) {
["property:protected"]=>
array(0) {
}
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=43239&edit=1