¿Hay una función para hacer una copia de una matriz PHP a otra?
Me quemé varias veces tratando de copiar matrices PHP. Quiero copiar una matriz definida dentro de un objeto a un global fuera de él.
¿Hay una función para hacer una copia de una matriz PHP a otra?
Me quemé varias veces tratando de copiar matrices PHP. Quiero copiar una matriz definida dentro de un objeto a un global fuera de él.
Respuestas:
En PHP, las matrices se asignan por copia, mientras que los objetos se asignan por referencia. Esto significa que:
$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);
Rendirá:
array(0) {
}
Mientras:
$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);
Rendimientos:
object(stdClass)#1 (1) {
["foo"]=>
int(42)
}
Podría confundirse con complejidades como ArrayObject
, que es un objeto que actúa exactamente como una matriz. Sin embargo, al ser un objeto, tiene semántica de referencia.
Editar: @AndrewLarsson plantea un punto en los comentarios a continuación. PHP tiene una característica especial llamada "referencias". Son algo similares a los punteros en lenguajes como C / C ++, pero no son lo mismo. Si su matriz contiene referencias, mientras la matriz se pasa por copia, las referencias aún se resolverán en el objetivo original. Por supuesto, ese suele ser el comportamiento deseado, pero pensé que valía la pena mencionarlo.
$copy = $original;
. Lo que no funciona si los elementos de la matriz son referencias.
php
nos presenta el resultado menos esperado , porque esta solución no siempre funciona . $a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
imprime array0
mientras $a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
imprime array1
. Aparentemente, algunas matrices se copian por referencia.
PHP copiará la matriz por defecto. Las referencias en PHP deben ser explícitas.
$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a
Si tiene una matriz que contiene objetos, debe hacer una copia de esa matriz sin tocar su puntero interno, y necesita clonar todos los objetos (para que no esté modificando los originales cuando realice cambios en la copia) matriz), use esto.
El truco para no tocar el puntero interno de la matriz es asegurarse de que está trabajando con una copia de la matriz y no con la matriz original (o una referencia a ella), por lo que usar un parámetro de función hará el trabajo (por lo tanto, Esta es una función que toma una matriz).
Tenga en cuenta que aún necesitará implementar __clone () en sus objetos si desea que sus propiedades también se clonen.
Esta función funciona para cualquier tipo de matriz (incluido el tipo mixto).
function array_clone($array) {
return array_map(function($element) {
return ((is_array($element))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
__FUNCTION__
es brillante.
Cuando tu lo hagas
$array_x = $array_y;
PHP copia la matriz, así que no estoy seguro de cómo te habrías quemado. Para su caso
global $foo;
$foo = $obj->bar;
Debería funcionar bien.
Para quemarse, creo que tendrías que haber estado usando referencias o esperando que los objetos dentro de las matrices sean clonados.
array_merge()
es una función en la que puedes copiar una matriz a otra en PHP.
$a_c = array_combine(array_keys($a), array_values($a))
.
simple y hace una copia profunda rompiendo todos los enlaces
$new=unserialize(serialize($old));
Me gusta array_replace
(o array_replace_recursive
)
$cloned = array_replace([], $YOUR_ARRAY);
Funciona como Object.assign
desde 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';
resultará en
// 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)
o cuando no te importan las llaves array_values($arr)
? Estoy pensando que podrían ser más rápidos que buscar en una matriz. Además, en javascript, es bastante popular usarlo Array.slice()
para clonar matrices.
array_slice
y todos los demás métodos mencionados aquí funcionan muy bien. Pero si desea fusionar varios pares clave-valor (como también es posible con JS-Objects vía Object.assign
o la sintaxis spread ), array_replace
puede ser más útil.
array_values()
que funcionó perfectamente para mi caso de uso.
Si solo tiene tipos básicos en su matriz, puede hacer esto:
$copy = json_decode( json_encode($array), true);
No necesitará actualizar las referencias manualmente
. Sé que no funcionará para todos, pero funcionó para mí.
Como esto no estaba cubierto en ninguna de las respuestas y ahora está disponible en PHP 5.3 (se suponía que la publicación original estaba usando 5.2).
Para mantener una estructura de matriz y cambiar sus valores, prefiero usar array_replace
o array_replace_recursive
dependiendo de mi caso de uso.
http://php.net/manual/en/function.array-replace.php
Aquí hay un ejemplo usando array_replace
y array_replace_recursive
demostrando que es capaz de mantener el orden indexado y capaz de eliminar una referencia.
El siguiente código está escrito utilizando la sintaxis de matriz corta disponible desde PHP 5.4 que reemplaza array()
con []
.
http://php.net/manual/en/language.types.array.php
Funciona en matrices indexadas indexadas o indexadas
$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);
Salida:
["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"
}
Sé esto hace mucho tiempo, pero esto funcionó para mí ...
$copied_array = array_slice($original_array,0,count($original_array));
Esta es la forma en que estoy copiando mis matrices en Php:
function equal_array($arr){
$ArrayObject = new ArrayObject($arr);
return $ArrayObject->getArrayCopy();
}
$test = array("aa","bb",3);
$test2 = equal_array($test);
print_r($test2);
Esto produce:
Array
(
[0] => aa
[1] => bb
[2] => 3
)
$test2 = $test;
? ¿Qué problema está ArrayObject
resolviendo aquí?
Crea una copia del objeto Array
<?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);
?>
de https://www.php.net/manual/en/arrayobject.getarraycopy.php
Define esto:
$copy = create_function('$a', 'return $a;');
Copie $ _ARRAY en $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
En php array, solo debe asignarlos a otra variable para obtener una copia de esa matriz. Pero primero debe asegurarse de su tipo, ya sea array o arrayObject o stdObject.
Para la matriz php simple:
$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;
}
}