Есть ли функция, чтобы сделать копию массива PHP другой?
Я несколько раз сжигался, пытаясь скопировать массивы PHP. Я хочу скопировать массив, определенный внутри объекта, к глобальному вне его.
В PHP массивы назначаются копией, а объекты назначаются по ссылке. Это значит, что:
$a = array(); $b = $a; $b['foo'] = 42; var_dump($a);
Будет давать:
array(0) { }
В то время как:
$a = new StdClass(); $b = $a; $b->foo = 42; var_dump($a);
Урожайность:
object(stdClass)#1 (1) { ["foo"]=> int(42) }
Вы можете запутаться в тонкостях, таких как ArrayObject
, который является объектом, который действует точно так же, как массив. Однако, будучи объектом, он имеет ссылочную семантику.
Изменить: @AndrewLarsson поднимает точку в комментариях ниже. PHP имеет специальную функцию, называемую «ссылки». Они несколько похожи на указатели на языках типа C / C ++, но не совсем одинаковы. Если ваш массив содержит ссылки, тогда, когда сам массив передается копией, ссылки будут по-прежнему разрешаться исходной цели. Это, конечно, обычно желаемое поведение, но я думал, что это стоит упомянуть.
PHP будет копировать массив по умолчанию. Ссылки на PHP должны быть явными.
$a = array(1,2); $b = $a; // $b will be a different array $c = &$a; // $c will be a reference to $a
Если у вас есть массив, содержащий объекты, вам нужно сделать копию этого массива, не касаясь его внутреннего указателя, и вам нужны все клонируемые объекты (чтобы вы не изменяли оригиналы при внесении изменений в скопированные массив), используйте это.
Трюк, чтобы не касаться внутреннего указателя массива, заключается в том, чтобы убедиться, что вы работаете с копией массива, а не с исходным массивом (или ссылкой на него), поэтому использование параметра функции выполнит задание (таким образом, это функция, которая принимает массив).
Обратите внимание, что вам все равно нужно реализовать __clone () для своих объектов, если вы хотите, чтобы их свойства также были клонированы.
Эта функция работает так же хорошо для любого типа массива (включая смешанный тип).
function array_clone($array) { return array_map(function($element) { return ((is_array($element)) ? call_user_func(__FUNCTION__, $element) : ((is_object($element)) ? clone $element : $element ) ); }, $array); }
Когда вы это сделаете
$array_x = $array_y;
PHP копирует массив, поэтому я не уверен, как вы сожгли бы вас. Для вашего случая,
global $foo; $foo = $obj->bar;
должен работать нормально.
Чтобы сгореть, я думаю, вам придется либо использовать ссылки, либо ожидать, что объекты внутри массивов будут клонированы.
array_merge()
– это функция, в которой вы можете скопировать один массив в другой в PHP.
Если в вашем массиве есть только базовые типы, вы можете сделать это:
$copy = json_decode( json_encode($array), true);
Вам не нужно обновлять ссылки вручную
Я знаю, что это не сработает для всех, но это сработало для меня
простой и делает глубокую копию всех ссылок
$new=unserialize(serialize($old));
Поскольку это не было затронуто ни в одном из ответов и теперь доступно в PHP 5.3 (предполагается, что Original Post использует 5.2).
Чтобы поддерживать структуру массива и изменять его значения, я предпочитаю использовать array_replace
или array_replace_recursive
зависимости от моего array_replace_recursive
использования.
http://php.net/manual/en/function.array-replace.php
Вот пример использования array_replace
и array_replace_recursive
демонстрирующий, что он способен поддерживать индексированный порядок и способен удалить ссылку.
Код ниже написан с использованием синтаксиса короткого массива, доступного с PHP 5.4, который заменяет array()
на []
. http://php.net/manual/en/language.types.array.php
Работает как с индексированными, так и с индексированными массивами имен
$o1 = new stdClass; $a = 'd'; //This is the base array or the initial structure $o1->ar1 = ['a', 'b', ['ca', 'cb']]; $o1->ar1[3] = & $a; //set 3rd offset to reference $a //direct copy (not passed by reference) $o1->ar2 = $o1->ar1; //alternatively array_replace($o1->ar1, []); $o1->ar1[0] = 'z'; //set offset 0 of ar1 = z do not change ar2 $o1->ar1[3] = 'e'; //$a = e (changes value of 3rd offset to e in ar1 and ar2) //copy and remove reference to 3rd offset of ar1 and change 2nd offset to a new array $o1->ar3 = array_replace($o1->ar1, [2 => ['aa'], 3 => 'd']); //maintain original array of the 2nd offset in ar1 and change the value at offset 0 //also remove reference of the 2nd offset //note: offset 3 and 2 are transposed $o1->ar4 = array_replace_recursive($o1->ar1, [3 => 'f', 2 => ['bb']]); var_dump($o1);
Вывод:
["ar1"]=> array(4) { [0]=> string(1) "z" [1]=> string(1) "b" [2]=> array(2) { [0]=> string(2) "ca" [1]=> string(2) "cb" } [3]=> &string(1) "e" } ["ar2"]=> array(4) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> array(2) { [0]=> string(2) "ca" [1]=> string(2) "cb" } [3]=> &string(1) "e" } ["ar3"]=> array(4) { [0]=> string(1) "z" [1]=> string(1) "b" [2]=> array(1) { [0]=> string(2) "aa" } [3]=> string(1) "d" } ["ar4"]=> array(4) { [0]=> string(1) "z" [1]=> string(1) "b" [2]=> array(2) { [0]=> string(2) "bb" [1]=> string(2) "cb" } [3]=> string(1) "f" }
Я знаю это давно, но это сработало для меня.
$copied_array = array_slice($original_array,0,count($original_array));
Так я копирую свои массивы в Php:
function equal_array($arr){ $ArrayObject = new ArrayObject($arr); return $ArrayObject->getArrayCopy(); } $test = array("aa","bb",3); $test2 = equal_array($test); print_r($test2);
Эти результаты:
Array ( [0] => aa [1] => bb [2] => 3 )
Определите это:
$copy = create_function('$a', 'return $a;');
Скопируйте $ _ARRAY в $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
Самый безопасный и дешевый способ, который я нашел, это:
<?php $b = array_values($a);
Это также имеет преимущество для переопределения массива.
Это не будет работать так, как ожидалось, в ассоциативном массиве (хеш), но не каждый из предыдущих ответов.
В php-массиве вам нужно просто назначить их другой переменной, чтобы получить копию этого массива. Но сначала вам нужно убедиться в его типе, будь то массив или arrayObject или stdObject.
Для простого массива php:
$a = array( 'data' => 10 ); $b = $a; var_dump($b); output: array:1 [ "data" => 10 ]
private function cloneObject($mixed) { switch (true) { case is_object($mixed): return clone $mixed; case is_array($mixed): return array_map(array($this, __FUNCTION__), $mixed); default: return $mixed; } }
<?php function arrayCopy( array $array ) { $result = array(); foreach( $array as $key => $val ) { if( is_array( $val ) ) { $result[$key] = arrayCopy( $val ); } elseif ( is_object( $val ) ) { $result[$key] = clone $val; } else { $result[$key] = $val; } } return $result; } ?>