0
0
PHPprogramming~15 mins

__clone for object copying in PHP - Deep Dive

Choose your learning style9 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.