imbriquer des boucles

pat
Eléphant du PHP | 132 Messages

18 oct. 2007, 11:11

Bonjour,

Je possède une table t_region comportant les régions de France avec les colonnes
ID_region
region
et une table t_regionfourn comportant le n° du fournisseur et les n° de régions sur lesquelles il travaille
les colonnes sont
id_fournregion
id_fourn
id_region

Je veux que la page affiche OK devant les régions du fournisseur


mais ça ne marche pas elle n'affiche que les régions
<?php require_once('Connections/connectgl.php'); ?>
<?php
mysql_select_db($database_connectgl, $connectgl);
$query_region = "SELECT * FROM t_region WHERE Region <> 'France' ORDER BY Region ASC";
$region = mysql_query($query_region, $connectgl) or die(mysql_error());
$row_region = mysql_fetch_assoc($region);
$totalRows_region = mysql_num_rows($region);

$colfourn_regionfourn = "379";
if (isset($_SESSION['numfourn'])) {
  $colfourn_regionfourn = (get_magic_quotes_gpc()) ? $_SESSION['numfourn'] : addslashes($_SESSION['numfourn']);
}
mysql_select_db($database_connectgl, $connectgl);
$query_regionfourn = sprintf("SELECT t_fournregion.id_fournregion, t_fournregion.id_fourn, t_fournregion.id_region, t_fournregion.affichez, t_region.ID_Region, t_region.Region FROM t_fournregion, t_region WHERE t_fournregion.id_fourn=%s AND t_region.ID_Region=t_fournregion.id_region", $colfourn_regionfourn);
$regionfourn = mysql_query($query_regionfourn, $connectgl) or die(mysql_error());
$row_regionfourn = mysql_fetch_assoc($regionfourn);
$totalRows_regionfourn = mysql_num_rows($regionfourn);
?>
<html>
<head>
<title>Document sans titre</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<?php do { ?>
<?php echo $row_region['ID_Region']; ?> 
	<?php do { ?>
		<?php if( $row_regionfourn['ID_Region'] == $row_region['ID_Region'])
		{echo "ok";}
		?> 
	<?php } while ($row_regionfourn = mysql_fetch_assoc($regionfourn)); ?>
<?php } while ($row_region = mysql_fetch_assoc($region)); ?>
</body>
</html>
<?php
mysql_free_result($region);

mysql_free_result($regionfourn);
?>


d0m
Mammouth du PHP | 1141 Messages

18 oct. 2007, 11:28

conseil pour debugguer :
si il n'affiche pas ok c'est que vraisemblablement ta condition n'est pas vérifiée.
Pour être sur de ça et voir ce qui se passe, affiche tes deux membres du test d'égalité pour les comparer à l'oeil :
//remplace :
<?php
if( $row_regionfourn['ID_Region'] == $row_region['ID_Region'])
 {echo "ok";}
?> 

par :
<?php
  echo $row_regionfourn['ID_Region'] . ' == '.  $row_region['ID_Region'];
?>

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

18 oct. 2007, 11:31

Voici quelques conseils pour faciliter ton développement et alléger tes codes :
  • il est inutile de faire
    <?php ... ?>
    <?php ...
    Si tu n'a aucun caractères entre ?> et <?php, pas la peine de les mettres
  • Si tu ne changes pas de base de données, un seul mysql_select_db() suffit
  • Il faut éviter les SELECT *, il ne faut récupérer que les champs qui t'intéresse. Pour la 1ere requête, par exemple, SELECT ID_Region suffirait
  • Pourquoi toujours récupérer le nombre de résultat de la requête, pas nécessaire si tu ne l'utilise pas
  • il vaut mieux parcourir les résultats des requête avec un while () {} plutôt qu'un do {} while () (Permet d'éviter des erreurs si la requête ne retourne aucun résultat)
Voici une version allegée de ton code, a toi de prendre en compte mon dernier conseil.
Non seulement ton code est plus facile à lire, mais en plus, tu verras surement apparaitre des erreurs ;)
<?php 
	require_once('Connections/connectgl.php');

	mysql_select_db($database_connectgl, $connectgl);
	
	$query_region = "	SELECT * 
						FROM t_region 
						WHERE 
							Region <> 'France'
						ORDER BY Region ASC";
	$region 	= mysql_query($query_region, $connectgl) or die(mysql_error());
	$row_region = mysql_fetch_assoc($region);
	
	$colfourn_regionfourn = "379";
	if (isset($_SESSION['numfourn'])) {
	  $colfourn_regionfourn = (get_magic_quotes_gpc()) ? $_SESSION['numfourn'] : addslashes($_SESSION['numfourn']);
	}

	$query_regionfourn = sprintf("	SELECT 
										t_fournregion.id_fournregion,
										t_fournregion.id_fourn, 
										t_fournregion.id_region, 
										t_fournregion.affichez, 
										t_region.ID_Region, 
										t_region.Region 
									FROM 
										t_fournregion, 
										t_region 
									WHERE 
										t_fournregion.id_fourn = %s 
										AND t_region.ID_Region = t_fournregion.id_region",
									$colfourn_regionfourn);
	$regionfourn 			= mysql_query($query_regionfourn, $connectgl) or die(mysql_error());
	$row_regionfourn 		= mysql_fetch_assoc($regionfourn);
	$totalRows_regionfourn 	= mysql_num_rows($regionfourn);
?>
<html>
	<head>
		<title>Document sans titre</title>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
	</head>

	<body>
<?php 
	do {
		echo $row_region['ID_Region'];
    	do {
    		if( $row_regionfourn['ID_Region'] == $row_region['ID_Region'])
        	{
        		echo "ok";
        	}
        } while ($row_regionfourn = mysql_fetch_assoc($regionfourn));
	} while ($row_region = mysql_fetch_assoc($region));
?>
	</body>
</html>
<?php
	mysql_free_result($region);
	
	mysql_free_result($regionfourn);
?> 
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

pat
Eléphant du PHP | 132 Messages

18 oct. 2007, 12:31

conseil pour debugguer :
si il n'affiche pas ok c'est que vraisemblablement ta condition n'est pas vérifiée.
Pour être sur de ça et voir ce qui se passe, affiche tes deux membres du test d'égalité pour les comparer à l'oeil :
//remplace :
<?php
if( $row_regionfourn['ID_Region'] == $row_region['ID_Region'])
 {echo "ok";}
?> 

par :
<?php
  echo $row_regionfourn['ID_Region'] . ' == '.  $row_region['ID_Region'];
?>
J' ai utiliser ton code pour verifier ce qui ce passe ( j'ai ajouté des <br> pour la lisibilité.
Voici ce que je trouve
1
23 == 1
12 == 1
20 == 1
21 == 1
2
== 2
3
== 3
En fait il ne fait tourner la variable $row_regionfourn['ID_Region'] uniquement lors du premier tour de la première boucle.
Pourquoi

d0m
Mammouth du PHP | 1141 Messages

18 oct. 2007, 12:50

C'est normal, lorsque tu parcours les élements résultats d'une requête, tu ne peux le faire qu'une fois.
Ce que je te conseille de faire c'est avant de faire de l'affichage, tu stocke dans une variable (tableau par exemple) les résultats de ta requête pour pouvoir les parcourir plusieurs fois.
$region_fourn = array();
while ($row_regionfourn = mysql_fetch_assoc($regionfourn)){
  $region_fourn[$row_regionfourn['ID_Region']] = $row_regionfourn['ID_Region'];
}

do {
  echo $row_region['ID_Region'];
  ifin_array($row_region['ID_Region'],$region_fourn) echo 'ok';
} while ($row_region = mysql_fetch_assoc($region)); 

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

18 oct. 2007, 13:01

ou alors, on peut utiliser mysql_data_seek(0) pour réinitialiser un jeu de résultat MySQL
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

pat
Eléphant du PHP | 132 Messages

18 oct. 2007, 15:04

je viens d'essayer la solution de DOM en corrigeant les fautes de frappe.
<?php $region_fourn = array();
while ($row_regionfourn = mysql_fetch_assoc($regionfourn)){
  $region_fourn[$row_regionfourn['ID_Region']] = $row_regionfourn['ID_Region'];
}

do {
  echo $row_region['ID_Region'];
  if (in_array($row_region['ID_Region'],$region_fourn)) echo "ok";?>
  <br>
  <?php
} while ($row_region = mysql_fetch_assoc($region)); ?>
<?php print_r($region_fourn)?>
le résultat ne prend jamais la première région de la requête regionfourn
Il me met OK devant 20 21 23 et oublie 12
Si j' inverse l'ordre de la requête avec order by
Il me met OK devant 12 20 21 et oublie 23
J'ai fait un print_r qui confirme qu' il oublie toujours le premier enregistrement

d0m
Mammouth du PHP | 1141 Messages

18 oct. 2007, 15:19

c'est parce que tu fais ceci avant la boucle :
$row_regionfourn = mysql_fetch_assoc($regionfourn); //(1)
en faisant cela, tu ne prends pas en compte le premier résultat de ta requête dans la boucle while.
En effet lorsque tu fait le while,
while($row_regionfourn = mysql_fetch_assoc($regionfourn)); 
tu passe au second enregistrement car le premier a déjà parcouru par l'instruction (1)

pat
Eléphant du PHP | 132 Messages

18 oct. 2007, 15:37

Je viens de faire la solution de ZEUS qui fonctionne parfaitement
<?php do { 
 echo $row_region['ID_Region']; ?> 

	<?php do { 
  if ($row_regionfourn['ID_Region'] == $row_region['ID_Region']) {echo"OK";}
  
?> 

	<?php } while ($row_regionfourn = mysql_fetch_assoc($regionfourn)); 
	 $row_regionfourn = mysql_data_seek($regionfourn,0);
	 ?>
	 <br>
	 <?php
 } while ($row_region = mysql_fetch_assoc($region)); ?>
Par contre dom j'avoue ne pas bien comprendre ce que je dois faire.
J'ai essayé de bouger le while mais çà ne change rien.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

18 oct. 2007, 15:47

Je viens de faire la solution de ZEUS qui fonctionne parfaitement
Ce qui devrait te donner envie de suivre mes autres conseils ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

d0m
Mammouth du PHP | 1141 Messages

18 oct. 2007, 15:52

ZEUS te conseillais également d'utiliser while au lieu de do while.

Je vais t'expliquer :
Cette instruction
$row_regionfourn = mysql_fetch_assoc($regionfourn)
a pour effet de placer ligne suivante du résultat de la requete dans la variable $row_regionfourn sous forme de tableau associatif.
A chaque fois que cette instruction est utilisée, on avance dans le résultat (comme un next sur un tableau).

Dans ton code tu utilises do ...while
<?php do { 
  if ($row_regionfourn['ID_Region'] == $row_region['ID_Region']) {echo"OK";}
} while ($row_regionfourn = mysql_fetch_assoc($regionfourn));
Normalement, en entrant pour la première fois dans la boucle, il devrait y avoir une erreur car $row_regionfourn n'est pas initialisé. Chez toi ca marche car tu l'as déjà initialisé avant grace à l'instruction
$row_regionfourn = mysql_fetch_assoc($regionfourn);
située après ta requête.

Mais pourquoi faire la première instruction hors de la boucle?
En gros pour imager cela c'est comme si tu faisais :
echo $tab[0];
for($i=1;$i<6;$i++){
  echo $tab[$i];
}

//au lieu de 
for($i=0;$i<6;$i++){
  echo $tab[$i];
}

pat
Eléphant du PHP | 132 Messages

18 oct. 2007, 17:08

Je viens de faire la solution de ZEUS qui fonctionne parfaitement
Ce qui devrait te donner envie de suivre mes autres conseils ;)
Encore merci pour ta solution et je vais suivre tes autres conseils.
Je vais essayer aussi de faire fonctionner la solution de DOM afin d'être moins bête ce soir

pat
Eléphant du PHP | 132 Messages

18 oct. 2007, 17:14

ZEUS te conseillais également d'utiliser while au lieu de do while.

Je vais t'expliquer :
Cette instruction
$row_regionfourn = mysql_fetch_assoc($regionfourn)
a pour effet de placer ligne suivante du résultat de la requete dans la variable $row_regionfourn sous forme de tableau associatif.
A chaque fois que cette instruction est utilisée, on avance dans le résultat (comme un next sur un tableau).

Dans ton code tu utilises do ...while
<?php do { 
  if ($row_regionfourn['ID_Region'] == $row_region['ID_Region']) {echo"OK";}
} while ($row_regionfourn = mysql_fetch_assoc($regionfourn));
Normalement, en entrant pour la première fois dans la boucle, il devrait y avoir une erreur car $row_regionfourn n'est pas initialisé. Chez toi ca marche car tu l'as déjà initialisé avant grace à l'instruction
$row_regionfourn = mysql_fetch_assoc($regionfourn);
située après ta requête.

Mais pourquoi faire la première instruction hors de la boucle?
En gros pour imager cela c'est comme si tu faisais :
echo $tab[0];
for($i=1;$i<6;$i++){
  echo $tab[$i];
}

//au lieu de 
for($i=0;$i<6;$i++){
  echo $tab[$i];
}
Bon ça marche encore merci pour ta solution et tes explications qui m'ont éclaircie certains points

Voila le script
<?php require_once('Connections/connectgl.php'); ?>
<?php
mysql_select_db($database_connectgl, $connectgl);
$query_region = "SELECT * FROM t_region WHERE Region <> 'France' ORDER BY Region ASC";
$region = mysql_query($query_region, $connectgl) or die(mysql_error());
$row_region = mysql_fetch_assoc($region);
$totalRows_region = mysql_num_rows($region);

$colfourn_regionfourn = "379";
if (isset($_SESSION['numfourn'])) {
  $colfourn_regionfourn = (get_magic_quotes_gpc()) ? $_SESSION['numfourn'] : addslashes($_SESSION['numfourn']);
}
mysql_select_db($database_connectgl, $connectgl);
$query_regionfourn = sprintf("SELECT t_fournregion.id_fournregion, t_fournregion.id_fourn, t_fournregion.id_region, t_fournregion.affichez, t_region.ID_Region, t_region.Region FROM t_fournregion, t_region WHERE t_fournregion.id_fourn=%s AND t_region.ID_Region=t_fournregion.id_region", $colfourn_regionfourn);
$regionfourn = mysql_query($query_regionfourn, $connectgl) or die(mysql_error());

$totalRows_regionfourn = mysql_num_rows($regionfourn);
?>
<html>
<head>
<title>Document sans titre</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<?php $region_fourn = array();
while ($row_regionfourn = mysql_fetch_assoc($regionfourn))
{
  $region_fourn[$row_regionfourn['ID_Region']] = $row_regionfourn['ID_Region'];
}
while ($row_region = mysql_fetch_assoc($region))

 {
  echo $row_region['ID_Region'];
  if (in_array($row_region['ID_Region'],$region_fourn)) echo "ok";
  ?>
  <br>
  <?php
	}  ?>
<?php print_r($region_fourn)?> 
</body>
</html>
<?php
mysql_free_result($region);

mysql_free_result($regionfourn);
?>