Bug #74058 [Opn->Csd]: ArrayObject can not notice changes

From: Date: Wed, 08 Mar 2017 23:10:55 +0000
Subject: Bug #74058 [Opn->Csd]: ArrayObject can not notice changes
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-207753@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74058&edit=1

 ID:                 74058
 Updated by:         nikic@php.net
 Reported by:        php at abiusx dot com
 Summary:            ArrayObject can not notice changes
-Status:             Open
+Status:             Closed
 Type:               Bug
 Package:            SPL related
 Operating System:   OS X
 PHP Version:        7.0.15
 Block user comment: N
 Private report:     N

 New Comment:

Automatic comment on behalf of andrew.nester.dev@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8f799137d7ed6634687e272cea798cac56da4b98
Log: Fixed bug #74058


Previous Comments:
------------------------------------------------------------------------
[2017-03-02 14:08:09] andrew dot nester dot dev at gmail dot com

Thanks, really good catch! I've just added PR fixing this issue.

------------------------------------------------------------------------
[2017-02-07 17:13:01] php at abiusx dot com

Description:
------------
I want to create a class that mimics arrays, but has full control over itself, i.e., whenever a
property is updated/set, it knows.

Basically I want to use this to cache this array in memory persistently, and update the cache on the
fly when updated.

Using a custom class with __get, __set, or using ArrayAccess, or using SPL ArrayObject did not
enable me to get past this simple limitation.

PHP implicitly creates a stdClass when you do

$obj->a->b='something';

But does not invoke set or get on $obj with key "a". Even if a stdClass is initiated, one
would expect it to hold the value, then be passed to set(). Or one would expect a stdClass to be
created, then get() used to retrieve it for modifications.

There is basically no way to notice such behavior from within the class. Even an error handler,
although recognizing this happenning, can not access the properties.

Test script:
---------------
class MyArrayObject extends ArrayObject
{
	function __construct($input=[])
	{
		parent::__construct($input,ArrayObject::ARRAY_AS_PROPS);
	}
	function offsetSet($x,$v)
	{
		echo "offsetSet('{$x}')\n";
		return parent::offsetSet($x,$v);
	}
	function &offsetGet($x)
	{
		echo "offsetGet('{$x}')\n";
		$t=parent::offsetGet($x);
		return $t;
	}
	function __get($x)
	{
		echo "__get('{$x}')\n";
	}
	function __set($x,$v)
	{
		echo "__set('{$x}')\n";
	}
	function offsetExists($x)
	{
		echo "offsetExists('{$x}')\n";
		return parent::offsetExists($x);
	}
}
$x=new MyArrayObject;
$x->hello=5;
$x['hi']=10;
$x['hello']++;
@$x->a->b=7;
$x->a->b++;
var_dump($x);


Expected result:
----------------
either set() or get() being called.

Actual result:
--------------
No call.


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=74058&edit=1


Thread (3 messages)

« previous php.bugs (#207753) next »