Bird
Raised Fist0
PHPprogramming~15 mins

__clone for object copying in PHP - Deep Dive

Choose your learning style10 modes available
Overview - __clone for object copying
What is it?
__clone is a special method in PHP used to create a copy of an object. When you copy an object using the clone keyword, PHP calls the __clone method if it exists. This method allows you to customize how the object is copied, especially when the object contains other objects inside it. Without __clone, PHP makes a shallow copy, which might not be what you want.
Why it matters
Copying objects correctly is important to avoid unexpected changes in your program. Without __clone, copying an object with other objects inside can lead to both copies sharing the same inner objects. This can cause bugs that are hard to find because changing one object changes the other. __clone helps you make a true, independent copy, keeping your data safe and your program predictable.
Where it fits
Before learning __clone, you should understand basic PHP objects and how assignment works with them. After __clone, you can learn about deep copying, serialization, and design patterns like Prototype that rely on object copying.
Mental Model
Core Idea
The __clone method lets you control how an object is copied so that all parts of it become independent duplicates.
Think of it like...
Imagine you have a photocopy machine that copies a book. Without __clone, it only copies the cover and leaves the pages as empty placeholders pointing to the original book’s pages. With __clone, you tell the machine to copy every page too, so the new book is fully independent.
Original Object
┌───────────────┐
│ Object A     │
│ ┌─────────┐ │
│ │Object B │ │
│ └─────────┘ │
└───────────────┘

Shallow Copy (without __clone)
┌───────────────┐
│ Object A'    │
│ ┌─────────┐ │
│ │Object B │ │  <-- same Object B as original
│ └─────────┘ │
└───────────────┘

Deep Copy (with __clone)
┌───────────────┐
│ Object A'    │
│ ┌─────────┐ │
│ │Object B'│ │  <-- new copy of Object B
│ └─────────┘ │
└───────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding Object Assignment
🤔
Concept: Objects in PHP are assigned by reference, not by value.
When you assign one object variable to another, both variables point to the same object in memory. For example: $a = new stdClass(); $a->value = 10; $b = $a; $b->value = 20; echo $a->value; // outputs 20 Here, changing $b also changes $a because they are the same object.
Result
Output is 20 because $a and $b refer to the same object.
Understanding that object variables are references helps explain why copying objects needs special handling.
2
FoundationUsing clone to Copy Objects
🤔
Concept: The clone keyword creates a shallow copy of an object.
Using clone creates a new object with the same properties as the original: $a = new stdClass(); $a->value = 10; $b = clone $a; $b->value = 20; echo $a->value; // outputs 10 Now $a and $b are different objects, so changing $b does not affect $a.
Result
Output is 10 because $a and $b are separate objects after cloning.
Clone creates a new object, but only copies properties shallowly, which matters when properties are objects themselves.
3
IntermediateWhat Happens Without __clone Method
🤔Before reading on: do you think cloning an object with another object property copies the inner object too? Commit to yes or no.
Concept: By default, clone copies properties shallowly, so inner objects are shared.
Consider: class Inner { public $data; } class Outer { public $inner; } $inner = new Inner(); $inner->data = 5; $outer1 = new Outer(); $outer1->inner = $inner; $outer2 = clone $outer1; $outer2->inner->data = 10; echo $outer1->inner->data; // outputs 10 The inner object is shared between $outer1 and $outer2.
Result
Output is 10, showing the inner object was not copied but shared.
Knowing that clone does shallow copying by default reveals why __clone is needed for deep copying.
4
IntermediateDefining __clone to Deep Copy
🤔Before reading on: do you think __clone can be used to copy inner objects manually? Commit to yes or no.
Concept: __clone lets you customize cloning to copy inner objects too.
You can define __clone in your class to clone inner objects: class Outer { public $inner; public function __clone() { $this->inner = clone $this->inner; } } Now cloning Outer creates a new Inner object too, making copies fully independent.
Result
Changing inner data in the clone does not affect the original object.
Understanding __clone as a hook for deep copying inner objects is key to safe object duplication.
5
AdvancedHandling Complex Object Graphs in __clone
🤔Before reading on: do you think __clone automatically handles circular references? Commit to yes or no.
Concept: In complex objects with circular references, __clone must be carefully written to avoid infinite loops.
If objects reference each other, naive cloning can cause infinite recursion: class Node { public $child; public function __clone() { if ($this->child) { $this->child = clone $this->child; } } } If two nodes reference each other, cloning one triggers cloning the other endlessly unless you add checks or use a cloning map.
Result
Without precautions, cloning circular references causes errors or crashes.
Knowing the limits of __clone in complex graphs prevents bugs and guides design of safe cloning strategies.
6
ExpertUsing __clone in Prototype Design Pattern
🤔Before reading on: do you think __clone is useful beyond copying objects? Commit to yes or no.
Concept: __clone is a core part of the Prototype pattern, enabling object creation by cloning existing instances.
Prototype pattern uses cloning to create new objects efficiently: class Prototype { public $value; public function __clone() { // customize cloning if needed } } $prototype = new Prototype(); $prototype->value = 42; $newObject = clone $prototype; This avoids complex constructors and allows runtime object configuration.
Result
Cloning creates new objects based on a prototype, simplifying object creation.
Understanding __clone’s role in design patterns shows its power beyond simple copying.
Under the Hood
When you use clone on an object, PHP creates a new object instance and copies all properties from the original to the new one. If the class defines a __clone method, PHP calls it after copying. This method can modify the new object, for example by cloning properties that are objects themselves. Internally, PHP performs a shallow copy first, then __clone allows deep copying or other adjustments.
Why designed this way?
PHP separates shallow copying and customization to give developers control. Automatic deep copying would be expensive and unpredictable, especially with complex or circular references. The __clone method lets developers decide how deep copying should behave, balancing performance and correctness.
Clone Operation Flow

Original Object
     │
     ▼
Shallow Copy by PHP
     │
     ▼
Call __clone() if exists
     │
     ▼
Custom adjustments (e.g., clone inner objects)
     │
     ▼
New independent object ready
Myth Busters - 4 Common Misconceptions
Quick: Does cloning an object automatically clone all objects inside it? Commit to yes or no.
Common Belief:Cloning an object copies everything inside it automatically, including all nested objects.
Tap to reveal reality
Reality:Cloning only copies properties shallowly by default; nested objects remain shared unless __clone clones them explicitly.
Why it matters:Assuming deep copy by default leads to bugs where changes in one object unexpectedly affect another.
Quick: Is __clone called when assigning one object variable to another? Commit to yes or no.
Common Belief:Assigning one object variable to another calls __clone and creates a copy.
Tap to reveal reality
Reality:Assignment copies the reference only; __clone is called only when using the clone keyword.
Why it matters:Confusing assignment with cloning causes unexpected shared references and side effects.
Quick: Does __clone get called automatically on all nested objects? Commit to yes or no.
Common Belief:__clone is automatically called on all nested objects during cloning.
Tap to reveal reality
Reality:__clone is called only on the object being cloned; nested objects must be cloned manually inside __clone.
Why it matters:Not manually cloning nested objects causes shallow copies and shared state bugs.
Quick: Can __clone handle circular references without extra code? Commit to yes or no.
Common Belief:__clone automatically handles circular references safely.
Tap to reveal reality
Reality:__clone does not handle circular references automatically; developers must implement logic to avoid infinite loops.
Why it matters:Ignoring circular references can cause infinite recursion and crash the program.
Expert Zone
1
When cloning objects with resources (like database connections), __clone should avoid copying or should reset those resources to prevent errors.
2
Using __clone to implement deep copy requires careful management of object identity to avoid duplicating shared dependencies unnecessarily.
3
In PHP 8+, cloning objects with readonly properties requires special attention because readonly properties cannot be changed after construction.
When NOT to use
Avoid using __clone when objects manage external resources or connections that cannot be duplicated safely. Instead, use factory methods or explicit constructors to create new instances. Also, for immutable objects, cloning is often unnecessary and can be replaced by creating new instances with desired values.
Production Patterns
In production, __clone is often used in caching systems to duplicate objects before modification, in Prototype pattern implementations for flexible object creation, and in ORM systems to copy entity objects safely. Developers also use __clone to reset internal state or detach objects from shared references.
Connections
Prototype Design Pattern
__clone is the PHP mechanism that enables the Prototype pattern by allowing object cloning.
Understanding __clone clarifies how Prototype pattern creates new objects by copying existing ones instead of building from scratch.
Deep Copy vs Shallow Copy
__clone lets you implement deep copy manually, while default cloning is shallow copy.
Knowing the difference between shallow and deep copy helps avoid bugs with shared mutable objects.
Copy Constructors in C++
Both __clone in PHP and copy constructors in C++ serve to customize how objects are copied.
Seeing __clone as PHP’s version of copy constructors helps understand object copying across languages.
Common Pitfalls
#1Assuming clone copies nested objects automatically.
Wrong approach:class Outer { public $inner; } $outer1 = new Outer(); $outer1->inner = new stdClass(); $outer2 = clone $outer1; $outer2->inner->value = 5; echo $outer1->inner->value; // expects null but outputs 5
Correct approach:class Outer { public $inner; public function __clone() { $this->inner = clone $this->inner; } } $outer1 = new Outer(); $outer1->inner = new stdClass(); $outer2 = clone $outer1; $outer2->inner->value = 5; echo $outer1->inner->value; // outputs null as expected
Root cause:Misunderstanding that clone does shallow copy by default and nested objects remain shared.
#2Using assignment instead of clone to copy objects.
Wrong approach:$a = new stdClass(); $a->value = 1; $b = $a; $b->value = 2; echo $a->value; // outputs 2 unexpectedly
Correct approach:$a = new stdClass(); $a->value = 1; $b = clone $a; $b->value = 2; echo $a->value; // outputs 1 as expected
Root cause:Confusing assignment (reference copy) with cloning (object copy).
#3Not handling circular references in __clone.
Wrong approach:class Node { public $child; public function __clone() { $this->child = clone $this->child; } } $node1 = new Node(); $node2 = new Node(); $node1->child = $node2; $node2->child = $node1; $copy = clone $node1; // causes infinite recursion
Correct approach:class Node { public $child; private static $cloning = []; public function __clone() { if (in_array($this, self::$cloning, true)) { return; } self::$cloning[] = $this; if ($this->child) { $this->child = clone $this->child; } } } // Use careful cloning logic to avoid infinite loops
Root cause:Ignoring circular references causes infinite recursion during cloning.
Key Takeaways
In PHP, the clone keyword creates a shallow copy of an object, copying its properties but not nested objects.
The __clone method lets you customize cloning behavior, especially to deep copy nested objects for full independence.
Without __clone, cloning objects with inner objects leads to shared references and unexpected side effects.
Assignment copies object references, not objects themselves, so clone must be used to duplicate objects.
Handling complex object graphs with circular references requires careful __clone implementations to avoid infinite loops.

Practice

(1/5)
1. What does the __clone method do in PHP when you use the clone keyword on an object?
easy
A. It runs automatically to customize the copying process of the object.
B. It deletes the original object after cloning.
C. It converts the object into a string.
D. It prevents the object from being cloned.

Solution

  1. Step 1: Understand the clone keyword behavior

    When you clone an object in PHP, the __clone method runs automatically if it exists.
  2. Step 2: Purpose of __clone method

    The __clone method lets you customize how the object is copied, for example, copying inner objects or resetting properties.
  3. Final Answer:

    It runs automatically to customize the copying process of the object. -> Option A
  4. Quick Check:

    __clone customizes cloning = A [OK]
Hint: Remember: __clone runs automatically on cloning [OK]
Common Mistakes:
  • Thinking __clone deletes the original object
  • Confusing __clone with __toString
  • Believing cloning is prevented by __clone
2. Which of the following is the correct syntax to define a __clone method inside a PHP class?
easy
A. public function clone() {}
B. function __copy() {}
C. public function __clone() {}
D. private function cloneObject() {}

Solution

  1. Step 1: Identify the magic method syntax

    PHP magic methods start with double underscores, so __clone is the correct method name.
  2. Step 2: Confirm method declaration

    The method must be declared as public function __clone() to be called automatically on cloning.
  3. Final Answer:

    public function __clone() {} -> Option C
  4. Quick Check:

    Magic method __clone syntax = B [OK]
Hint: Magic methods start with double underscores __ [OK]
Common Mistakes:
  • Using single underscore or wrong method name
  • Making __clone private or protected
  • Confusing __clone with __copy
3. What will be the output of this PHP code?
class Box {
  public $size;
  public function __clone() {
    $this->size = $this->size * 2;
  }
}

$box1 = new Box();
$box1->size = 5;
$box2 = clone $box1;
echo $box2->size;
medium
A. 5
B. 10
C. 0
D. Error

Solution

  1. Step 1: Understand cloning and __clone method

    When $box1 is cloned to $box2, the __clone method runs and doubles the size property.
  2. Step 2: Calculate the new size value

    Original size is 5, after cloning size becomes 5 * 2 = 10.
  3. Final Answer:

    10 -> Option B
  4. Quick Check:

    size doubled on clone = 10 [OK]
Hint: Check __clone changes after cloning [OK]
Common Mistakes:
  • Assuming size stays same after cloning
  • Forgetting __clone runs automatically
  • Expecting syntax or runtime error
4. Consider this PHP code snippet:
class Item {
  public $value;
  public function __clone() {
    $this->value = $this->value + 1;
  }
}

$item1 = new Item();
$item1->value = 10;
$item2 = $item1;
$item3 = clone $item1;
echo $item2->value . ',' . $item3->value;

What is the output and why?
medium
A. 10,11
B. 11,11
C. 10,10
D. Error

Solution

  1. Step 1: Understand assignment vs cloning

    $item2 = $item1 assigns the same object reference, no cloning happens, so value stays 10.
  2. Step 2: Cloning triggers __clone method

    $item3 = clone $item1 creates a new object and runs __clone, increasing value by 1 to 11.
  3. Final Answer:

    10,11 -> Option A
  4. Quick Check:

    Assignment no change, clone adds 1 = 10,11 [OK]
Hint: Assignment copies reference; clone calls __clone [OK]
Common Mistakes:
  • Thinking assignment clones the object
  • Expecting both values to change
  • Confusing output order
5. You have a PHP class Person with a property address which is an object of class Address. You want to clone a Person object so that the address object is also cloned (deep copy), not just referenced. How should you implement the __clone method in Person?
hard
A. No need to implement __clone; cloning copies all properties deeply by default.
B. public function __clone() { $this->address = $this->address; }
C. public function __clone() { unset($this->address); }
D. public function __clone() { $this->address = clone $this->address; }

Solution

  1. Step 1: Understand shallow vs deep copy

    By default, cloning copies object properties shallowly, so inner objects remain shared references.
  2. Step 2: Implement deep copy in __clone

    To clone the inner address object, you must explicitly clone it inside __clone method.
  3. Final Answer:

    public function __clone() { $this->address = clone $this->address; } -> Option D
  4. Quick Check:

    Deep copy inner objects by cloning them in __clone [OK]
Hint: Clone inner objects inside __clone for deep copy [OK]
Common Mistakes:
  • Assuming clone copies inner objects automatically
  • Assigning inner object without cloning
  • Removing inner object instead of cloning
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard