Petite aide pour un switch...

Résolu
fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012 - 8 mars 2011 à 00:10
fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012 - 8 mars 2011 à 15:41
Bonjour à tous.
J'ai comme un petit problème de switch...
Je m'explique:
Je pioche une valeur dans une table sous format d'un nombre.
Suivant la valeur j'affecte un numéro qui sera en echo dans un nom d'image (.png">).

La valeur piochée varie de 1 à 250 par exemple.

Donc j'applique le code suivant:
switch($Pourcent){
case $Pourcent < 4 : $imgp = '01';
break;
case ($Pourcent >= 5) && ($Nombre <= 9) : $imgp = '02';
break;

ect......

case $Pourcent > 250 : $imgp = '15';
break;
default : $imgp = '01';
break;
}


Une fois la page affichée, je me retrouve avec l'image 01 et l'image 02 seulement alors que j'ai des valeurs diverses et même dépassant les 100...

On peut voir le source en appli sur le site www.team-ufs.fr dans le bandeau rouge en dessous du gros cadre du haut, le texte en marquee, où le nombre affiché est le pourcentage (après application d'une function calcul) du nombre réel pioché dans la table puis l'image après le "%".

M'est-je trompé quelque part dans mon case ou utiliserai-je une mauvaise procédure?
Si besoin est, je posterai la portion de code concernée.
Merci d'avance!




Amiga user for ever...

11 réponses

fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012
8 mars 2011 à 13:58
Tu as sûrement raison, je ne suis pas assez compétent pour contredir à 100% mais je cite:
Le Switch permet d'avoir une écriture simplifiée, nettement plus lisibile qu'une pile de if then else.
Exemple simple

$Nombre = 2;
switch($Nombre)
  {
  case 1:
    echo "Un";
  case 2:
    echo "Deux";
  case 3:
    echo "Trois";
  }

    * Constatez l'absence de ; à la fin de switch($Nombre). Très important, sinon ça ne marche pas!
    * Après case 1, case 2 et case 3, ce sont deux ponts : et non pas point-virgule ;
    * les accolades sont nécessaires

Dans cet exemple le résultat sera étrangement :
DeuxTrois

Je n'ai pas d'explication quant à ce phénomène, mais j'ai une solution :

Il est nécessaire d'inclure le mot-clé break; afin de l'informer qu'il doit s'arrêter. Le code suivant :

$Nombre = 2;
switch($Nombre)
  {
  case 1:
    echo "Un";
    break;
  case 2:
    echo "Deux";
    break;
  case 3:
    echo "Trois";
    break;
  }

affichera :
Deux

    * Si $Nombre avait valu 5, rien n'aurait été affiché, et aucune erreur n'aurait été générée.

Phénomène lié au break :

Dès qu'une comparaison est exécutée, le break renvoie immédiatement à la ligne d'instruction après le Switch. Exemple :

$Nombre = 5;
switch($Nombre)
  {
  case 5 :
    echo "Cinq";
    break;
  case 5 :
    echo "Five";
    break;
}

Affiche seulement :
Cinq
Gestion des valeurs non prévues avec default

Si nombre est différent de 1,2 ou 3, on veut afficher "Nombre différent de 1, 2 ou 3" :

$Nombre = 5;
switch($Nombre)
  {
  case 1:
    echo "Un";
    break;
  case 2:
    echo "Deux";
    break;
  case 3:
    echo "Trois";
    break;
  default:
    echo "Nombre différent de 1, 2 ou 3";
    break;
}

    * C'est bien default : et PAS case default :

Gestion des plages de valeur

Il faut savoir que l'écriture

$Nombre = 1;
switch($Nombre)
  {
  case 1:
    echo "Un";
    break;
  }

N'est que la contraction de l'écriture :

$Nombre = 1;
switch($Nombre)
  {
  case $Nombre == 1:
    echo "Un";
    break;
  }

Quand on a compris ça, la gestion des plages de valeurs coule de source. L'exemple suivant affiche :

    * Petit si le nombre est inférieur à 10
    * Moyen s'il est compris entre 10 et 50
    * Grand s'il est supérieur à 50

$Nombre = 32;
switch ($Nombre)
  {
  case ($Nombre < 10) :
    echo "petit";
    break;
  case (($Nombre >= 10) && ($Nombre <= 50)) :
    echo "Moyen";
    break;
  case ($Nombre > 50) : // ou default, c'est pareil
    echo "Grand";
    break; // dernier break facultatif par sa nature même
  }

    * En fait, on peut mettre n'importe quelle expression booléenne après les case, même si ça n'a rien à voir avec l'instruction initiale switch.

Booléen ou non?

Tant est que ce que j'ai fait fonctionne bien, sauf que je m'étais simplement trompé dans une des variables (comme quoi on est pas parfait)...

if ($Pourcent <= 4){
$imgp = '01';
} elseif (($Pourcent >= 5) && ($Pourcent <= 9)){
$imgp = '02';
} elseif (($Pourcent >= 10) && ($Pourcent <= 14)){
$imgp = '03';
} elseif (($Pourcent >= 15) && ($Pourcent <= 19)){
$imgp = '04';
} elseif (($Pourcent >= 20) && ($Pourcent <= 24)){
$imgp = '05';
} elseif (($Pourcent >= 25) && ($Pourcent <= 29)){
$imgp = '06';
} elseif (($Pourcent >= 30) && ($Pourcent <= 34)){
$imgp = '07';
} elseif (($Pourcent >= 35) && ($Pourcent <= 39)){
$imgp = '08';
} elseif (($Pourcent >= 40) && ($Pourcent <= 44)){
$imgp = '09';
} elseif (($Pourcent >= 45) && ($Pourcent <= 49)){
$imgp = '10';
} elseif (($Pourcent >= 50) && ($Pourcent <= 99)){
$imgp = '11';
} elseif (($Pourcent >= 100) && ($Pourcent <= 149)){
$imgp = '12';
} elseif (($Pourcent >= 150) && ($Pourcent <= 199)){
$imgp = '13';
} elseif (($Pourcent >= 200) && ($Pourcent <= 249)){
$imgp = '14';
} elseif ($Pourcent >= 250){
$imgp = '15';
}


J'ai ainsi une image par plage de valeur.
Merci quand même, julien.


Amiga user for ever...
3
fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012
8 mars 2011 à 00:14
Zutoublié:

Je dois afficher 15 images différentes réparties sur la fourchette de 250 sachant de 1 à 100 en pas de 25 et de 100 à 250 en pas de 50.
Chaque image est attribuée donc à un nombre de base lui même attribué à un pseudo (juste pour info).


Amiga user for ever...

Le textarea des commentaires de ce site ne comprend pas le bbcode
.

Donc considérer que ce qu'il y a entre ces tags là n'est que du code cité.
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
8 mars 2011 à 01:07
Le switch s'applique à des valeurs différentes (et non à des conditions sur celles-ci). Ce serait donc sur la valeur entière de $pourcent divisé par 5 qu'il faudrait faire porter le switch (au moins pour les premières images)
$nos=round($pourcent/5);
switch($nos) {
case 0:img='01';break;
case 1:img='02';break;
}
Le calcul du $nos de l'image pourrait, bien entendu, être modifié au delà de certains paliers.

Ceci dit l'utilité du switch n'apparaît pas évidente puisque le nom de l'image semble alors pouvoir être construit à partir de son numéro...

Enfin, il existe en php une fonction array_rand() permettant de tirer au hasard n éléments d'un tableau plus important.

Il serait donc aisé de lire un répertoire d'images (repérées par la date et l'heure de leur téléchargement sur le serveur de manière à éviter les piratages de l'ensemble des images) et de choisir aléatoirement les images à afficher...

La fonction schuffle() pourrait permettre aussi quelques variantes en distinguant des catégories d'images ...
0
cod57 Messages postés 1653 Date d'inscription dimanche 7 septembre 2008 Statut Membre Dernière intervention 11 septembre 2013 19
8 mars 2011 à 08:59
bonjour
l'idée de 007julien est la bonne je crois
petit snippet pour t'aider
bne prog
a++

<?php
$host="localhost";
$login="root";
$pass="";
$base="atast";
$table="tableau";

              
mysql_connect($host,$login,$pass) or die('serveur ?');
mysql_select_db($base) or die('base ?');
$sql="select image from ".$table;
$query=mysql_query($sql) or die('demande ?');

$choix = array();

while($res=mysql_fetch_array($query)){
$choix[]=$res['image'];
}

$count=count($choix);

if(isset($choix) && !empty($choix)){
$position=rand(0,$count-1);

/*sol 1*/
$rand_keys = array_rand($choix,$position+1);
echo $choix[$position] . "\n";

/*sol 2*/
shuffle($choix);
echo  $choix[$position]."\n";
$choix=array(); /*vide le tableau*/
$count=0;
}else{
echo 'erreur choix vide';
}
?>
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cod57 Messages postés 1653 Date d'inscription dimanche 7 septembre 2008 Statut Membre Dernière intervention 11 septembre 2013 19
8 mars 2011 à 09:08
erratum ...

<?php
$host="localhost";
$login="root";
$pass="";
$base="atast";
$table="tableau";

              
mysql_connect($host,$login,$pass) or die('serveur ?');
mysql_select_db($base) or die('base ?');
$sql="select image from ".$table;
$query=mysql_query($sql) or die('demande ?');

$choix = array();

while($res=mysql_fetch_array($query)){
$choix[]=$res['image'];
}

$count=count($choix);

if(isset($choix) && !empty($choix)){
$position=rand(0,$count-1);

/*sol 1*/
$rand_keys = array_rand($choix);
echo $choix[$rand_keys] . "\n";

/*sol 2*/
shuffle($choix);
echo  $choix[$position]."\n";
$choix=array(); /*vide le tableau*/
$count=0;
}else{
echo 'erreur choix vide';
}
?>
0
fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012
8 mars 2011 à 12:13
Oh ben! Merci bien les gars!
julien=> tes précisions sont intéressantes, mais il me semble bien que dans la doc php, ils précisent qu'on peut utiliser switch en conditionnel, à l'identique de if ($truc >= $bidule){ .... Je vais plutôt tenter avec du conditionnel simple a base de if elseif, ainsi je verrai si ce sont mes valeurs issues de la bdd qui posent problème.
cod57=>merci pour ce snippet. Il est intéressant mais ne risque pas trop de coller à ce que je recherche. Cependant, je garde sous le coude car on a toujours besoin d'un randomize çà ou là (et peut servir à d'autres).
Je tenais aussi à préciser à julien que les images ne peuvent être aléatoires, ce n'est pas une galerie ou un cadre photo mais des icones bien définies récompensant chaque utilisateur suivant le nombre de posts qu'il a effectué sur le forum, parallèle au site.
Mais la fonction array_rand() peut être utile, je retiens.





Amiga user for ever...

Le textarea des commentaires de ce site ne comprend pas le bbcode
.

Donc considérer que ce qu'il y a entre ces tags là n'est que du code cité.
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
8 mars 2011 à 13:14
Désolé, aussi bien en vo que traduite en français (voir extraits ci-après), la documentation PHP n'évoque pas les booléens lorsqu'elle évoque les valeurs possibles des cases d'un switch. Merci de ne pas suggérer de contre-vérités.

« The case expression may be any expression that evaluates to a simple type, that is, integer or floating-point numbers and strings »

[i]« La valeur du case peut être toute expression de type scalaire, c'est-à-dire nombre entier, nombre à virgule flottante et chaîne de caractères. »
/i
Par ailleurs, même si le textarea de ce site ne comprend pas le «bbcode», des boutons autorisent l'insertion de codes divers et variés.
0
fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012
8 mars 2011 à 14:02
Oublié:
pour
Par ailleurs, même si le textarea de ce site ne comprend pas le «bbcode», des boutons autorisent l'insertion de codes divers et variés. 

Ne pas prendre en considération, ce n'était pas adressé à ce site... Copier/coller, quand tu me colles...


Amiga user for ever...
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
8 mars 2011 à 15:23
Effectivement le switch admet (avec PHP 5.3.0) la reprise du paramètre et l'inclusion de conditions sur celui-ci (bien que cela semble un peu contre nature).

Pour le reste, le code suivant ne serait-il pas plus performant?
if ($prm<50) $prm=round($pourcent/5);
else $prm=10+round($pourcent/50);

$prf="";if ($prm<10) $prf="0";
$imgp=$prf.$prm;
0
007Julien Messages postés 276 Date d'inscription mercredi 22 septembre 2010 Statut Membre Dernière intervention 8 janvier 2014 4
8 mars 2011 à 15:26
Il faut remplacer le round() par un floor() pour arrondir à l'entier inférieur ou égal à.
0
fra1ft Messages postés 35 Date d'inscription mercredi 7 mai 2003 Statut Membre Dernière intervention 24 septembre 2012
8 mars 2011 à 15:41
Ui, c'est vrai qu'arrondir au lieu de laisser du brut avec virgule serait mieux, tout en affinant le résultat suivant la plage de valeur à analyser.
(Pour l'inclusion de conditions dans un switch, je suis d'accord que c'est un peu capilotracté et contre nature mais bon...)
Pour une fois que je tombe sur des gars qui s'intéressent et affinent le code d'un novice au lieu de critiques peu constructives, j'en profite!
C'est comme ça qu'on en apprend et surtout de ceux qui pratiquent souvent ou depuis longtemps.
Merci encore, en tout cas, julien.


Amiga user for ever...
0
Rejoignez-nous