JeuWeb - Crée ton jeu par navigateur
De la base de données à la vue : afficher les instances des zones des cartes - 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 : De la base de données à la vue : afficher les instances des zones des cartes (/showthread.php?tid=5264)

Pages : 1 2 3


De la base de données à la vue : afficher les instances des zones des cartes - Dexyne - 21-02-2011

Bon voilà j'ai un soucis d'affichage et je me prend surement la tête pour rien XD.

Avant de mettre le soucis j'aimerais avoir vos avis sur la construction de mes tables parce que j'ai toujours des soucis avec elles xD.

Ce que je cherche à faire :
-J'ai des maps (instanciés), celle-ci contiennent des "zones" (ça a pas de nom je crois mais moi je les appellent ainsi pour les identifier), ces zones contiennent des instances (donjons).
-On a donc les zones qui appartiennent à une map et contiennent des instances.
-Et des instances qui appartiennent à des zones et donc à des maps.

Actuellement j'ai créer 3 tables : instances, maps et zones.
La table maps (id, nom_map) ;
la table zones à les champs (id, nom_zone, id_map) (je sais pu comment on note les clefs étrangères mais id_map en est une) ;
et la table instances (id, nom_instance, id_zone) (id_zone est une clef étrangère).

Note : Y'a d'autres champs dans instances mais ce sont simplement niveau infos et elles sont pas utile dans la construction.

----

Voilà pour la construction, mon problème c'est que je voudrais récupérer les infos des instances + des zones et des maps (en une ou plusieurs requêtes au besoin).

Actuellement je fais comme ceci :

{Controller}

//récupère le résultat du modèle via le controller
$data['instances'] = $this->instancesManager->getInstances();

{View}

foreach ($instances as $listeInstances) :
echo '<h3>'. $listeInstances->nom_map .' - '. $listeInstances->nom_zone .'</h3>';

for($i = 0;$i < sizeof($instances); $i++)
{
if ($instances[$i]->nom_zone === $listeInstances->nom_zone) {
echo $instances[$i]->nom_instance .', '. $instances[$i]->nom_zone .'<br />';
}
}
endforeach;

avec la requête suivante (à cause du copier-coller et du forum ça décale les indentations mais tant pis x)) :
{Model}

public function getInstances()
{
$query = 'SELECT
instances.*,
maps.*,
zones.*
FROM
instances
LEFT JOIN zones ON instances.id_zone_instance = zones.id_zone
LEFT JOIN maps ON zones.id_map = maps.id_map
ORDER BY nom_zone ASC';
$listeInstances = $this->db->query($query);

return $listeInstances->result();
}
J'ai préférer ne pas utiliser le système de CodeIgniter niveau des fonctions pour les requêtes pour faire plus simple pour le moment, sinon là je sélectionnes tout de instances, maps, et zones.

le problème c'est que ça me donne ça :
[Image: dnfaffichageinfos.jpg]

Ce que je voudrais, c'est le même résultat mais sans que la ligne

echo '<h3>'. $listeInstances->nom_map .' - '. $listeInstances->nom_zone .'</h3>';
ne se répète avec le reste du code (je sais que ça vient du foreach vu que mon array contient 7 entrées mais je ne vois pas comment éviter ce doublon, le mieux serait via la requête ou le code PHP ?).

Je suis sur de me prendre la tête pour rien et ça doit être tout con mais bon :x.

Merci d'avance pour vos réponses, suggestions, etc Smile.


Edit de Sephi-Chan : Je renomme le sujet pour mieux présenter le problème (l'ancien titre était "BDD, affichage via php").


RE: BDD, affichage via php - atra27 - 21-02-2011

un if...
Si la ligne est la même que la précédente tu affiche pas!
Sinon tu affiche et tu stock la valeur dans une seconde variable pour les comparaisons ultérieures.


RE: BDD, affichage via php - Nosrehl - 21-02-2011

Si j'ai bien compris, tu veux que les lignes en H3 ne soit affichées qu'une seule fois, donc ne pas les afficher si elles ont déjà été affichées :
Il suffit de stocker la ligne H3 dans une variable temporaire et de tester si la nouvelle ligne H3 est équivalente à chaque fois.


$ligne_H3_precedente = "";
foreach ($instances as $listeInstances) :
$ligne_H3 = '<h3>'. $listeInstances->nom_map .' - '. $listeInstances->nom_zone .'</h3>';

if ($ligne_H3 != $ligne_H3_precedente)
echo $ligne_H3;

$ligne_H3_precedente = $ligne_H3;

for($i = 0;$i < sizeof($instances); $i++)
{
if ($instances[$i]->nom_zone === $listeInstances->nom_zone) {
echo $instances[$i]->nom_instance .', '. $instances[$i]->nom_zone .'';
}
}

endforeach;

Mais je ne suis pas sûr de bien comprendre parce que j'ai l'impression que tu as des doublons pour chaque groupe (ligne H3 + lignes des zones / instances).
Et donc il faudrait plutôt regarder du côté d'un GROUP BY en SQL, chais pas ça dépend de ce que tu veux.

Edit : erf powned, trop lent...


RE: BDD, affichage via php - Sephi-Chan - 21-02-2011




RE: BDD, affichage via php - Dexyne - 22-02-2011




RE: BDD, affichage via php - Sephi-Chan - 22-02-2011

Regarde mon tableau de départ, c'est de la même forme que le tiens :


Array
(
[0] => Array
(
[name] => Blackwing Descent
[zone_name] => Blackrock Mountain
[map_name] => Eastern Kingdoms
)

[1] => Array
(
[name] => Blackrock Caverns
[zone_name] => Blackrock Mountain
[map_name] => Eastern Kingdoms
)

[2] => Array
(
[name] => Bastion of Twilight
[zone_name] => Twilight Highlands
[map_name] => Eastern Kingdoms
)

[3] => Array
(
[name] => Throne of the Four Winds
[zone_name] => Uldum
[map_name] => Kalimdor
)

)

Et pourtant j'arrive à avoir le tableau final. Smile


Sephi-Chan


RE: BDD, affichage via php - niahoo - 22-02-2011

Tu sais Sephi tu peux aussi simplifier en PHP, ce n'est pas incorrect.


$instances_by_zones_by_map = array();
$instances = array(
array('name' => 'Blackwing Descent', 'zone_name' => 'Blackrock Mountain', 'map_name' => 'Eastern Kingdoms'),
array('name' => 'Blackrock Caverns', 'zone_name' => 'Blackrock Mountain', 'map_name' => 'Eastern Kingdoms'),
array('name' => 'Bastion of Twilight', 'zone_name' => 'Twilight Highlands', 'map_name' => 'Eastern Kingdoms'),
array('name' => 'Throne of the Four Winds', 'zone_name' => 'Uldum', 'map_name' => 'Kalimdor')
);

foreach($instances as $instance)
$instances_by_zones_by_map[$instance['map_name']][$instance['zone_name']][] = $instance;




RE: BDD, affichage via php - Sephi-Chan - 22-02-2011

@Niahoo

Oui, c'est plus court ainsi. Smile

D'ailleurs, c'est par cette solution que j'avais commencé, à la différence que j'utilisais array_push, qui balançait des Warning: array_push() expects parameter 1 to be array, null given, l'utilisation de [] réglait le problème. Cohérence, quand tu nous tiens !

Je garde le code plus haut tel qu'il est pour qu'il puisse comprendre la logique de la chose, mais ton code est plus pratique et simple (j'utiliserais des variables $map_key et $zone_key pour maximiser la lisibilité).


@Dexyne

En regardant un peu le fragment de code suivant, j'ai plusieurs choses :


foreach ($instances as $listeInstances) :
echo '<h3>'. $listeInstances->nom_map .' - '. $listeInstances->nom_zone .'</h3>';

for($i = 0;$i < sizeof($instances); $i++)
{
if ($instances[$i]->nom_zone === $listeInstances->nom_zone) {
echo $instances[$i]->nom_instance .', '. $instances[$i]->nom_zone .'';
}
}
endforeach;

  • Tu n'es pas homogène dans ta notation : un coup tu utilises la syntaxe alternative (foreach/endforeach), un coup tu utilises les accolades. Je te conseille d'utiliser les accolades dans tes scripts et la syntaxe alternative dans tes vues (ça rend la fermeture plus lisible).
  • Tu n'es pas homogène dans ton nommage : nom_map est un mélange d'anglais et de français. map_name ou nom_carte est plus cohérent. Bien sûr, je te conseille d'utiliser l'anglais.
  • Tu n'es pas homogène dans ta façon de parcourir un tableau : un coup tu utilises foreach, un coup tu utilises for. Je te conseille d'utiliser foreach.

Essaye de t'imposer un style, ce sera plus simple pour toi et ceux qui lisent ton code.

De plus, ton modèle de données est bien mais le nommage de tes colonnes l'est moins (outre le mélange des langues).
Par exemple, on trouve une colonne nom_map dans ta table maps. Pourquoi ne pas se limiter à nom ? On sait très bien que c'est le nom de la map puisqu'on est dans la table maps.


Sephi-Chan


RE: De la base de données à la vue : afficher les instances des zones des cartes - Dexyne - 22-02-2011

Alors pour le for je parcours pas le tableau ici c'est pour pour avoir la somme des entrée de $instances pour $i et ainsi afficher le bon nom que je désire. Ou alors je vois pas de quoi tu veux parler :o.
Sur le coup je savais pu si for () : "enfor" était faisable alors j'ai préférer faire avec des accolades mais j'aurais utiliser cette méthode sinon.
Pour le nom français / anglais j'avoue que map tellement je le vois que le mot carte n'existe plus XD (à force de dire map en jouant et non carte bah voilà ce qu'il se passe :p).

Si je ne me limite pas à nom en faite c'était surtout à mes débuts pour différencier lorsqu'il y une clef étrangère et un id, pour ne pas les mélanger bien que l'on peux nommer la clef étrangère différemment mais j'avais pris l'habitude de bien nommer selon la table pour ne pas me perdre dans les jointures ou autres (et j'avais pas forcément une bonne utilisation de mes variables ou dans ce genre donc bon).
Mais je me suis demandé si je devais pas justement virer cette habitude bien que je l'ai laissé là mais ce n'est pas trop grave ici, je modifierais pour la version en ligne ^^.


RE: De la base de données à la vue : afficher les instances des zones des cartes - niahoo - 22-02-2011

faire un for et utiliser l'indice $i++ pour accéder successivent aux éléments d'un tableau, si tu n'appelles pas ça parcourir un tableau je me demande bien comment tu appelles ça !