Как в PHP полностью скопировать массив в другую переменную, чтобы изменения не влияли на оригинал?
Ответ: используйте unserialize(serialize($array)) или array_map с рекурсией
Вы правы: в PHP присваивание массива создает поверхностную копию (shallow copy). Это работает для одномерных массивов, но для многомерных (с вложенными массивами или объектами) ссылки на вложенные структуры остаются общими. PHP использует механизм copy-on-write, но он применяется только к первому уровню.
Самый простой и часто используемый способ сделать полную (глубокую) копию — это сериализация и десериализация:
<?php
$original = ['name' => 'Иван', 'age' => 30, 'hobbies' => ['чтение', 'бег']];
// Глубокая копия через сериализацию
$deepCopy = unserialize(serialize($original));
// Теперь изменения в копии не влияют на оригинал
$deepCopy['hobbies'][] = 'программирование';
print_r($original['hobbies']); // ['чтение', 'бег']
print_r($deepCopy['hobbies']); // ['чтение', 'бег', 'программирование']
?>
Как это работает:
serialize()преобразует массив в строку, включая все вложенные структуры.unserialize()восстанавливает из строки новый независимый массив.
Плюсы: простота, работает для любых типов данных (массивы, объекты, строки, числа).
Минусы: медленнее для больших массивов; не работает с ресурсами (файлы, соединения БД) и некоторыми объектами (например, с закрытыми свойствами или циклическими ссылками).
Альтернатива: рекурсивная функция
Если нужна только для массивов и вы хотите избежать сериализации, напишите свою рекурсивную функцию:
<?php
function deepCopyArray($array) {
$result = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$result[$key] = deepCopyArray($value); // рекурсия для вложенных массивов
} else {
$result[$key] = $value;
}
}
return $result;
}
$original = ['name' => 'Иван', 'hobbies' => ['чтение', 'бег']];
$copy = deepCopyArray($original);
$copy['hobbies'][] = 'программирование';
print_r($original['hobbies']); // ['чтение', 'бег']
?>
Для объектов внутри массива нужно клонировать их через clone (если класс реализует __clone()). Но для большинства случаев с массивами достаточно serialize/unserialize.
Современный подход (PHP 7.4+):
Можно использовать array_map с рекурсивной анонимной функцией, но это менее читаемо. Лучше придерживаться первых двух вариантов.
Итог: для быстрой глубокой копии массива используйте unserialize(serialize($array)). Если массив очень большой или содержит ресурсы — напишите свою рекурсивную функцию.
Дополнение: используйте json_decode(json_encode($array), true)
Еще один популярный способ — конвертировать массив в JSON и обратно. Это тоже создает глубокую копию, но с ограничениями: все данные должны быть сериализуемы в JSON (строки, числа, булевы значения, массивы). Объекты и ресурсы не поддерживаются.
<?php
$original = ['name' => 'Иван', 'hobbies' => ['чтение', 'бег']];
$deepCopy = json_decode(json_encode($original), true);
$deepCopy['hobbies'][] = 'программирование';
print_r($original['hobbies']); // ['чтение', 'бег']
?>
Плюсы: быстрее сериализации для простых данных; читаемый код.
Минусы: теряет типы (например, целые числа могут стать строками, если они в ключах); не работает с объектами.
Когда использовать: если массив содержит только скалярные значения и вложенные массивы (например, конфигурации, JSON-данные). Для общих случаев лучше serialize/unserialize.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Работа с базами данных в PHP: PostgreSQL и MongoDB