Есть ли функция, чтобы сделать копию массива PHP в другой?
Я был сожжен несколько раз, пытаясь скопировать массивы PHP. Я хочу скопировать массив, определенный внутри объекта, в глобальный за его пределами.
Есть ли функция, чтобы сделать копию массива 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 ++, но не совсем так. Если ваш массив содержит ссылки, то, хотя сам массив передается копией, ссылки все равно будут преобразовываться в исходную цель. Это, конечно, обычно желаемое поведение, но я подумал, что стоит упомянуть.
$copy = $original;
. Что не работает, если элементы массива являются ссылками.
php
дарит нам наименьший ожидаемый результат , потому что это решение не всегда работает . $a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
печатает array0
пока $a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
печатает array1
. Видимо, некоторые массивы скопированы по ссылке.
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))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
__FUNCTION__
великолепно.
Когда вы делаете
$array_x = $array_y;
PHP копирует массив, поэтому я не уверен, как бы вы сгорели. Для вашего случая
global $foo;
$foo = $obj->bar;
должно работать нормально.
Для того, чтобы сгореть, я думаю, вы должны были использовать ссылки или ожидать клонирования объектов внутри массивов.
array_merge()
это функция, в которой вы можете скопировать один массив в другой в PHP.
$a_c = array_combine(array_keys($a), array_values($a))
.
простой и делает глубокое копирование, ломая все ссылки
$new=unserialize(serialize($old));
Мне нравится array_replace
(или array_replace_recursive
).
$cloned = array_replace([], $YOUR_ARRAY);
Это работает как Object.assign
из JavaScript.
$original = [ 'foo' => 'bar', 'fiz' => 'baz' ];
$cloned = array_replace([], $original);
$clonedWithReassignment = array_replace([], $original, ['foo' => 'changed']);
$clonedWithNewValues = array_replace([], $original, ['add' => 'new']);
$original['new'] = 'val';
приведет к
// original:
{"foo":"bar","fiz":"baz","new":"val"}
// cloned:
{"foo":"bar","fiz":"baz"}
// cloned with reassignment:
{"foo":"changed","fiz":"baz"}
// cloned with new values:
{"foo":"bar","fiz":"baz","add":"new"}
array_slice($arr, 0)
или когда вам нет дела до ключей array_values($arr)
? Я думаю, что они могут быть быстрее, чем поиск в массиве. Кроме того, в javascript он довольно популярен Array.slice()
для клонирования массивов.
array_slice
и всех других методов, упомянутых здесь, работают очень хорошо. Но если вы хотите объединить несколько пар ключ-значение (как это также возможно с JS-Objects через Object.assign
или с помощью синтаксиса распространения ), это array_replace
может быть более полезным.
array_values()
которое отлично сработало для моего варианта использования.
Если у вас есть только базовые типы в вашем массиве, вы можете сделать это:
$copy = json_decode( json_encode($array), true);
Вам не нужно обновлять ссылки вручную,
я знаю, что это не будет работать для всех, но у меня это сработало
Поскольку это не было охвачено ни одним из ответов и теперь доступно в PHP 5.3 (предполагается, что Original Post использовал 5.2).
Чтобы поддерживать структуру массива и изменять его значения, я предпочитаю использовать array_replace
или в 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
)
$test2 = $test;
? Какую проблему ArrayObject
здесь решаем?
Создает копию ArrayObject
<?php
// Array of available fruits
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);
$fruitsArrayObject = new ArrayObject($fruits);
$fruitsArrayObject['pears'] = 4;
// create a copy of the array
$copy = $fruitsArrayObject->getArrayCopy();
print_r($copy);
?>
с https://www.php.net/manual/en/arrayobject.getarraycopy.php
Определите это:
$copy = create_function('$a', 'return $a;');
Скопируйте $ _ARRAY в $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
В массиве 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;
}
}