Asked  7 Months ago    Answers:  5   Viewed   38 times

Can someone explain me

  • what is Object Cloning in php?

  • When should i use clone keyword in php?

 Answers

45

Object cloning is the act of making a copy of an object. As Cody pointed out, cloning in PHP is done by making a shallow copy of the object. This means that internal objects of the cloned object will not be cloned, unless you explicitly instruct the object to clone these internal objects too, by defining the magic method __clone().

If you don't utilize the __clone method, the internal objects of the new object will be references to the same objecs in memory as the internal objects of the original object that was cloned.

Consider these examples:

// in this exampe the internal member $_internalObject of both objects
// reference the same instance of stdClass in memory.
class CloneableClass
{
    private $_internalObject;

    public function __construct()
    {
        // instantiate the internal member
        $this->_internalObject = new stdClass();
    }
}

$classA = new CloneableClass();
$classB = clone $classA;


// in this exampe the internal member $_internalObject of both objects
// DON'T reference the same instance of stdClass in memory, but are inividual instances
class CloneableClass
{
    private $_internalObject;

    public function __construct()
    {
        // instantiate the internal member
        $this->_internalObject = new stdClass();
    }

    // on clone, make a deep copy of this object by cloning internal member;
    public function __clone()
    {
        $this->_internalObject = clone $this->_internalObject;
    }
}

$classA = new CloneableClass();
$classB = clone $classA;

Use cases for cloning would for instance be a case where you don't want outside objects to mess with the internal state of an object.

Let's say you have a class User with a internal object Address.

class Address
{
    private $_street;
    private $_streetIndex;
    private $_city;
    // etc...

    public function __construct( $street, $streetIndex, $city /* etc.. */ )
    {
        /* assign to internal values */
    }
}

class User
{
    // will hold instance of Address
    private $_address;

    public function __construct()
    {
        $this->_address = new Address( 'somestreet', '1', 'somecity' /* etc */ );
    }

    public function getAddress()
    {
        return clone $this->_address;
    }
}

For arguments sake, let's say you don't want outside objects to mess with the internal Address of User objects, but you do want to be able to give them a copy of the Address object. The above example illustrates this. The getAddress method returns a clone of the address object to calling objects. This means that if the calling object alters the Address object, the internal Address of User will not change. If you didn't give a clone, then the outside object would be able to alter the internal Address of User, because a reference is given by default, not a clone.

Hope this all makes some sense.

PS.:
Be aware though, that if Address would also have internal objects, you would have to make sure Address makes a deep copy of itself on cloning (as per my second example of this post) by defining __clone() in Address. Otherwise you will get headaches of trying to figure out why your data is screwed.

Wednesday, March 31, 2021
 
Floris
answered 7 Months ago
69

There might be a semicolon or bracket missing a line before your pasted line.

It seems fine to me; every string is allowed as an array index.

Wednesday, March 31, 2021
 
Revent
answered 7 Months ago
58

You could add a __clone() method to your email class. Which is automatically called when an instance of this class is cloned via clone(). In this method you can then manually add the template.

Example:

class email {
    __clone() {
         $this->template = new template();
    }
}

.

unserialize(serialize($object)); // would be another solution...
Wednesday, March 31, 2021
 
Nickool
answered 7 Months ago
71

To make things short, an exception is a "special condition that change the normal flow of program execution" (quoting wikipedia)


You might be interested by (at least) those couple of articles :

  • Exception handling - wikipedia
  • Exceptional PHP: Introduction to Exceptions
  • Exceptional PHP: Extending The Base Exception Class
  • Exceptional PHP: Nesting Exceptions In PHP

They should give you some interesting elements -- especially the second one, for "what is an exception in php"


One of the advantages (which is part of the basic idea) is :

  • you have the "normal" code in the try block
  • and the biggest part of the "dealing with problems" code is in the catch block
  • which means less "dealing with problems" code in the middle of the "normal" code
  • and also allows you to regroup "dealing with problems" portions of code
Wednesday, March 31, 2021
 
Stefan
answered 7 Months ago
19

Replace

Octagon copy = (Octagon)test.clone();

with

Octagon copy = (Octagon)((Octagon)test).clone();

so that the called clone method is the one of your class.

Wednesday, August 4, 2021
 
DaveRandom
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :