|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Bonjour à tous, j'espère tout d'abord poster au bon endroit ;
J'ai bien utilisé la fonction de recherche avant, et trouvé une question presque similaire à la mienne, mais le résultat ne me convenait pas (requête dans une boucle, berk.) Voilà mon soucis : J'extrais d'une base les informations sur des forums (ID, titre, etc.). Chaque forum possède un champ 'parent_forum_id', qui peut avoir une valeur NULL. Si NULL, alors le forum est en première ligne, sans parent. Sinon, c'est le sous-forum du parent précisé. Du coup, je me retrouve avec un résultat ligne par ligne de forums / sous-forums, et je dois refaire l'arbre ; le but est de refaire cet arbre sous forme d'Array, qui pourra être exploité ultérieurement.. Voici mon script à l'heure actuelle, qui permet d'avoir dans l'array : Les catégories et leurs infos, plus un champ 'children', qui contient NULL par défaut, puis qui contient les array des forums qu'il contient, avec leurs infos, plus un champ 'children', etc. J'arrive à créer l'Array avec les catégories, puis à y insérer les Forums sans parents, puis à insérer par le biais d'une fonction les premiers sous-forums ; mais impossible, pour mon pauvre esprit, de concevoir la fonction en mode récursif pour continuer dans la "généalogie".. Je comprends bien le concept d'une fonction récursive, mais juste, mes syntaxes finissent par planter (des erreurs d'index inexistants, ou encore de mémoire dépassée) Code :
Si quelqu'un a une idée pour me décoincer |
||
|
|
00
|
|
|
#2 | ||
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Je post la suite de mon problème, ayant avancé seul..
J'ai réussi à créer ma fonction, et le résultat est quasiement bon ; le seul bémol, c'est qu'au résultat final, mon array est correctemetn construit mais j'ai perdu au passage toute information concernant les catégories et les 1ers forums. Les sous-forums, quant à eux, sont parfaitement en place avec toutes leurs informations (titre, etc..) voilà mon script à l'heure actuelle : Code :
|
||
|
|
00
|
|
|
#3 | |||
|
Expert Confirmé
![]() ![]() |
Salut WibiMaster,
Citation:
Code :
function addEnfant(&$parents, &$enfants) De mon côté j'ai eu à faire un truc de ce genre et je te l'ai adapté (grosso modo) à tes besoins j'y ai mis des annotations dans le code histoire de ne pas être paumé. Je ne saurais que trop te conseiller de te pencher sur la SPL (Standard PHP Library) car elle offre des tas de fonctions sacrément utiles par exemple dans le cas de la récursivité. Et pour ne rien gâcher la récursivité est mise à plat et du coup tu ne risque pas de mettre à genoux le serveur en cas d'algorithme attaquant des données très volumineuses (vécu). Code :
|
|||
|
00
|
|
|
#4 |
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Merci !
Déjà pour l'histoire des références, il me semblait qu'en la déclarant avec le "&" dans le foreach, je pouvais l'utiliser sans après.. Mais je me trompe peut-être. J'ai donc testé ton script, ça fonctionne presque ; les sous-forums de sous-forums ne sont pas pris en compte, et j'obtiens assez régulièrement l'erreur : Warning: Cannot use a scalar value as an array in C:\Program Files (x86)\EasyPHP-5.3.3\www\live4dev\test2.php on line 53 dans le var_dump.. |
|
|
00
|
|
|
#5 | ||||
|
Expert Confirmé
![]() ![]() |
Oui j'ai fait une boulette dans la ligne 53
remplace $last &= par Code :
Code :
|
||||
|
00
|
|
|
#6 | ||||||
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Presque bon xD
C'est la première fois que j'utilise les RecursiveIteratorIterator, alors je prends mon temps pour lire, comprendre, en utilisant la doc. En tout cas, c'est quasiement bon, mais ça plantait (serveur down) quand je lançais la page. Alors j'ai essayé avec tes données, moins importantes que les miennes, et ça plante aussi. En coupant le chargement de la page au bout de quelques secondes avant que tout pète, j'ai pu remarquer qu'en fait, la boucle ne s'arrêtait jamais ; je retrouve array(3) { ["g0"]=> donc l'origine, plusieurs fois. Comme si toute la page se relançait sans arrêt, donc forcément, tout plante. J'essaie de voir où le script devrait détecter la fin et s'arrêter, pour l'améliorer ; étrange que cela fonctionne correctement chez toi, j'ai pourtant repris point par point tout ce que tu m'as donné.. Les lignes Code :
Code :
Merci de ton aide ! [edit] En réalité, j'ai bien observer le var_dump (meme arreté avant la fin) ; ce n'est pas que le code se répète indéfiniment (quoi que, sans doute tout de même), c'est assez étrange ce qu'il ressort... Tout d'abord, ça me ressort l'array des catégories ; ensuite, l'array des catégories avec le premier forum ; ensuite, la meme chose mais avec plus de forums ; et ainsi de suite.. Comme s'il faisait un var_dump au fur et à mesure, Après vérification, celui-ci était bien dans la boucle. Je l'ai donc ressorti, et du coup, ça plante avant de faire le var_dump, je ne vois donc même pas ce qu'il peut contenir. La boucle ne s'arrête réellement jamais.. Je ne comprends pas, dans ton script, c'est un foreach sur un tableau fini, il ne devrait donc pas tourner éternellement... Ca doit etre à ce niveau là : Code :
|
||||||
|
|
00
|
|
|
#7 |
|
Expert Confirmé
![]() ![]() |
Salut WibiMaster,
Bon je t'explique pourquoi chez moi cela a marché : je l'ai exécuté en mode debug avec un point d'arrêt sur var_dump($map) et avec le débug de PHPED j'ai inspecté le contenu de la variable $map et vu qu'il me parraissait correct, je coupais le sifflet au script sans le terminer proprement (J'avais sorti le var_dump de la boucle foreach). C'est la raison pour laquelle je n'ai pas vu que le script bouclait sans fin. J'suis un âne quand même parfois ![]() Je pense le hic se situe dans le fait que l'on modifie le tableau $map tout en le parcourant récursivement et ça doit poser problème à la SPL. Je me penche dessus. |
|
00
|
|
|
#8 | ||
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Test après test, j'ai cibler le probleme un peu plus bas ;
La boucle ne devrait pas etre infini, le $nb dans l'exemple vaut 1 à chaque tour. donc le for($i = 0; $i < $nb [...] devrait s'arreter au bout d'un tour, ce qu'il n'a pas l'air de faire.. Ca semble bloquer au niveau du $last =& le truc, c'est que je n'arrive pas à comprendre cette syntaxe, même après recherche La boucle entière : Code :
|
||
|
|
00
|
|
|
#9 | |
|
Expert Confirmé
![]() ![]() |
Citation:
J'ai fait un essai sans rien modifer au script mais juste en rajoutant exit(); après le var_dump() et là tu as bien le rendu. |
|
|
00
|
|
|
#10 | ||||
|
Expert Confirmé
![]() ![]() |
ça y est l'os n'est plus :-)
Tu conserves tout le script tel quel et tu lui rajoute un minable après Code :
Code :
Bon dev
|
||||
|
10
|
|
|
#11 |
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
![]() Rien à redire... Respect. Et surtout un énorme merci parce qu'en plus tu post les explications avec, et ça c'est génial pour apprendre de ses erreurs Bon, ça plante avec ma récupération de données, mais ça doit venir des arrays qui ressortent, je reglerais ça rapidement vu que ça marche avec les tiens qui semblent similaires. Je marque résolu, et je t'en dois une belle ! Je te copyrighterais à l'occasion si dans mon entourage je vois un problème similaire :p Encore merci !!! |
|
|
00
|
|
|
#12 | |
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Citation:
[EDIT] Après vérification, le foreach sur le new RecursiveIteratorIterator fais quelques centaines de tours avant de planter, alors que je n'ai que 19 lignes... Il y a donc bien un problème, autre que le break que l'on a placé.. |
|
|
|
00
|
|
|
#13 | ||
|
Expert Confirmé
![]() ![]() |
Salut,
Tu peux aussi écrire le foreach comme ça et fais un essai avec tes données : Code :
|
||
|
00
|
|
|
#14 | ||
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Cela plante également...
J'ai mis le break en dehors de la condition, et ça ne plante plus ; cependant, ça ne me prends pas en compte les sous forums. Ci-joint un aperçu de mes tables catégories et forums, donc qui ressortent comme ton exemple d'array... (avec un sous-forum en plus, je ne sais pas si ça change grand chose..) La boucle fait vraiment trop de tour, elle fais plus que boucler sur l'array uniquement ![]() [EDIT] J'ai fais un test en initialisant le nombre de tour à 0 avant le foreach problematique, et en faisant un echo de ce nombre incrémenter de 1 à chaque tour ; ça plante, quand j'en arrive à 169228. Je mets mon code dans son intégralité, sait-on jamais... (j'ai ré-ordonner les données sorties, le var_dump donne bien le résultat attendu) Code :
|
||
|
|
00
|
|
|
#15 | ||
|
Expert Confirmé
![]() ![]() |
Décidemment il y a des jours où il faudrait mieux rester couché.
Bon comme je suis un sale entêté teigneux, j'ai continué à creuser et voici ce que je te propose. J'ai quand même un peu honte car c'est désarmant de simplicité. Je t'y ai mis aussi un tableau de données qui me faisait le même dépassement de mémoire que toi avec le RecursiveIteratorIterator/RecursiveArrayIterator. Code :
Je me suis absenté 2 heures et au retour ça m'a fait splash boum la-dedans. De mon côté je n'arrive pas à expliquer pourquoi un banal RecursiveIteratorIterator/RecursiveArrayIterator fait un dépassement de capacité mémoire. Je vais chercher et si je trouve une explication qui tienne la route je ferais un suivi ici |
||
|
10
|
|
|
#16 | ||||||
|
Futur Membre du Club
![]() Damien Inscription : juillet 2009 Messages : 50 ![]() |
Citation:
Citation:
![]() Citation:
Citation:
Code :
1e tour : champ1 2e tour : champ1, 3e tour : champ2 4e tour : champ1, 5e tour : champ2, 6e tour : champ3 Résultat 6 tours pour arriver au champ3. Ce n'est qu'une hypothèse, mais ça expliquerait pourquoi avec 19 lignes de 5 champs + 4 lignes de 3 champs il arrive à faire un nombre de tour supérieur à 160000... Peut-être la manière dont le script est agencer. Pourtant selon la doc, si j'ai bien compris, avec cette méthode il efface petit à petit ce sur quoi il a déjà bouclé (suis pas sûr de ça, mais y a une phrase dans la doc qui le fais présager, selon une traduction arbitraire de ma part ^^) donc le dépassement de mémoire ne devrait pas se produire... Quoi qu'il en soit, ta dernière réponse correspond exactement à ce que j'essayais de mettre en place dès le début ^^ Je n'ai juste pas pensé à l'astuce du $current, et à l'array_merge... S'il existe un vrai système de notation dans ce forum, j'te mets la note maximale immédiatement pour ta détermination et le résultat obtenu !! Encore merci !!
|
||||||
|
|
00
|
Copyright © 2000-2012 - www.developpez.com