tipos - recorrer un array multidimensional php
¿Existe una función para hacer una copia de una matriz de PHP a otra? (17)
Cuando tu lo hagas
$array_x = $array_y;
PHP copia la matriz, así que no estoy seguro de cómo te hubieras quemado. Para su caso,
global $foo;
$foo = $obj->bar;
debería funcionar bien
Para quemarme, creo que tendrías que haber estado usando referencias o esperando que los objetos dentro de los arreglos fueran clonados.
¿Existe una función para hacer una copia de una matriz de PHP a otra?
Me han quemado varias veces intentando copiar matrices PHP. Quiero copiar una matriz definida dentro de un objeto a un global fuera de él.
Dado que esto no se trató en ninguna de las respuestas y ahora está disponible en PHP 5.3 (se supone 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.
Aquí hay un ejemplo que usa array_replace
y array_replace_recursive
demostrando que es capaz de mantener el orden indexado y es capaz de eliminar una referencia.
El código a continuación se escribe usando la sintaxis de matriz corta disponible desde PHP 5.4 que reemplaza a array()
con []
. http://php.net/manual/en/language.types.array.php
Funciona en matrices indexadas por desplazamiento e indexadas por nombre
$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"
}
Define esto:
$copy = create_function(''$a'', ''return $a;'');
Copie $ _ARRAY a $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
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. Al ser un objeto sin embargo, tiene semántica de referencia.
Edición: @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 exactamente los mismos. Si su matriz contiene referencias, entonces mientras la matriz se pasa por copia, las referencias se resolverán al objetivo original. Por supuesto, ese es generalmente el comportamiento deseado, pero pensé que valía la pena mencionarlo.
En php array, solo necesita asignarlos a otra variable para obtener una copia de ese array. Pero primero debe asegurarse de su tipo, ya sea array o arrayObject o stdObject.
Para Simple php array:
$a = array(
''data'' => 10
);
$b = $a;
var_dump($b);
output:
array:1 [
"data" => 10
]
Esta es la forma en que estoy copiando mis arreglos 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
)
La forma más segura y barata que encontré es:
<?php
$b = array_values($a);
Esto también tiene el beneficio de reindexar la matriz.
Esto no funcionará como se espera en la matriz asociativa (hash), pero tampoco la mayoría de las respuestas anteriores.
Lo sé hace mucho tiempo, pero esto funcionó para mí ..
$copied_array = array_slice($original_array,0,count($original_array));
PHP copiará la matriz por defecto. Las referencias en PHP tienen que 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 solo tiene tipos básicos en su matriz, puede hacer esto:
$copy = json_decode( json_encode($array), true);
No necesitarás actualizar las referencias manualmente.
Sé que no funcionará para todos, pero funcionó para mí
Si tiene una matriz que contiene objetos, necesita hacer una copia de esa matriz sin tocar su puntero interno, y necesita que todos los objetos se clonen (para que no modifique los originales cuando realice cambios en la copia). array), usa 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 al utilizar un parámetro de función se realizará el trabajo (por lo tanto, esta es una función que toma en una matriz).
Tenga en cuenta que aún necesitará implementar __clone() en sus objetos si desea que sus propiedades también sean clonadas.
Esta función funciona igual de bien para cualquier tipo de matriz (incluido el tipo mixto).
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);
}
Simple y hace copia profunda rompiendo todos los enlaces.
$new=unserialize(serialize($old));
simple y limpio para PHP> = 5.3
$cloned = array_replace([], $YOUR_ARRAY);
array_replace
(o array_replace_recursive
). Para mí, la forma más limpia y como Object.assign
de 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_merge()
es una función en la que puede copiar una matriz a otra en PHP.
$arr_one_copy = array_combine(array_keys($arr_one), $arr_one);
Sólo para publicar una solución más;)
<?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;
}
?>
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;
}
}