Jump to content

How to replace data associated with an existing object in SplObjectStorage?


Recommended Posts

splobjectstorage.attach shows how to add an object inside the storage and associate it to some data. 

How should one replace the data associated to an object already in storage?

All of the following solutions seem to work, however, I would like confirmation as I couldn't find and specific direction in the documentation.  Assuming that detaching shown in my options 3 and 4 is not required, right?  Probably option 2?

Or, would it be best not to replace the data in storage, but add a shell object to the storage and update the data property?  Use case is the object is a stream and the data is a specific type of client which can change over time.

<?php

class dataA{}
class dataB{}
class dataC{}
class dataD{}
class dataE{}
class obj{}

$storage = new SplObjectStorage();

$obj=new obj;

$storage->attach($obj, new dataA);
$data = $storage[$obj];
var_dump($data);

//Option 1
$storage->attach($obj, new dataB);
$data = $storage[$obj];
var_dump($data);

//Option 2
$storage->offsetSet($obj, new dataC);
$data = $storage[$obj];
var_dump($data);

//Option 3
$storage->detach($obj);
$storage->attach($obj, new dataD);
$data = $storage[$obj];
var_dump($data);

//Option 4
$storage->detach($obj);
$storage->offsetSet($obj, new dataE);
$data = $storage[$obj];
var_dump($data);
object(dataA)#3 (0) { } object(dataB)#4 (0) { } object(dataC)#3 (0) { } object(dataD)#4 (0) { } object(dataE)#3 (0) { }

 

Edited by NotionCommotion
Added thought about not changing
Link to comment
Share on other sites

You can just re-attach it to change the data, or just use it as an array.

//Option 1
$storage->attach($obj, new dataB);
$data = $storage[$obj];
var_dump($data);

//Option 2
$storage[$obj]=new dataC;
$data = $storage[$obj];
var_dump($data);

offsetSet is there because SplObjectStorage implements ArrayAccess which means you can just read/write keys like any other array.  The offset* functions are not really intended to be called directly.

Link to comment
Share on other sites

Thanks kicken,  Any recommendations of these two approaches.  The second is what I meant by "Or, would it be best not to replace the data in storage..."

class OptionOne
{
    private $clientList;
    public function __construct() {
        $this->clientList = new SplObjectStorage;;
    }

    public function clientConnects($stream) {
        $client=new UnregisteredClient($stream);
        $stream->setClient($client);
        $this->clientList->attach($stream, new UnregisteredClient);
    }

    public function clientRegisters($stream, $data) {
        $client=new NewClient($stream, $data);
        $stream->setClient($client);
        $this->clientList[$stream]=$client;
    }
}
class ClientShell
{
    private $client;
    public function __construct($client) {$this->setClient($client);}
    public function setClient($client){$this->client=$client;}
    public function getClient(){return $this->client;}
    
}

class OptionTwo
{
    private $clientList;
    public function __construct() {
        $this->clientShellList = new SplObjectStorage;;
    }

    public function clientConnects($stream) {
        $clientShell=new ClientShell(new UnregisteredClient($stream));
        $this->clientShellList->attach($stream, $clientShell);
    }

    public function clientRegisters($stream, $data) {
        $client=new NewClient($stream, $data);
        $this->clientShellList[$stream]->setClient($client);
    }

 

Link to comment
Share on other sites

I'd probably just go with essentially option one.  I don't see any real benefit to using a shell object.

class OptionOne
{
    private $clientList;
    public function __construct() {
        $this->clientList = new SplObjectStorage;;
    }

    public function clientConnects($stream) {
        $client=new UnregisteredClient($stream);

        $stream->setClient($client);
        $this->clientList[$stream] = $client;
    }

    public function clientRegisters($stream, $data) {
        $client=new NewClient($stream, $data);

        $stream->setClient($client);
        $this->clientList[$stream] = $client;
    }
}

 

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.