Question autour de l'unset - Version imprimable +- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org) +-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38) +--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51) +--- Sujet : Question autour de l'unset (/showthread.php?tid=4101) Pages :
1
2
|
Question autour de l'unset - Ter Rowan - 17-06-2009 coucou voilà, je me pose peut être un problème qui n en est pas un mais paranoia d'un ancien développeur C oblige, je me pose des questions sur le comportement d'unset dans des cas un peu plus lourd que la simple variable pour éviter x requêtes unitaires, je charge dans plusieurs tableaux des "objets" de l'inventaire d'une liste de personnages. Chaque tableau correspond à un type d'accès particulier ( qu'y a t il dans ce sac ? quels sont les objets de ce type ?) que j'utilise grâce à des "foreach" (pour obtenir la liste suivant des filtres) et des "isset" (est ce que l'objet existe) Code PHP :
je crée donc pour un enregistrement en base un objet (new Obj) que j'attribue à deux ou trois tableaux tout cela c'est très bien mais je développe les fonctions de suppression et là quelques inquiétudes, soucis, questions autant je construis sans problème la requête SQL qui nettoie en base, autant j'aimerais avoir un nettoyage "élégant" de mes tableaux prenons le cas de la suppression d'un personnage. Le personnage est identifié par $res['obj_ext_poss_id'] ce que j'aimerais faire c'est, par exemple un Code PHP :
- à savoir toutes les cas de $this->_byType[ $res['obj_ext_poss_id'] ], mais ça je pense que oui - mais aussi les objets "obj" associés (et là je ne sais pas trop) - mais aussi l'ensemble des cases du tableau $this->_possessionsId[$res['obj_id']] qui correspondent à des objets de ce propriétaire - etc... là je suis dans le cas d'un personnage complet mais j'aimerais aussi pouvoir supprimer toutes les possessions d'un personnage d'un certain type (unset($this->_byType[ $res['obj_ext_poss_id'] ][$res['obj_ext_type_id']) ou supprimer toutes les possessions d'un personnage contenu dans un sac (unset($this->_byBag[ $res['obj_ext_poss_id'] ][ $res['obj_ext_conteneur_id' ] ]) voyez ce que je veut dire ? cela marche peut être complètement, naturellement mais j'ai un doute. je serais en C je bouclerais sur tous les éléments unitaires du plus fin au plus gros, pour tout nettoyer, mais en php est ce utile ou arrive t il à se débrouiller ? merci de votre aide RE: [php] question autour de l'unset - Allwise - 17-06-2009 Quand tu instancies ton objet Obj et que tu assignes son instance à tes diverses variables, le hic avec unset, naholyr en parlait d'ailleurs dans un autre topic, c'est que quand tu vas faire unset($tableau['xxx']['xxx']), ça va juste couper le lien entre $tableau['xxx']['xxx'] et l'objet, mais l'objet existera toujours en mémoire, probablement du fait qu'il existe d'autres références qui pointent dessus, et donc les autres variables auxquelles l'instance est liée ne bougeront pas. Ce que tu peux faire, c'est assigner ton instance d'Obj à une variable : Code PHP :
Et passer la référence de $var à tes tableaux & co : Code PHP :
En creusant dans cette piste, tu peux sûrement arriver à tes fins. RE: [php] question autour de l'unset - Ter Rowan - 17-06-2009 merci allwise, je vais regarder cela, mais , finalement ça revient à faire "à la main" le nettoyage complet, comme je le craignais ^^ juste un point, tu as peut être détecté une cagade dans ce que j'ai fait : en effet, je n'ai pas mis de & dans mes égalités $this->_byType = $this->_byBag et pas $this->_byType = &$this->_byBag est à dire que j'ai des clônes de mes objets ? RE: [php] question autour de l'unset - wild-D - 17-06-2009 théoriquement PHP est sensé garder la trace des références pointant sur ton objet et quand y en a plus il fait le nettoyage tout seul... quand il considère que c'est pertinent. (je connais pas les détail du garbage collecting de php ) unset() donc normalement ne force pas la libération de la mémoire, mais la référence, le garbage collecting devant se charger du reste (pour forcer à libérer la place immédiatement $var = null). Et comme naholyr l'a dit, y a des soucis avec des références croisées ou d'autre montage, apparemment y a des référence qui sont pas correctement effacée. RE: [php] question autour de l'unset - Allwise - 17-06-2009 Non, y a pas une copie du contenu cible en mémoire, y a toujours qu'un seul contenu en mémoire et plusieurs liens ( les variables ). Quand tu fais $this->_byType = &$this->_byBag, _byType va pointer sur _byBag. C'est à dire que si tu modifies _byBag, _byType sera également modifié. Si tu omets le &, _byType sera égal à _byBag, c'est à dire qu'ils pointeront tous deux vers la même adresse mémoire, et que si tu modifies _byBag, ça n'aura aucune incidence sur _byType. RE: [php] question autour de l'unset - naholyr - 17-06-2009 (17-06-2009, 10:26 AM)Ter Rowan a écrit : $this->_byType = $this->_byBagEn PHP5, quand la partie droite de l'affectation est un objet, c'est strictement équivalent (affectation par référence automatique). PHP ne videra jamais la mémoire tant qu'il reste une référence à un objet, quand bien même elle ne devrait plus être active. Exemple classique des références croisées : Code PHP :
Triste, mais inévitable. La bonne nouvelle étant que la mémoire est bien récupérée au niveau du système après l'exécution du script, encore heureux Note : c'est encore plus flagrant si on rajoute un destructeur dans la classe Personnage ou Inventaire (avec dedans un bête echo "quelque chose"), on se rend compte que ce destructeur n'est *jamais* appelé. Le seul moyen est d'écrire un destructeur et qu'on l'appelle manuellement. Le code suivant ne provoquera pas de fatal error : Code PHP :
Comme ça vous avez les exemples concrets sous les yeux RE: [PHP] Question autour de l'unset - wild-D - 17-06-2009 Citation :En PHP5, quand la partie droite de l'affectation est un objet, c'est strictement équivalent (affectation par référence automatique).aie non, y a une subtile différence... en fait une grosse (d'ailleurs ça m'a valu une sacrée prise de tête), les alias et les "référence" d'objet c'est pas du tout "strictement équivalent". $o = new objet(); $io = $o;// affectation par "référence" objet $ao = &$o; // affectation par "alias" tu peux accéder à ton objet indistinctement par $o, $io, $ao. pourtant si tu t'amuse à réaffecter $o, $io, ou $ao; va y avoir une grosse différence, $o et son alias $ao c'est "pareil"; par contre $io, tintin RE: [PHP] Question autour de l'unset - naholyr - 17-06-2009 Effectivement, ça valait le coup d'être précisé j'ai commis une erreur qu'en plus je connaissais (d'autant plus impardonnable) RE: [PHP] Question autour de l'unset - Ter Rowan - 18-06-2009 ok en cas de réaffectation, mais en cas de suppression c'est le même combat ? $o = new objet() $io = $o $ao = &$o puis unset ($io); qu'est ce qu'il y a dans $o ? null ? l'objet ? et si je fais unset ($ao), il se passe quoi pour $o ? tu me diras je pourrais tester mais au boulot je n'ai pas php ^^ en tout cas merci de votre aide RE: [PHP] Question autour de l'unset - wild-D - 18-06-2009 y se passe rien $o reste indeme ton bel objet. -> unset ($io); tu unset "l'accesseur" (je suis pas sûr du terme exacte) $io enfin la réf objet; non l'objet lui-même. -> unset($ao); ben j'avais mis de gros guillement à mon pareil; parce que si tu réaffecte l'alas sur une autre variable ou tu unset l'alias; tu casse en fait le lien entre entre l'alias et la variable au lieu d'agir sur la variable. dans le genre tordu encore; -je viens de vérifier - si tu unset($o); $ao et $io, t'as pas de soucis ils te donnent toujours accès à l'objet. |