Копирование объектов в PHP

В PHP объект — не просто переменная. Когда вы присваиваете объект другой переменной, обе ссылаются на один и тот же экземпляр в памяти. Изменение одной переменной затронет вторую. Чтобы получить действительно независимую копию объекта, существует оператор clone.

 

Присваивание ≠ копирование

Сначала разберём распространённую ошибку. Многие думают, что присваивание объекта новой переменной создаёт копию. На самом деле обе переменные указывают на один и тот же объект:

class Config

{

    public function __construct(public string $env = 'production') {}

}

 

$original = new Config();

$copy     = $original; // это НЕ копия — это та же ссылка

$copy->env = 'testing';

echo $original->env; // testing — оригинал тоже изменился!

echo $copy->env;     // testing

 

Оператор clone

Для создания независимой копии объекта используется оператор clone. Он создаёт новый объект и копирует в него все свойства оригинала. После этого изменения в копии никак не затрагивают оригинал:

$original = new Config('production');

$copy     = clone $original; // настоящая независимая копия

 

$copy->env = 'testing';

echo $original->env; // production — оригинал не изменился

echo $copy->env;     // testing

clone выполняет поверхностное копирование: скалярные свойства (строки, числа, булевы) копируются по значению, а вложенные объекты — по ссылке. Оба объекта будут разделять один и тот же вложенный объект.

 

Глубокое копирование через __clone()

Чтобы вложенные объекты тоже копировались независимо, используют магический метод __clone(). Он вызывается автоматически сразу после того, как clone создал поверхностную копию, и позволяет вручную клонировать вложенные объекты:

class Article

{

    public function __construct(

        public string $title,

        public Author $author

    ) {}

 

    // Вызывается автоматически при clone

    public function __clone(): void

    {

        // Клонируем вложенный объект вручную

        $this->author = clone $this->author;

    }

}

 

$original = new Article('PHP 8', new Author('Иван'));

$copy     = clone $original;

$copy->author->name = 'Мария';

echo $original->author->name; // Иван  — теперь не изменился

echo $copy->author->name;     // Мария — независимая копия

 

Копирование объектов — важная тема, которую легко упустить из виду. Простое присваивание через = не создаёт копию — оно копирует ссылку. Оператор clone создаёт новый независимый объект, но копирует вложенные объекты по ссылке. Для полной независимости используйте магический метод __clone(), в котором вручную клонируете все вложенные объекты.

Logo

Spartacus_85 [Admin]

Администратор сайта — это специалист, который отвечает за техническую поддержку и бесперебойную работу веб-ресурса.



0 Комментарий(я)

Зарегистрируйтесь чтобы оставить комментарий