[RESOLU] probleme liste deroulante

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 09:42

bonjour, j'ai réalisé une liste déroulante permettant de visualiser tout les champs de mon type ENUM dans ma base de données . je visualise donc le champs choisis par la personne plus tout le reste des champs .
donc il y a une répétition du même mot.

voici mon code :
<?php 
$result1 = mysql_query("SELECT DISTINCT * FROM personne WHERE Nom LIKE '".mysql_real_escape_string($nom)."' && Prenom LIKE '".mysql_real_escape_string($prenom)."'");
$list1 = mysql_query("SELECT DISTINCT situation FROM personne ");//requete pour listing personnes
						
echo '<select name="situation">';//création du select	
while ($data = mysql_fetch_array($result1))
{
	while (($row = mysql_fetch_array($list1) )) 
	{
		if ($row["situation"] == $data["situation"])
		  echo '<option value="'.$row["situation"].'" selected>'.$row["situation"].'</option>';
		else
		{
		}
        }									
                 $res = mysql_query('SHOW COLUMNS FROM personne LIKE "situation" ');// requete pour chercher les valeurs dans SET
                 $ligne = mysql_fetch_array($res);//je met les valeurs dans un tableau
                 $type = substr($ligne['Type'], 5, (strlen($ligne['Type'])-7));//je les traites en enlevant les premier et les derniers caractere
                 $mon_enum = preg_split('#\',\'#', $type);//j'enleve les guiellemets et les virgules
                 for ($i=0 ; $i<6 ; $i++)
                 echo '<option value="'.$mon_enum[$i].'">'.$mon_enum[$i].'</option>';	
}
echo '</select>';//fin select		
?>  

il affiche :

liste déroulante:
Marié (valeur sélectionné)
en couple
célibataire
divorcé
Marié

et j'aimerais qu'il affiche une seul fois "Marié" ! comment puis-je faire ? avez vous des idées ?

Mammouth du PHP | 661 Messages

07 janv. 2013, 10:15

Salut :

Tu dois mettre la valeur sélectionnée dans une variable, ensuite, tu affiche la liste des choix possible, et si il y en a un qui correspond à ta variable (choix sélectionné), tu affiche 'selected dans l'<option/>


Sinon, je ne suis pas sur qu'un champ de type ENUM soit une bonne chose pour ce genre d'info, une table liée serait peut-être mieux pour les statistique, évolutions et autres souplesses d'utilisations (mais ce n'est que mon avis ;) )

@++

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 10:45

bonjour,
merci de ta réponse, j'ai mis la variable sélectionne dans le $select et après je l'ai affiché ! mais cela fait toujours un doublons ?
peut être que j'ai mal compris ce que ta dit !
<?php 
$result1 = mysql_query("SELECT DISTINCT * FROM personne WHERE Nom LIKE '".mysql_real_escape_string($nom)."' && Prenom LIKE '".mysql_real_escape_string($prenom)."'");
$list1 = mysql_query("SELECT DISTINCT situation FROM personne ");//requete pour listing personnes
echo '<select name="situation">';//création du select	
while ($data = mysql_fetch_array($result1))
	{
	while (($row = mysql_fetch_array($list1) )) 
		{
		if ($row["situation"] == $data["situation"])	
		$select = $row["situation"];
		}									
	}	
res = mysql_query("SHOW COLUMNS FROM personne LIKE 'situation' ");// requête pour chercher les valeurs dans SET
$ligne = mysql_fetch_array($res);//je met les valeurs dans un tableau
$type = substr($ligne['Type'], 5, (strlen($ligne['Type'])-7));//je les traites en enlevant les premier et les derniers caractère
$mon_enum = preg_split('#\',\'#', $type);//j’enlève les guillemets et les virgules
for ($i=0 ; $i<6 ; $i++)
echo '<option value="'.$mon_enum[$i].'">'.$mon_enum[$i].'</option>';
echo '<option value="'.$select.'" selected >'.$select.'</option>';		
echo '</select>';//fin select		
?>
PS : je récupéré mes valeurs dans un SET et non ENUM , c'est pratiquement pareil

Eléphant du PHP | 120 Messages

07 janv. 2013, 11:28

Bonjour,

J'ai découvert plusieurs erreurs dans ce script. À commencer par la plus flagrante :
res = mysql_query("SHOW COLUMNS FROM personne LIKE 'situation' ");
Ici, il manque le $ à la définition de variable.

Ensuite, tu sembles ne pas comprendre le fonctionnement des pointeurs dans un résultat select de MySQL.
Lorsque tu fais fetch_array(), tu vas lire la prochaine valeur dans la liste de résultats. Ce n'est sûrement pas ce que tu veux, car à la première itération du premier while, tu vas déjà chercher toutes les données de la seconde boucle. Chaque tour de boucle supplémentaire de $result1 ne recevra aucune information de $list1. D'ailleurs les expressions régulières (preg_split) ne sont pas utiles dans ton cas.

Enfin bref, ce code ne fonctionne que par hasard.
Quelques conseils MySQL :
- L'extension MySQL de PHP est dépréciée à partir de PHP5.5 et sera sans doute supprimée à partir de PHP5.6 ou PHP6. Ceci rendrait ton code totalement infonctionnel. Je te conseille donc de passer à mysqli ou PDO avant qu'il ne soit trop tard.
- Il est fortement déconseillé d'utiliser "*" pour récupérer tous les champs, il est vraiment mieux de les définir tous à la main.
- L'opérateur LIKE est moins efficace que l'opérateur =. Like a seulement une utilité lorsque tu veux faire des recherches à l'intérieur du texte du champ (avec les placeholders % et _).
- L'opérateur && n'est pas un standard SQL, l'opérateur AND est standard.

Le code qui fait ce que tu veux (avec PDO) :
<?php
$statement = $db->query("show columns from personne like 'situation'");
$row = $statement->fetch(PDO::FETCH_ASSOC);
$statement->closeCursor();
$type = substr($row['Type'], 5, strlen($row['Type']) - 7);
$enum = explode("','", $type);

$statement = $db->prepare('select distinct situation from personne where Nom = :nom and Prenom = :prenom');
$statement->bindValue(':nom', $nom, PDO::PARAM_STR);
$statement->bindValue(':prenom', $prenom, PDO::PARAM_STR);
$statement->execute();
if ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
	echo '<select name="situation">';
	foreach ($enum as $value) {
		if ($value === $row['situation']) {
			echo '<option value="' . $value . '" selected="selected">' . $value . '</option>';
		} else {
			echo '<option value="' . $value . '">' . $value . '</option>';
		}
	}
	echo '</select>';
}
$statement->closeCursor();
?>

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 11:36

bonjour,

le $res c'est juste un copier/coller qui n'a pas du marcher !!! mais je l'avais dans mon code !
sinon ce qui concerne PDO , je voulais d'abord régler le problème en MYSQL, mais c'est sûr j'allais passez en PDO.
je suis en version PHP 5.3 ! donc PDO ne marche pas.

merci de ta réponse

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 11:42

je rectifie sur PHP 5.3 ! ca marche ! merci pour ta solution !

Eléphant du PHP | 120 Messages

07 janv. 2013, 11:44

Tu es en PHP5.3, donc PDO ne marche pas ? Quel est le rapport ? PDO existe depuis PHP5.1.
Dans ce cas, je vais poster le code pour le mauvais choix de l'extension que je réprouve :
<?php
$result = mysql_query("show columns from personne like 'situation'", $link);
$row = mysql_fetch_assoc($result);
mysql_free_result($result);
$type = substr($row['Type'], 5, strlen($row['Type']) - 7);
$enum = explode("','", $type);

$result = mysql_query("
select
	distinct situation
from
	personne
where
	Nom = '" . mysql_real_escape_string($nom) . "' and
	Prenom = '" . mysql_real_escape_string($prenom) . "'
", $link);

if ($row = mysql_fetch_assoc($result)) {
	echo '<select name="situation">';
	foreach ($enum as $value) {
		if ($value === $row['situation']) {
			echo '<option value="' . $value . '" selected="selected">' . $value . '</option>';
		} else {
			echo '<option value="' . $value . '">' . $value . '</option>';
		}
	}
	echo '</select>';
}
mysql_free_result($result);
?>
D'ailleurs, c'est pas pour dans 5 ans que ton code ne fonctionnera plus du tout avec cette extension. Dans au plus tard 2 ans, ce sera le cas.

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 11:52

merci encore !!! mais je vais passé en PDO !! il faut bien le faire un jour !

Eléphant du PHP | 120 Messages

07 janv. 2013, 11:53

Très bonne initiative :)

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 12:17

juste une derniere question !! comment mettre cela en PDO ?
$result = mysql_query("SELECT * FROM personne WHERE Nom LIKE '".mysql_real_escape_string($nom)."' && Prenom LIKE '".mysql_real_escape_string($prenom)."'");
$nblignes = mysql_numrows($result);
for ($i=0;$i<$nblignes;$i=$i+1)
        { 
	$Nom =  mysql_result($result,$i,"Nom");
	echo $Nom; 
	}
j'ai lu des doc mais c'est plutot compliqué

merci

ViPHP
xTG
ViPHP | 7331 Messages

07 janv. 2013, 12:37

Tu remplaces mysql_query par la fonction query de l'objet PDO instancié.
mysql_real_escape_string par la fonction quote.
Ensuite tu peux itérer directement sur le retour de query avec un foreach.

Eléphanteau du PHP | 25 Messages

07 janv. 2013, 12:49

merci beaucoup !!!!

Eléphant du PHP | 120 Messages

07 janv. 2013, 20:01

Ou bien mieux : avec des requêtes préparées comme dans l'exemple plus haut. En général, il faut éviter de passer des variables directement à la requête sous forme de chaine de caractères. Généralement, si tu dois utiliser la méthode quote(), c'est que tu fais mal les choses.

Cherche après PDO::prepare() dans Google.

Si la performance de ton script t'importe, je te déconseille d'utiliser foreach directement sur le retour de prepare/query, car il ne s'agit pas là réellement d'un tableau (mais d'un objet traversable).
La méthode while ($statement->fetch(PDO::FETCH_ASSOC)) est bien plus performante ;)

ViPHP
xTG
ViPHP | 7331 Messages

07 janv. 2013, 22:03

Ou bien mieux : avec des requêtes préparées comme dans l'exemple plus haut. En général, il faut éviter de passer des variables directement à la requête sous forme de chaine de caractères. Généralement, si tu dois utiliser la méthode quote(), c'est que tu fais mal les choses.
:shock:

Pourrais-tu me détailler ce que fais une requête préparée ? Mais surtout, à quoi cela sert !

Eléphant du PHP | 120 Messages

08 janv. 2013, 09:09

Les requêtes préparées sont l'avantage de PDO et sa force.
Dans la plupart des moteurs les supportant, une requête préparée ressemble à ça :
select user_id, username from users where username = ?
En PDO, il y a moyen de remplacer les points d'interrogation par des alias, ce qui permet de ne pas devoir se soucier de la quantité et de l'ordre des alias que la requête contient ; et donc d'en ajouter et d'en retirer sans devoir changer des entiers à la définition des champs.
$sql = 'select user_id, username from users where username = :username or email_address = :email';
$PDO->prepare($sql);
$PDO->bindValue(':username', $username, PDO::PARAM_STR); // Transmettre $username à la requête en remplaçant ":username"
$PDO->bindValue(':email', $email, PDO::PARAM_STR); // Transmettre $email à la requête en remplaçant ":email"
$PDO->execute();
while ($row = $PDO->fetch(PDO::FETCH_ASSOC)) {
    // Faire quelque chose de ça.
}
D'ailleurs cela marche aussi avec des requêtes INSERT. Et vu qu'on peut exécuter plusieurs fois une telle requêtes, on peut aussi lui transmettre des paramètres différents avant chaque exécution. Les requêtes sont mise en cache (c'est un peu plus compliqué que ça, mais ça résume la situation) et ne sont donc plus analysées syntaxiquement une deuxième fois, ne doivent plus être passées à la base de données. Seules les nouvelles valeurs inscrites sont envoyées. Ceci améliore les performances assez bien à partir de trois/quatre requêtes. Avec une ou deux exécution, la performance est sensiblement identique à celle d'un bête query.
Cette méthode permet aussi de ne plus du tout devoir se soucier d'injections SQL.