php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74058 ArrayObject can not notice changes
Submitted: 2017-02-07 17:13 UTC Modified: -
From: php at abiusx dot com Assigned:
Status: Closed Package: SPL related
PHP Version: 7.0.15 OS: OS X
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: php at abiusx dot com
New email:
PHP Version: OS:

 

 [2017-02-07 17:13 UTC] 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.

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-02 14:08 UTC] andrew dot nester dot dev at gmail dot com
Thanks, really good catch! I've just added PR fixing this issue.
 [2017-03-08 23:10 UTC] nikic@php.net
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
 [2017-03-08 23:10 UTC] nikic@php.net
-Status: Open +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC