Что это такое
Паттерн Прототип создаёт новые объекты путём клонирования уже существующего, а не сборки с нуля. Вы готовите один объект как шаблон, затем копируете его ключевым словом PHP clone и меняете только то, что отличается.
Главное, что нужно учесть: обычный clone копирует свойства-значения, но вложенные объекты остаются общими, а не копируются. Метод __clone() копирует их заново, и тогда клон действительно независим.
Пример: шаблон документа
Шаблон несёт те части, которые повторяются в каждом документе. clone копирует его — а __clone() заново копирует вложенный объект TagList — поэтому правка копии не затрагивает шаблон.
Клонируйте, затем меняйте отличия
Отчёт получил новый заголовок и дополнительный тег, а в шаблоне по-прежнему только [draft] — потому что __clone() скопировал список тегов, а не сделал его общим.
Вывод: PHP-скрипт
<?php
class TagList {
public function __construct(public array $tags) {}
public function add(string $tag): void {
$this->tags[] = $tag;
}
public function show(): string {
return "[" . implode(" ", $this->tags) . "]";
}
}
class Document {
public function __construct(
public string $title,
public string $footer,
public TagList $tags,
) {}
// Обычное клонирование РАЗДЕЛЯЛО бы объект TagList — копируем его здесь заново.
public function __clone(): void {
$this->tags = clone $this->tags;
}
}
$template = new Document("Untitled", "PromptCookbook 2026", new TagList(["draft"]));
$report = clone $template;
$report->title = "Yearly Report";
$report->tags->add("finance");
echo "шаблон: ", $template->title, " ", $template->tags->show(), "\n";
echo "копия: ", $report->title, " ", $report->tags->show(), "\n";
Когда использовать
Используйте, когда новые объекты в основном представляют собой копии заранее подготовленного — документы из шаблона, игровые сущности из спаунера, тестовые данные из фикстуры.
Не используйте, когда объекты дёшево создать заново или когда в них нет ничего общего. Для объекта из простых значений — строк, чисел, массивов — обычный clone в PHP уже даёт полную копию, и __clone() не нужен.
Плюсы и минусы
Плюсы: дешёвое создание предварительно настроенных объектов; шаблон документирует значения по умолчанию; никакого повторяющегося кода настройки.
Минусы: в глубоком копировании легко допустить незаметную ошибку — забытое свойство-объект тихо связывает клон и оригинал; со временем клоны незаметно расходятся с шаблоном.