php copie d'éléments de tableau par valeur et non par référence
J'ai le code suivant:
$data['x'] = $this->x->getResults();
$data['y'] = $data['x'];
//some code here to modify $data['y']
//this causes (undesirably) $data['x] to be modified as well
Je suppose que puisque tous les éléments de $données sont elles-mêmes références, la modification de $data['y'] modifie également $data['x']..ce qui n'est PAS ce que je veux. Je veux $data['x'] reste le même. Est-il possible de les déréférencer les éléments ici afin que je puisse copier les éléments en valeur?
Grâce.
Mise à jour: $this->x>getResults(); retourne un tableau d'objets. Donc, je peux alors faire quelque chose comme: $data['x'][0]->date_create ...
Mise à jour:
ma dernière tentative de cloner le tableau ressemble à quelque chose comme ceci:
$data['x'] = $this->x->getResults();
$data['y'] = $data['y'];
foreach($data['x'] as $key=>$row) {
$data['y'][$key]->some_attr = clone $row->some_attr;
}
Suis-je loin d'ici? Je reçois un "__clone méthode appelée sur le non-objet" d'erreur. En lisant les réponses, il semble que ma meilleure option est de faire une itération sur chaque élément et de le cloner (qui est ce que j'essayais de faire avec ce code..).
Mise à JOUR: vient d'être résolu!: à l'intérieur de la boucle foreach j'ai juste besoin de changer la ligne:
$data['y'][$key] = clone $row;
Et ça marche!!! Merci à tous pour l'aide.
$this->x->getResults()
retour? Un objet?Il serait important de savoir ce que
$this->x->getResults()
est de retour...oui, j'utilise codeigniter c'est donc un appel à un modèle (x) qui retourne un tableau d'objets de la base de données de résultats de la requête
Ensuite, vous devez cloner chaque objet du tableau d'objets.
Lors de l'écriture de vos propres classes, variable interne références ne sont pas clonés par défaut. Vous devez mettre en œuvre le clone de la fonction, par exemple:
public function __clone() { $this->widget = clone $this->widget(); }
pour chaque référence à l'intérieur de votre objet qui doit être cloné.OriginalL'auteur oym | 2009-07-27
Vous devez vous connecter pour publier un commentaire.
Vous pouvez profiter du fait que PHP peut déréférencer les résultats d'un appel de fonction.
Voici un exemple de code que j'ai fouetté jusqu':
Les résultats ressemblent à ceci:
Vous pouvez voir que les résultats de l'utilisation
array_flip()
au cours de la mission de$arr
à$arr2
donne lieu à des différences dans la suite de modifications apportées à$arr2
, comme learray_flip()
appelle les forces d'un déréférencement.Il ne semble pas terriblement efficace, mais il peut travailler pour vous si
$this->x->getResults()
est de retourner un tableau:Voir c' (sans réponse) thread pour un autre exemple.
Si tout dans votre tableau retourné est un objet cependant, alors le seul moyen pour copier un objet à l'aide de
clone()
, et vous devez parcourir$data['x']
et clone chaque élément dans$data['y']
.Exemple:
sympa de me battre pour elle! merci pour votre aide!
Pas de problème, j'ai ajouté un exemple.
clone
ne fonctionne que sur les objets réels, de sorte que si le résultat de retour de$this->x->getResults();
est un tableau d'objets au lieu d'un objet, alors vous ne pouvez pas cloner le tableau, vous devez cloner chaque élément de la matrice séparément.array_flip
n'est pas une bonne idée!!!!! Si vous avez 2 clés avec la même valeur alors la première clé est perdue lorsque learray_flip
fonction est appelée.un peu de mal d'informations ici. le retour de la fonction ne pas faire une profonde déférence. la magie au-dessus est le
array_flip(array_flip($array))
..OriginalL'auteur zombat
array_flip()
ne fonctionne pas lorsque la matrice de valeurs ne sont pas des chaînes, ni les nombres entiers.J'ai trouvé une solution simple, cependant:
Cela fonctionne grâce aux propriétés de clone sur un objet.
Cela ne fonctionne pas. Si
$arr
a les variables de référence, la nouvelle matrice qui les ont toujours. Références survivre clonage.OriginalL'auteur Jérôme Schneider
Pas simple.
Lisez à propos de clone
MAIS! si vos éléments sont pas des objets et pas de référence des variables de type vous n'avez pas de problème.
Exemple pour les types référence:
En PHP, (à partir de la version 5 IICRC) tous les objets sont passés par référence par défaut.
Cette réponse n'est pas tout à fait vrai. Il faut lire "Si vos éléments ne sont pas des références, vous n'avez pas de problème.". Vous pouvez avoir des références qui ne sont pas des objets.
Merci, édité répondre en conséquence
Les objets ne sont pas des références, ils sont techniquement des pointeurs, mais ils semblent agir comme des références.
OriginalL'auteur Itay Moav -Malimovka
Si vous travaillez avec des objets, vous voudrez peut-être jeter un oeil à
clone
, pour créer un copie d'un objet, au lieu d'un référence.Voici un très court exemple :
D'abord, avec un tableau, il fonctionne en valeur :
Par défaut, avec des objets, des œuvres de référence :
Mais, si vous le clone de l'objet, de travailler sur une copie :
Je suppose que c'est votre cas ?
Espère que cette aide,
Je n'ai aucune idée à propos de l'efficacité, mais si vous avez besoin de la fonctionnalité, il n'a pas vraiment d'importance, n'est ce pas ? (et, en considérant que vous faites de la base de données de requête juste avant, il ne devrait pas être long, en comparaison avec le reste du script 🙂 )
...bon point 🙂
Je pense que la seule inefficacité serait dû au fait que vous êtes doublement de la quantité de mémoire afin de stocker le même objet deux fois. Ainsi, il est aussi inefficace que la copie de toute autre variable serait.
OriginalL'auteur Pascal MARTIN
Vous pouvez utiliser cette fonction pour copier les tableaux multidimensionnels contenant des objets.
clone
faire une copie? Afin de ne pas répéter à toutes les propriétés de la matrice.Oui il ne sera pas. Donc je suppose que si il ya des propriétés de la matrice contenant plusieurs objets vous pouvez utiliser
__clone()
de laisser les objets eux-mêmes comprendre exactement comment ils devraient être cloné.OriginalL'auteur uKolka
Je viens de découvrir que si vous voulez simplement une copie d'un tableau de valeurs (pas de références) à partir d'une constante, alors vous pouvez simplement écrire:
$new_array = (array) (objet) self::old_array;
Pas une réponse exacte à la discussion de la question, mais elle m'a aidé et peut aider quelqu'un d'autre.
OriginalL'auteur rexthestrange