Search code examples
phpclonespl

Clone SplHeap that contains Objects in PHP


I will like to know how can I clone an extended class of SplHeap that contains objects. For example, if FooHeap extends SplHeap, is it possible for FooHeap to have a __clone method and clone its object elements?

class FooHeap extends SplHeap{
    public function compare($value1, $value2){.... }

    public function __clone(){

        // how do I access its elements to clone?
    }
}

Alternatively, if I have to create a new FooHeap object and re-insert the clones of the object elements, is there a way (e.g. from top to bottom, or from bottom to top) that I should re-insert the cloned elements to ensure optimized performance?


Solution

  • The essence of SplHeap is that it automatically sorts all inserted values (like objects), and when iterating over it, every value is deleted from the heap.

    When you clone a heap, the inserted values are copied as well, but objects are not cloned, but copied as reference as expected.

    The usual approach would be to iterate over the stored data and clone every object found. But because iterating deletes the nodes, you have to collect them somewhere and re-insert.

    There is no choice in order, because all you can do is "get the next".

    If you do worry about performance, measure!

    I found this code to be working:

    class MyHeap extends SplHeap
    {
    
        public function compare($a, $b)
        {
            return (strcmp(get_class($a), get_class($b)));
        }
    
        public function __clone()
        {
            echo "Im cloning in ";
            foreach ($this as $obj) {
                $clones[] = clone($obj);
            }
            foreach ($clones as $obj) {
                $this->insert($obj);
            }
            var_dump($this);
        }
    }
    
    $heap = new MyHeap();
    
    $obj1 = new stdClass();
    $heap->insert($obj1);
    $obj2 = new stdClass();
    $heap->insert($obj2);
    
    var_dump($heap);
    
    $clone = clone($heap);
    
    var_dump($clone);
    foreach ($clone as $insert) {
        var_dump($insert);
    }
    foreach ($heap as $insert) {
        var_dump($insert);
    }
    

    Outputs:

    class MyHeap#1 (0) {
    }
    Im cloning in class MyHeap#4 (0) {
    }
    class MyHeap#4 (0) {
    }
    class stdClass#6 (0) {
    }
    class stdClass#7 (0) {
    }
    class stdClass#2 (0) {
    }
    class stdClass#3 (0) {
    }