Page 1 sur 2

Afficher les menus et sous menus depuis ma BDD

Posté : 26 juin 2011, 13:12
par rimie
bonjour,

J'ai effectue une requete MySQLi afin d'afficher les menus de ma table hmenu et les sous menu de ma table bmenu, afin d'avoir le resultat suivant:

+Menu1
++ Sous menu1
++ Sous menu1
++ Sous menu1
++ Sous menu1
+Menu2
++ Sous menu2
++ Sous menu2
++ Sous menu2
+Menu3
++ Sous menu3

ainsi de suite
<?php
        	while($row = $r->result->fetch_object())
        	{
        	
			// on affiche les menus principales
        	echo '<div class="headMenu">'.$row->hmenu_ar.'</div>';
        	
        	// on affiche les sous menus du menu principale
        	$r->toDo('SELECT', '*', 'bmenu', 'id_hm1=\''.$row->id_hm.'\' AND onoff=\'1\'');
			$r->num_rows('Number of rows returned: ');
			
			echo '<ul class="ulMenus">';
        	while($row = $r->result->fetch_object())
        	{
        		echo '<li class="liMenus">'.$row->bmenu_ar.'</li>';
        	}
        	
        	echo '</ul>';
        	}
?>

l'affichage se fait comme ca:

+Menu1
++ Sous menu1
++ Sous menu1
++ Sous menu1
++ Sous menu1

mais le reste des menus n'apparaissait pas, merci pour votre aide

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 27 juin 2011, 10:05
par sadeq
Bonjour,

L'erreur est claire : Tu utiliser 2 requêtes imbriquées l'une (celle des sous-menus) dans l'autre (celle des menus principaux) mais malheureusement tu utilises le même nom $r pour les 2 différentes requêtes du coups la seconde requête imbriquée écrase donc la première et la boucle primaire s'arrête net juste après son premier tours c'est à dire après avoir traité le premier menu principal. Il suffit de donner deux noms différents $r1 et $r2 pour séparer les requêtes et par la même il est recommandé aussi de différencier les $row en $row1 et $row2.

Ce sont des règles d'or de programmation : une variable a un nom propre et une durée de vie par rapport une étendue de visibilité.

Début d'une procédure ou fonction ou programme principal:
----- variables locale niveau 1
----- Bloc : IF, WHILE, FOR, ... => variables locales niveau 2 (visibilité variable locales niveau 1)
--------------Sous-Bloc : IF, WHILE, FOR, ... => variables locales niveau 3 (visibilité variable locales niveau 1 et 2)
---------------
... visibilité totale : variables locales niveau 1, 2 et 3
Fin.
... Aucune visibilité des variables locales quelque soit le niveau

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 03:55
par rimie
voila la class que j'utilisais pour la connexion:
<?php

######################## Class de connexion Start #################################
class Connexion {
	
	public $db_host, $db_user, $db_passwd, $db_name, $result, $mysqli;
	
	
	// connect to the server
	public function __construct($db_host='', $db_user='', $db_passwd='')
		{
			$this->db_host = $db_host;
			$this->db_user = $db_user;
			$this->db_passwd = $db_passwd;
			
			$this->connexion = new mysqli($db_host, $db_user, $db_passwd); //HOST, USER, PASSWORD
			
				if ($this->connexion->connect_error) 
					{
 						die('Connect Error (' . $this->connexion->connect_errno . ') '. $this_connexion->connect_error);
					}
			
			// set charset to utf-8
			$char = $this->connexion->set_charset("utf8");
		     
		} // end __construct
		
	
	// select databse
	public final function db_name($db_name)
		{
			$this->db_name = $db_name;
			
			$s_db = $this->connexion->select_db($this->db_name);
			
			if(!$s_db)
			{
				echo 'The '.$db_name.' DOES NOT exists<br>';
			}
			
		} // end db_name
		
	
	// method: select, create, insert, delete, update, read (CRUD)
	public final function toDo($method='', $fields=array(), $table_name='', $conditions='') 
		{
			$this->method = $method;
			$this->fields = $fields;
			$this->table_name = $table_name;	
			$this->conditions = $conditions;
			
			switch($this->method)
				{
					case 'SELECT':
						if($conditions)
							{
								$this->select = "$this->method $fields FROM $this->table_name WHERE $conditions";	
							}
							else
							{
								$this->select = "$this->method $fields FROM $this->table_name";
							}
						echo $this->select.'<br>';
					
					
					/*
					ici je veux mettre prepare et execute, est ce que c'est bien comme ca???
					//$this->presult = $this->connexion->prepare($this->select);
					//$this->exresult = $this->result->execute();	
					*/
					$this->result = $this->connexion->query($this->select);
					
					if(!$this->result)
					{
						echo 'An error has occured<br>';
					}
					break;					
				
				
				} // EnD switch
			
		} // EnD toDo
	
	
	
			
	
	public final function num_rows($sentence='')
		{			
				$row_cnt = $this->result->num_rows;
				echo $sentence.$row_cnt.'<br>';			
		} // end num_rows


} // EnD class
######################## Class de connexion Start #################################
?>
au niveau procedureal on fait comme ca:
$con = SELECT ...
$sql = mysql_query...
pour chaque requete on doit avoir une variable differencte ($con), je ne sais pas si c'est le meme cas dessus:

et le reste du code est:
<?php
$r = new Connexion($db_host, $db_user, $db_passwd);
$r->db_name($db_general);
$r->toDo('SELECT', '*', 'hmenu', 'location="r" AND onoff=\'1\'');
$r->num_rows('Number of rows returned: ');

                while($row = $r->result->fetch_object())
                {
               
                        // on affiche les menus principales
                echo '<div class="headMenu">'.$row->hmenu_ar.'</div>';
               
                // on affiche les sous menus du menu principale
                $r->toDo('SELECT', '*', 'bmenu', 'id_hm1=\''.$row->id_hm.'\' AND onoff=\'1\'');
                        $r->num_rows('Number of rows returned: ');
                       
                        echo '<ul class="ulMenus">';
                while($row = $r->result->fetch_object())
                {
                        echo '<li class="liMenus">'.$row->bmenu_ar.'</li>';
                }
               
                echo '</ul>';
                }
?>
je vais changer $r par $r1, $r2, ainsi de suite, et de meme pour $row, mais a chaque fois je dois etablir une nouvelle connexion??

merci sadeq

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 04:05
par devlop78
Euh ... Sinon, tu fais tout dans une seule requête ce sera encore plus simple, et moins lourd

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 04:08
par rimie
Euh ... Sinon, tu fais tout dans une seule requête ce sera encore plus simple, et moins lourd
oui, ce n'est qu'un bruillon pour tester la class, parce que je suis heureuse a la creer et la tester, je suis contente de verifier ma machine :D

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 06:50
par epommate2
public final function toDo($method='', $fields=array(), $table_name='', $conditions='')
C'est une des pire choses que j'ai vue ... Tu ne devrais pas allez dans cette direction...

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 07:05
par rimie
public final function toDo($method='', $fields=array(), $table_name='', $conditions='')
C'est une des pire choses que j'ai vue ... Tu ne devrais pas allez dans cette direction...
guidez moi svp, je suis debutante :D

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 07:08
par epommate2
Une fonction qui te permet juste d'executer des requetes SQL comme te le conseil develop78 est plus que suffisante.

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 07:19
par rimie
Une fonction qui te permet juste d'executer des requetes SQL comme te le conseil develop78 est plus que suffisante.
qu'est ce que dois je faire?? pour les combiner, j'ai repondu a develop78 que ce n'est qu'un bruillon de les separer et connaitre les problemes de la class

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 11:11
par sadeq
Bonjour,

L'objectif de ta classe est de prendre en charge toutes les opérations d'interaction avec la base de données pour les rendre transparentes pour le programmeur. Selon ce principe l'utilisateur de la classe doit pouvoir ouvrir une connexion à une base de données dans le but de l'interroger, donc une seule connexion suffira par objet de ta classe et avec cette connexion on pourra en principe exécuter tout type de requêtes.
Si tu souhaites faire abstraction des requêtes SQL et proposer des méthodes qui simplifient leur usage ça sera une pure perte de temps car SQL est tellement bien conceptualisé que ses différentes combinaisons qui techniquement répondent aux requêtes utilisateurs sont inimitables sinon que du pure plagia. Le plus judicieux est créer des méthodes qui prennent en charge le traitement de l'exécution et la récupération des résultats d'exécution des requêtes SQL connues (SELECT, INSERT, UPDATE et DELETE) que l'utilisateur de la classe fournira texto.
Dans le cas du SELECT, l’intérêt d'une méthode d'exécution réside dans le fait que seule la classe ait accès à une connexion déjà ouverte, et que la méthode puisse gérer les erreurs inhérentes aux relations avec cette connexion. De plus, la méthode peut extraire les résultats d'exécution et les renvoyer à l'utilisateur de la classe dans un format séparé de la connexion comme par exemple : retourner les résultats dans un tableau. Ce qui reste exploitable facilement par l'utilisateur.

De ces spécifications ressort le modèle objet suivant qui redonne à ta classe une nouvelle organisation:
Programme de la classe et son test:
<?php
######################## Class de connexion #################################
class Connexion {
	// propriétés       
	public $connexion, $db, $db_host, $db_user, $db_passwd, $db_name, $result, $mysqli;

	// connect to the server & open default database
	public function __construct($db_host='', $db_user='', $db_passwd='', $db_name='')
	{
		$this->db_host = $db_host;
		$this->db_user = $db_user;
		$this->db_passwd = $db_passwd;
		$this->connexion = new mysqli($db_host, $db_user, $db_passwd); //HOST, USER, PASSWORD
		if ($this->connexion->connect_error)
	   	{
	   		die('Error (' . $this->connexion->connect_errno . ') : '. $this->connexion->connect_error);
		}
       
		// set charset to utf-8
		$this->connexion->set_charset("utf8");
		
		// open default database if givven
		if (trim($this->db_name)!='' && !$this->openDb($db_name))
	   	{
	   		die ('The '.$db_name.' does not exists');
		}
     
	} // end __construct
       
       
	// select a databse
	public function openDb($db_name)
	{
		//si pas de connexion, alors rien
		if (!$this->connexion) return false;
		
		//sinon ouvrir la base
		$this->db_name = $db_name;
       	$this->db = $this->connexion->select_db($this->db_name);
       	if(!$this->db)
		{
			return false;
		}
		return true; // db opened
       
	} // end db_name
       
       
	// method: select, create, insert, delete, update, read (CRUD)
	public function execSQL($sql)
	{
		//si pas de connexion, alors rien
		if (!$this->connexion) return false;
		
		// exécution SQL : 3 cas (1. erreur d'exécution, 2. résultat requêtes non SELECT, 3. résultat SELECT)
		$result = $this->connexion->query($sql);
		if ($result === FALSE) // cas d'erreur d'exécution
		{
			echo ('Error (' . $this->connexion->connect_errno . ') : '. $this->connexion->connect_error);
			return false;
		}
		else if ($result === TRUE)// cas de toute requête non SELECT
		{
			return true;
		}
		else {
			// cas du select
			$tabl_result = array();
			while ($result && $row = $this->connexion->fetch_object())
			{
				$tabl_result[] = $row;
			}
			return $tabl_result;
		}
	} // EnD execSQL
	
	// fermer la connexion
	public function close()
	{      
		if ($this->connexion && $this->db) $this->connexion->close();
	} // end close
	
	// destructeur
	public function __destruct() {
       $this->close();
   }


} // EnD class
######################## Class de connexion #################################



//////////// TEST de la classe ////////////////


// ouvrir la base de données TEST
$db_test = new Connexion('localhost', 'root', '', 'dbtest');

// exécuter des requêtes SELECT
$tabl_hMenu = $db_test->execSQL("SELECT * FROM hmenu WHERE location='r' AND onoff='1'");
if ($tabl_hMenu && is_array($tabl_hMenu))
{
	echo 'Number of rows returned: ' . count($tabl_hMenu);
	foreach($tabl_hMenu as $row_hMenu)
	{
		// on affiche les menus principales
		echo '<div class="headMenu">'.$row_hMenu->hmenu_ar.'</div>';
	
		// on affiche les sous menus du menu principale
		$tabl_bMenu = $db_test->execSQL("SELECT * FROM bmenu WHERE id_hm1='".$row_hMenu->id_hm."' AND onoff='1'");
		if ($tabl_bMenu && is_array($tabl_bMenu))
		{
			echo 'Number of rows returned: ' . count($tabl_bMenu);
			echo '<ul class="ulMenus">';
			foreach($tabl_bMenu as $row_bMenu)
			{                        
				echo '<li class="liMenus">'.$row_bMenu->bmenu_ar.'</li>';
            } // fin boucle $tabl_bMenu
			echo '</ul>';
		}
	} // fin boucle $tabl_hMenu
}

// fermer la base de données
$db_test->close();
?>

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 12:45
par epommate2
car SQL est tellement bien conceptualisé que ses différentes combinaisons qui techniquement répondent aux requêtes utilisateurs sont inimitables sinon que du pure plagia.
Alors celle-ci, je vais l'encadrer et l'afficher chez les gens qui me gonflent avec leur ORM :-)

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 28 juin 2011, 14:47
par sadeq
car SQL est tellement bien conceptualisé que ses différentes combinaisons qui techniquement répondent aux requêtes utilisateurs sont inimitables sinon que du pure plagia.
Alors celle-ci, je vais l'encadrer et l'afficher chez les gens qui me gonflent avec leur ORM :-)
Voila c'est fait :mrgreen:
Image

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 29 juin 2011, 02:32
par devlop78
LOL

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 29 juin 2011, 04:59
par rimie
sadeq: j'ai voulu tester le code avant de le bien comprendre ca donne rien, aucun affichage, avec un echo sur $result:
echo $result;
ca donne rien

Re: Afficher les menus et sous menus depuis ma BDD

Posté : 29 juin 2011, 06:21
par epommate2
Voila c'est fait :mrgreen:
lol, merci !