Jump to content

Set array in SplObjectStorage


NotionCommotion

Recommended Posts

How do I set the value of an element in an array stored in SplObjectStorage?

 

As seen, I receive a Indirect modification of overloaded element of SplObjectStorage has no effect warning.

 

Thanks

<?php

$s = new SplObjectStorage();

$o1 = new StdClass;
$s->attach($o1,123);

echo('$s[$o1]=');
var_dump($s[$o1]);

echo('$s[$o1]=321;'."\n");
$s[$o1]=321;

echo('$s[$o1]=');
var_dump($s[$o1]);

$o2 = new StdClass;
$s->attach($o2,['a'=>111,'b'=>222]);

echo('$s[$o2]=');
var_dump($s[$o2]);

echo('s[$o2][a]=');
var_dump($s[$o2]['a']);

echo('$s[$o2][a]=333;'."\n");
$s[$o2]['a']=333;
var_dump($s[$o2]['a']);
$s[$o1]=int(123)
$s[$o1]=321;
$s[$o1]=int(321)
$s[$o2]=array(2) {
  ["a"]=>
  int(111)
  ["b"]=>
  int(222)
}
s[$o2][a]=int(111)
$s[$o2][a]=333;
<br />
<b>Notice</b>:  Indirect modification of overloaded element of SplObjectStorage has no effect in <b>/var/www/public/spl.php</b> on line <b>27</b><br />
int(111)
Link to comment
Share on other sites

Arrays are by-val so yes: you'd have to get, update, and set separately.

 

How does that relate to the warning Indirect modification of overloaded element of SplObjectStorage has no effect warning?  When storing an array, is it caused by PHP internally hashing the array and turning it into a string and storing that hash?  Where is this documented?

 

Is it more typical to use an object since they are passed by reference? 

$s->attach($o,(object)['a'=>111,'b'=>222]);
$s[$o1]->b=555;
Link to comment
Share on other sites

The warning is because indexing an object like an array is just a shorthand for calling the offsetGet method of the ArrayAccess interface. That method returns the data stored under the given index by value so changes made to it will not persist. To have the change persist you have to re-assign the index the new changed value so that the offsetSet method is called.

 

You can see this warning if you create your own object that implements ArrayAccess and try to do the same:

 

<?php

class MyStorage implements ArrayAccess {
    private $map;
    public function offsetExists($n){ return isset($this->map[$n]); }
    public function offsetGet($n){ return $this->map[$n]; }
    public function offsetSet($n, $v){ $this->map[$n] = $v; }
    public function offsetUnset($n){ unset($this->map[$n]); }
}

$s = new MyStorage();
$s['blah'] = ['a' => 1, 'b' => 2, 'c' => 3];
var_dump($s['blah']);

$s['blah']['a'] = 10;
var_dump($s['blah']);
Link to comment
Share on other sites

Is it more typical to use an object since they are passed by reference?

I would expect that it's typical to put objects into SplObjectStorage. With what you're doing now you're basically treating the class as a fancy type of array that allows using objects as keys.
Link to comment
Share on other sites

I would expect that it's typical to put objects into SplObjectStorage. With what you're doing now you're basically treating the class as a fancy type of array that allows using objects as keys.

 

Agree, I am hacking an array to mimic an object.  There just easier to initiate for the type I needed.  Better off using an object, and it works as well.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.