jeudi 21 juin 2018

php cloning objects - one cloned object then contains not a cloned object. howto solve it?

I have a class which holds some objects. An important class needs also the holder of objects but when clonig the holder inside the important class is still the initial holder when constructed.

My question:

how can i make sure that the injected holder object in DD::_list gets updated with the new clones?.

I think there are several ways but i dont see a way how to get it automatically. Or how would you do it?

Btw: ALL is a context object, DD kind of backend controller. This situation came up with unittest when i tried to change the context and it fails obviously ALL inside DD is jailed.

<?php

abstract class abst {
    protected $_input;
    public function __construct() { $this->_input['i am'] = 'master'; }
    public function __clone() { $this->_input['i am'] = 'clone'; }
}

class AA extends abst {}
class BB extends abst {}
class CC extends abst {}
class DD extends abst {
    private $_all;
    public function __construct( ALL $obj, $params=array() )
    {
        $this->_all = $obj;
        parent::__construct();
    }

    public function getAll()
    {
        return $this->_all;
    }
}

class ALL extends abst 
{
    public function __construct()
    {
        $this->_list = array();
        parent::__construct();
    }

    public function __clone()
    {
        foreach ( $this->_list as $name => $obj ) {
            $this->_list[$name] = clone $obj;
        }
    }

    public function setObject( $object )
    {
        $this->_list[ get_class( $object ) ] = $object;
    }

    public function getObject( $name )
    {
        return $this->_list[ $name ];
    }

}
$all =  new ALL();
$all->setObject( new AA() );
$all->setObject( new BB() );
$all->setObject( new DD( $all ) );
$all->setObject( new CC() ); // late checkin

$dd = $all->getObject('DD');
// does dd->_all know about CC ?
$cc = $dd->getAll()->getObject('CC'); // yes, in this case
print_r($cc);
// print_r($all);

// what about clone? does dd knows changes of cc after a clone?
// No, it knows cc but it is the initial object, 
//changing c has no effect for DD
$cloneAll = clone $all; 

print_r($cloneAll);

Aucun commentaire:

Enregistrer un commentaire