W3docs

clone

Learn how the PHP clone keyword copies objects, why it makes a shallow copy, and how to use the __clone() magic method to control deep copies.

The PHP clone Keyword

In PHP, objects are handled by reference. When you assign one object variable to another with =, both variables point to the same object — change one and the other changes too. The clone keyword breaks that link: it makes a brand-new object that starts as a duplicate of an existing one, so you can modify the copy without touching the original.

This page covers the clone syntax, the difference between a shallow and a deep copy (the single biggest source of clone bugs), and the __clone() magic method that lets you control what happens during cloning.

If you are new to objects, read PHP Classes and Objects and Constructors first.

Syntax

$copy = clone $original;

clone returns a new object. The original is left untouched, and $copy is an independent instance whose properties are copied from $original.

Assignment vs. clone

This is the reason clone exists. With a plain assignment, both variables refer to one object:

<?php
class Counter
{
    public int $value = 0;
}

$a = new Counter();
$b = $a;          // same object, NOT a copy
$b->value = 10;

echo $a->value . PHP_EOL; // 10 — $a changed too

Use clone to get a genuinely separate object:

<?php
class Counter
{
    public int $value = 0;
}

$a = new Counter();
$b = clone $a;    // independent copy
$b->value = 10;

echo $a->value . PHP_EOL; // 0 — original is untouched
echo $b->value . PHP_EOL; // 10

A basic example

<?php
class Car
{
    public string $make;
    public string $model;
    public int $year;

    public function __construct(string $make, string $model, int $year)
    {
        $this->make = $make;
        $this->model = $model;
        $this->year = $year;
    }
}

$original = new Car("Ford", "Mustang", 2022);
$copy = clone $original;

$copy->make = "Chevrolet";
$copy->model = "Corvette";

echo "Original: {$original->make} {$original->model} {$original->year}" . PHP_EOL;
echo "Copy:     {$copy->make} {$copy->model} {$copy->year}" . PHP_EOL;

// Output:
// Original: Ford Mustang 2022
// Copy:     Chevrolet Corvette 2022

Changing $copy leaves $original alone, because they are two separate objects.

Shallow copy: the main gotcha

By default clone makes a shallow copy. Scalar properties (strings, ints, booleans) are copied by value, but if a property holds another object, only the reference is copied — both the original and the clone end up pointing at the same nested object.

<?php
class Engine
{
    public function __construct(public int $horsepower) {}
}

class Car
{
    public function __construct(public Engine $engine) {}
}

$original = new Car(new Engine(300));
$copy = clone $original;

// Both cars still share ONE Engine object
$copy->engine->horsepower = 500;

echo "Original engine: {$original->engine->horsepower} hp" . PHP_EOL;
echo "Copy engine:     {$copy->engine->horsepower} hp" . PHP_EOL;

// Output:
// Original engine: 500 hp
// Copy engine:     500 hp

Editing the clone's engine also changed the original's engine — almost never what you want.

Deep copy with __clone()

The __clone() magic method runs automatically on the new object right after it is duplicated. Use it to clone any nested objects so the copy gets its own independent ones (a deep copy):

<?php
class Engine
{
    public function __construct(public int $horsepower) {}
}

class Car
{
    public function __construct(public Engine $engine) {}

    public function __clone()
    {
        // Give the clone its own Engine instead of sharing the original's
        $this->engine = clone $this->engine;
    }
}

$original = new Car(new Engine(300));
$copy = clone $original;

$copy->engine->horsepower = 500;

echo "Original engine: {$original->engine->horsepower} hp" . PHP_EOL;
echo "Copy engine:     {$copy->engine->horsepower} hp" . PHP_EOL;

// Output:
// Original engine: 300 hp
// Copy engine:     500 hp

Now the two cars have separate engines, so changing one does not affect the other. __clone() is the right place for any per-copy fix-up: resetting an auto-generated ID, clearing a cached value, or deep-copying nested objects and arrays of objects.

When to use clone

  • Working copies / drafts — duplicate an object so a user can edit a copy while the original is preserved (think "Save As").
  • Prototype pattern — pre-configure one object and clone it whenever you need a new pre-set instance, instead of running an expensive constructor each time.
  • Immutability helpers — return a modified clone instead of mutating $this, a common technique in value objects and DTOs.

Reach for clone when you specifically need a second, independent object; if you only need to read the same object from two places, a plain reference is fine.

Things to remember

  • clone makes a shallow copy by default — nested objects are shared, not duplicated.
  • Define __clone() to perform a deep copy or any other per-copy adjustment.
  • __clone() runs on the new object, where $this is the clone.
  • Clone is for objects. Arrays in PHP are already copied by value on assignment, so they don't need clone.

Practice

Practice
What does the __clone() method in PHP do?
What does the __clone() method in PHP do?
Was this page helpful?