Existe-t-il une fonction pour faire une copie d'un tableau PHP vers un autre?
J'ai été brûlé plusieurs fois en essayant de copier des tableaux PHP. Je veux copier un tableau défini à l'intérieur d'un objet vers un global à l'extérieur.
Existe-t-il une fonction pour faire une copie d'un tableau PHP vers un autre?
J'ai été brûlé plusieurs fois en essayant de copier des tableaux PHP. Je veux copier un tableau défini à l'intérieur d'un objet vers un global à l'extérieur.
Réponses:
En PHP, les tableaux sont attribués par copie, tandis que les objets sont attribués par référence. Cela signifie que:
$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);
Donnera:
array(0) {
}
Tandis que:
$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);
Rendements:
object(stdClass)#1 (1) {
["foo"]=>
int(42)
}
Vous pourriez être confus par des subtilités telles que ArrayObject
, qui est un objet qui agit exactement comme un tableau. Cependant, étant un objet, il a une sémantique de référence.
Edit: @AndrewLarsson soulève un point dans les commentaires ci-dessous. PHP a une fonctionnalité spéciale appelée "références". Ils sont quelque peu similaires aux pointeurs dans des langages comme C / C ++, mais pas tout à fait les mêmes. Si votre tableau contient des références, alors que le tableau lui-même est transmis par copie, les références seront toujours résolues vers la cible d'origine. C'est bien sûr généralement le comportement souhaité, mais j'ai pensé qu'il valait la peine d'être mentionné.
$copy = $original;
. Ce qui ne fonctionne pas si les éléments du tableau sont des références.
php
nous présente le résultat le moins attendu , car cette solution ne fonctionne pas toujours . $a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
imprime array0
pendant les $a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
impressions array1
. Apparemment, certains tableaux sont copiés par référence.
PHP copiera le tableau par défaut. Les références en PHP doivent être explicites.
$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a
Si vous avez un tableau qui contient des objets, vous devez faire une copie de ce tableau sans toucher son pointeur interne, et vous avez besoin de tous les objets à cloner (afin de ne pas modifier les originaux lorsque vous apportez des modifications au copié tableau), utilisez-le.
L'astuce pour ne pas toucher le pointeur interne du tableau est de vous assurer que vous travaillez avec une copie du tableau, et non avec le tableau d'origine (ou une référence à celui-ci), donc l'utilisation d'un paramètre de fonction fera le travail (donc, c'est une fonction qui prend un tableau).
Notez que vous devrez toujours implémenter __clone () sur vos objets si vous souhaitez que leurs propriétés soient également clonées.
Cette fonction fonctionne pour tout type de tableau (y compris les types mixtes).
function array_clone($array) {
return array_map(function($element) {
return ((is_array($element))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
__FUNCTION__
est géniale.
Quand tu fais
$array_x = $array_y;
PHP copie le tableau, donc je ne sais pas comment vous vous seriez brûlé. Pour votre cas,
global $foo;
$foo = $obj->bar;
devrait bien fonctionner.
Pour être brûlé, je pense que vous auriez dû utiliser des références ou vous attendre à ce que les objets à l'intérieur des tableaux soient clonés.
array_merge()
est une fonction dans laquelle vous pouvez copier un tableau dans un autre en PHP.
$a_c = array_combine(array_keys($a), array_values($a))
.
simple et rend la copie profonde brisant tous les liens
$new=unserialize(serialize($old));
J'aime array_replace
(ou array_replace_recursive
).
$cloned = array_replace([], $YOUR_ARRAY);
Cela fonctionne comme à Object.assign
partir 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';
aura pour résultat
// 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)
ou quand vous ne vous souciez pas des clés array_values($arr)
,? Je pense qu'ils pourraient être plus rapides que de rechercher dans un tableau. En outre, en javascript, il est très populaire d'utiliser Array.slice()
pour cloner des tableaux.
array_slice
et toutes les autres méthodes mentionnées ici fonctionnent très bien. Mais si vous souhaitez fusionner plusieurs paires clé-valeur (comme cela est également possible avec JS-Objects via Object.assign
ou la syntaxe étalée ), cela array_replace
peut être plus utile.
array_values()
qui a parfaitement fonctionné pour mon cas d'utilisation.
Si vous n'avez que des types de base dans votre tableau, vous pouvez le faire:
$copy = json_decode( json_encode($array), true);
Vous n'aurez pas besoin de mettre à jour les références manuellement
Je sais que cela ne fonctionnera pas pour tout le monde, mais cela a fonctionné pour moi
Comme cela n'a été couvert dans aucune des réponses et est maintenant disponible en PHP 5.3 (en supposant que Original Post utilisait 5.2).
Afin de maintenir une structure de tableau et de changer ses valeurs, je préfère utiliser array_replace
ou en array_replace_recursive
fonction de mon cas d'utilisation.
http://php.net/manual/en/function.array-replace.php
Voici un exemple d'utilisation array_replace
et de array_replace_recursive
démonstration de sa capacité à maintenir l'ordre indexé et à supprimer une référence.
Le code ci-dessous est écrit en utilisant la syntaxe de tableau court disponible depuis PHP 5.4 qui remplace array()
par []
.
http://php.net/manual/en/language.types.array.php
Fonctionne sur les tableaux indexés et indexés par nom
$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);
Production:
["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"
}
Je le sais depuis longtemps, mais cela a fonctionné pour moi ..
$copied_array = array_slice($original_array,0,count($original_array));
Voici comment je copie mes tableaux 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);
Cela produit:
Array
(
[0] => aa
[1] => bb
[2] => 3
)
$test2 = $test;
? Quel problème ArrayObject
résout ici?
Crée une copie de l'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);
?>
depuis https://www.php.net/manual/en/arrayobject.getarraycopy.php
Définissez ceci:
$copy = create_function('$a', 'return $a;');
Copiez $ _ARRAY dans $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
Dans le tableau php, vous devez simplement les affecter à une autre variable pour obtenir une copie de ce tableau. Mais vous devez d'abord vous assurer de son type, qu'il s'agisse de array, arrayObject ou stdObject.
Pour un tableau 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;
}
}