__clone & Object Cloning
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 48 of 91.
When you assign one object to another variable in PHP, you don't create a copy - both variables point to the same object. To create an actual independent copy, you need to use the clone keyword:
<?php
class Product {
public function __construct(
public string $name,
public float $price
) {}
}
$original = new Product("Laptop", 999.99);
$copy = clone $original;
$copy->price = 899.99;
echo $original->price . " - " . $copy->price;
Output:
999.99 - 899.99By default, PHP performs a shallow copy - it copies all property values directly. This works fine for scalar values, but objects inside your object still reference the same instance. The __clone() magic method lets you customize this behavior:
<?php
class Order {
public function __construct(
public int $id,
public array $items = []
) {}
public function __clone(): void {
$this->id = 0;
$this->items = [];
}
}
$order1 = new Order(101, ["Book", "Pen"]);
$order2 = clone $order1;
echo "Original: " . $order1->id . ", Clone: " . $order2->id;
Output:
Original: 101, Clone: 0The __clone() method is called on the new object after the shallow copy is made. This is where you reset IDs, create fresh copies of nested objects, or perform any cleanup needed for the clone to be truly independent.
Challenge
EasyLet's build a document versioning system that demonstrates how cloning creates independent copies and how the __clone() magic method lets you customize what happens when an object is cloned.
You'll organize your code across two files:
Document.php— Create aDocumentclass that represents a versioned document. Use constructor promotion to define a public$title(string), a public$content(string), and a public$version(integer, defaulting to 1). Add a private$createdAtproperty that stores the current timestamp (usedate('Y-m-d H:i:s')in the constructor). Your document needs:getCreatedAt()— returns the creation timestamp__clone()— when a document is cloned, the version should increment by 1, and the$createdAtshould be reset to the current timestamp (the clone is a new version created "now")
main.php— Include the Document file. You'll receive three inputs: a title, content, and a new content string for the cloned version. Create aDocumentwith the title and content. Then clone it to create a new version, and update the clone's content to the new content string. Print four lines:- The original document's version
- The cloned document's version
- The original document's content
- The cloned document's content
This system shows how __clone() lets you control what happens during cloning. The original document keeps its version and creation time, while the clone automatically becomes a new version with a fresh timestamp — perfect for tracking document history where each clone represents a new revision.
Cheat sheet
To create an independent copy of an object, use the clone keyword:
<?php
class Product {
public function __construct(
public string $name,
public float $price
) {}
}
$original = new Product("Laptop", 999.99);
$copy = clone $original;
$copy->price = 899.99;
echo $original->price . " - " . $copy->price;
// Output: 999.99 - 899.99
By default, PHP performs a shallow copy of all property values. To customize cloning behavior, use the __clone() magic method:
<?php
class Order {
public function __construct(
public int $id,
public array $items = []
) {}
public function __clone(): void {
$this->id = 0;
$this->items = [];
}
}
$order1 = new Order(101, ["Book", "Pen"]);
$order2 = clone $order1;
echo "Original: " . $order1->id . ", Clone: " . $order2->id;
// Output: Original: 101, Clone: 0
The __clone() method is called on the new object after the shallow copy is made, allowing you to reset properties or create independent copies of nested objects.
Try it yourself
<?php
require_once 'Document.php';
// Read inputs
$title = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
$newContent = trim(fgets(STDIN));
// TODO: Create a Document with the title and content
// TODO: Clone the document to create a new version
// TODO: Update the clone's content to the new content string
// TODO: Print four lines:
// 1. The original document's version
// 2. The cloned document's version
// 3. The original document's content
// 4. The cloned document's content
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern