В 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(), в котором вручную клонируете все вложенные объекты.
0 Комментарий(я)
Зарегистрируйтесь чтобы оставить комментарий