Calcul de l'IMC en PHP

Salut à tous ! :slt:



Je vous expose mon problème : mon professeur d’informatique m’a demandé de réaliser un système de calcul de l’IMC.



Il doit se composer d’un formulaire qui demande le prénom, la taille et le poids.

Ensuite, tout doit s’afficher proprement sous forme de tableau.



On m’a filé Dreamweaver 8 et Wamp ( qui sont installés ), et à partir de là je dois me démerder … :pff:



J’ai donc appris le php par mes moyens grâce aux informations trouvées sur le net, et surtout grâce au site du zero.



Pour l’instant, je dispose d’un fichier imc.php qui contient le code suivant :


[code]

Devoir IMC



Système de détermination de l’IMC et de la corpulence



Entrez les données suivantes :





Entrez votre prénom :


Entrez votre taille (sous la forme 1.70) :


Entrez votre poids (en kilos) :






<?php

if(isset($_POST[‘valider’])){

$prenom=$_POST[‘prenom’];

$taille=$_POST[‘taille’];

$poids=$_POST[‘poids’];



$imc=$poids/($taille*$taille);



echo 'Bonjour '.$prenom.‘


Votre IMC (indice de masse corporelle) est exactement : ‘.$imc.’
’;



if ($imc<16.5){

$verdict=‘Vous êtes en dénutrition.’;

}

elseif ($imc<18.5){

$verdict=‘Vous êtes maigre.’;

}

elseif ($imc<25){

$verdict=‘Vous avez une corpulence normale.’;

}

elseif ($imc<30){

$verdict=‘Vous êtes en surpoids.’;

}

elseif ($imc<35){

$verdict='Vous êtes en état d\‘obésité modérée.’;

}

elseif ($imc<40){

$verdict='Vous êtes en état d\‘obésité sévère.’;

}

else{

$verdict='Vous êtes en état d\‘obésité massive.’;

}



echo $verdict;

}

?>


[/code]
Et après, je dois faire quoi ? Et comment voir si le code fonctionne ? :/

bah tu lances ton fichier avec un serveur lamp/wamp/mamp (donc tu le met dans le répertoir où le serveur va voir (sur mac : /Application/MAMP/httpdocs/ sous linux c’est /var/www il me semble, windows je ne sais plus)



ensuite ton fichier marche bien, mais perso j’aurai fait different



Genre :

[code]

Devoir IMC



Système de détermination de l’IMC et de la corpulence



<?php if(!isset($_POST['valider'])){ ?>

Entrez les données suivantes :





Entrez votre prénom :


Entrez votre taille (sous la forme 1.70) :


Entrez votre poids (en kilos) :






<?php

}else{

$prenom=$_POST[‘prenom’];

$taille=$_POST[‘taille’];

$poids=$_POST[‘poids’];



$imc=$poids/($taille*$taille);



echo 'Bonjour '.$prenom.‘


Votre IMC (indice de masse corporelle) est exactement : ‘.$imc.’
’;



if ($imc<16.5){

$verdict=‘Vous êtes en dénutrition.’;

}

elseif ($imc<18.5){

$verdict=‘Vous êtes maigre.’;

}

elseif ($imc<25){

$verdict=‘Vous avez une corpulence normale.’;

}

elseif ($imc<30){

$verdict=‘Vous êtes en surpoids.’;

}

elseif ($imc<35){

$verdict='Vous êtes en état d\‘obésité modérée.’;

}

elseif ($imc<40){

$verdict='Vous êtes en état d\‘obésité sévère.’;

}

else{

$verdict='Vous êtes en état d\‘obésité massive.’;

}



echo $verdict;

}

?>


[/code]
je cache donc le formulaire si $_POST existe pour afficher le résultat (tu peux ne pas être d'accords avec ce fonctionnement)
ensuite moi je testerai les entrées utilisateurs (même si là c'est qu'un simple calcul, ne jamais croire l'utilisateur !) donc :
[code]if(!empty($_POST['prenom'])){
$prenom=$_POST['prenom'];
}else{
echo 'vous n'avez pas rentré de prénom';
}[/code]
pour les "chiffres" j'aurai demander une taille en centimètre et pas en mètre (histoire d'avoir un entier ^^)

dans les deux cas ce code devrai marché (forme 1.XX ou 1,XX je ne sais pas)
[code]if(is_numeric($_POST['taille'])){
$taille=$_POST['taille'];
}[/code]
D'après moi c'est le programmeur qui doit prévoir tout les cas pour l'utilisateur... et pas à l'utilisateur de s'adapter a un programme mal fait :
[code]if(is_numeric($_POST['taille'])){
if(stripos($_POST['taille'], '.')||stripos($_POST['taille'], ',')){
$taille=$_POST['taille'];
}else{
$taille=$_POST['taille']/100;
}
}[/code]
Donc là on test si la taille est en mètre (avec virgule ou point) ou en centimètre et en centimètre, on convertit en mètre :p

pour le poids, un "is_numeric" en test serai pas mal aussi

Pour le prénom, on peu éviter tout les caractères qui feraient chier avec un "htmlspecialchars()"

de plus, j'aurai séparer le form et l'affichage du résultat dans des fichiers différant (histoire de s'entrainer un peu, et comme ça si l'application prend en ampleur, tu gardes un code bien séparer :p

voila je t'ai donner des conseils et des "bonnes pratique" et quelques truks à adapté toi même, de quoi t'amuser :)

Bon finalement je me suis amuser un peu avec ton code pendant 30petites minutes xD

Alors premier point, tu avait oublier de précisez l’encodage dans le head je l’ai rajouter avant le titre.

Deuxième point, j’ai utiliser le bootstrap tweeter, un moyen très simple de rendre la page plus jolie (par contre la nouvelle version met 3plombes à charger chez moi, faudrait l’avoir en local ;))



après tu remarqueras l’utilisation de html5/css3 pour me la pèter aussi (faut que tu apprennes à utiliser les nouveautés aussi ^^)

alors pour le css, utilisation de des ombres porté(=box-shadow), utilisation des nouveauté pour définir des couleurs différentes en fonction de l’état du formulaire (:invalide, :valid, :focus) et pour exclure une classe (le bouton submit qui était toujours valid et qui avait une ombre sous chrome)



ensuite en html normal, tu avait oublier les labels, c’est plus propre ainsi !

j’ai modifier les input pour les rendre conforme html5 (on faire pas les balises style input, br, img,… qui n’ont pas deux parties), j’ai mis un place holder (texte qui s’affiche quand le champs est vide), j’ai définit le type de la taille et du poid en temps que nombre avec un “pas” en centième pour la taille (on veux des mètres)

Faut garder à l’esprit que les vérifications de formulaire coté client, c’est pas sécurisé du tout, mais c’est userfriendly (donc il n’y aura que les hackeurs qui verront les messages renvoyer par le serveur php en théorie), donc on garde les vérifications en php aussi :wink:



Donc la correction des tests php aussi, mais que tu ne pourras pas tester avec un navigateur récent puisqu’ils interprèteront le html5 ^^




[code]





Devoir IMC









label{

display: inline;

}

input{

height: 28px;

}

input:invalid{

border-color: #953b39;

-webkit-box-shadow: 0 0 6px #d59392;

-moz-box-shadow: 0 0 6px #d59392;

box-shadow: 0 0 6px #d59392;

}

input:valid:not(.btn){

border-color: #356635;

-webkit-box-shadow: 0 0 6px #7aba7b;

-moz-box-shadow: 0 0 6px #7aba7b;

box-shadow: 0 0 6px #7aba7b;

}

input:focus, textarea:focus {

border-color: rgba(82, 168, 236, 0.8);

-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

outline: 0;

outline: thin dotted \9;

/* IE6-8 */

}







Système de détermination de l’IMC et de la corpulence




<?php if(!isset($_POST['valider'])){ ?>

Entrez les données suivantes :



Entrez votre prénom :

Entrez votre taille (sous la forme 1.70) :

Entrez votre poids (en kilos) :




<?php
}else{
$prenom=$_POST['prenom'];
if(is_numeric($_POST['taille'])){
if(stripos($_POST['taille'], '.')||stripos($_POST['taille'], ',')){
$taille=$_POST['taille'];
}else{
$taille=$_POST['taille']*100;
}
}else{
echo 'mauvaise taille';
}
if(is_numeric($_POST['poids'])){
$poids=$_POST['poids'];
}

$imc=$poids/($taille*$taille);

echo 'Bonjour '.$prenom.'

Votre IMC (indice de masse corporelle) est exactement : '.$imc.'
';

if ($imc<16.5){
$verdict='Vous êtes en dénutrition.';
}
elseif ($imc<18.5){
$verdict='Vous êtes maigre.';
}
elseif ($imc<25){
$verdict='Vous avez une corpulence normale.';
}
elseif ($imc<30){
$verdict='Vous êtes en surpoids.';
}
elseif ($imc<35){
$verdict='Vous êtes en état d\'obésité modérée.';
}
elseif ($imc<40){
$verdict='Vous êtes en état d\'obésité sévère.';
}
else{
$verdict='Vous êtes en état d\'obésité massive.';
}

echo $verdict;
}
?>

[/code]

Salut, déjà merci pour ton aide et tes conseils !

Je n’ai pas encore eu le temps de me pencher la dessus depuis mon post. Je testerai tout ça tout à l’heure et je te dis quoi :wink:

Par contre pour le rendu, ne met pas le bootstrap tweeter et le html5, si c’est pas quelque chose vu en cours, le proff va penser à la tricherie à cause de ça :stuck_out_tongue:



De même comprend bien qu’il faut toujours tout vérifier et maitriser les tests conditionnels ^^

PHP propose des fonctions simplifiant les tests genre pour les prénoms ma première idée était de tester avec une regex, alors qu’un htmlspecialchars évitera l’injection de code même s’il n’offre pas la souplesse d’une regex, il serai suffisant.



Pour les nombres, je vérifis que c’est bien des nombres, et en html5, j’utilise des fonctions pour forcé l’utilisateur à envoyer les données sous la bonne forme, mais faut toujours faire une deuxième vérification côté serveur.



Je me répète, mais voila la sécurité c’est primordial, c’est tellement simple de laisser des failles… (le deuxième point important est de fournir un code W3C compliant ^^)

Bonjour,

:lol: le site du zéro, la bible pour un programmer les exos d’école. C’était la même chose pour moi en C++ comme la prof n’aidait guère. Mon dernier programme en C++ était une gestion d’outils à partir de fichiers, 10 h 30 de boulot pou arriver à un truc fonctionnel. Ce qui me fait bien rire, tu as ton fichier programme avec les questions, un collègue te recopie intégralement une question, toi cela marche, le collègue, cela veut jamais marcher (même en Ctrl+c, ctrl+v).

Bon courage.

Salut ! Merci toto63 pour tes encouragements :wink:



En fait, en cours on a rien vu du tout, c’était par le biais de formations en ligne (juste l’HTML et le CSS). On a juste eu des cours de C …



Je ne sais pas me servir de Dreamweaver et Wamp. Je ne sais donc pas comment tester mes fichiers. J’ai placé mon “imc.php” dans le dossier "www"

EDIT : J’ai trouvé pour tester les fichiers; localhost puis choix du fichier :smiley:



Je vais bosser sur l’affichage et sur le test des variables et tout ça, comme tu me l’a conseillé !



EDIT : Apparemment j’ai un petit problème d’encodage ? [Résolu avec Notepad]



Aussi, en testant ton code, j’ai remarqué que seuls les résultats étaient affichés après avoir envoyé le données. ( Le formulaire n’est plus là, ce qui pousse l’utilisateur à cliquer sur précédent. Y aurait-il un moyen de créer un bouton “retour” ? Dans le genre qui renvoie à la page imc.php initiale ( vide de données, donc sans les informations dans les cases ) ?

pour le problème d’encodage, c’est dans ton éditeur de code, il faut que tu convertisse le fichier en UTF-8 qui est la norme utiliser maintenant ^^



pour le bouton précédant, il faut simplement mettre un lien vers la même page, comme tu n’enverra pas de données en POST, le <?php if(!isset($_POST['valider'])){ ?> sera faux donc vrai et affichera donc le formulaire



dans ton cas : Précédant (la classe pour garder le même style graphique pour tout les boutons ^^)

Merci pour ton aide ! Je me demandais s’il y avait moyen de mettre une image de fond, sans utiliser de CSS, avec CSS 3 ? Tu n’aurais pas un pitit lien pour que je me mette un peu à jour ? ( par exemple un lien qui explique le kit que tu as mis dans ton code ) :wink:



EDIT : Pour l’image de fond, c’est fait. Sinon pour le bouton “Précédent”, je dois le mettre ou au niveau de mon code ? Il fonctionne, mais n’est pas “stylisé”. Il est présent aussi avant l’envoi des informations, ce que je ne veut pas.



Aussi, quand j’utilise une virgule au lieu du point au poids et à la taille, j’obtiens des erreurs.



Voici mon code actuel :

[code]





Devoir - Calcul de l’IMC









label{

display: inline;

}

input{

height: 28px;

}

input:invalid{

border-color: #953b39;

-webkit-box-shadow: 0 0 6px #d59392;

-moz-box-shadow: 0 0 6px #d59392;

box-shadow: 0 0 6px #d59392;

}

input:valid:not(.btn){

border-color: #356635;

-webkit-box-shadow: 0 0 6px #7aba7b;

-moz-box-shadow: 0 0 6px #7aba7b;

box-shadow: 0 0 6px #7aba7b;

}

input:focus, textarea:focus {

border-color: rgba(82, 168, 236, 0.8);

-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

outline: 0;

outline: thin dotted \9;

}



body {

background-image: url(images/bg.jpg);

background-repeat: repeat;

}











Système de détermination de la corpulence




<?php if(!isset($_POST['valider'])){ ?>

Veuillez entrer les données suivantes :




Entrez votre prénom :

Entrez votre taille :

Entrez votre poids :




<?php
}else{
$prenom=$_POST['prenom'];
if(is_numeric($_POST['taille'])){
if(stripos($_POST['taille'], '.')||stripos($_POST['taille'], ',')){
$taille=$_POST['taille'];
}
else{
$taille=$_POST['taille']*100;
}
}else{
echo 'mauvaise taille';
}
if(is_numeric($_POST['poids'])){
$poids=$_POST['poids'];
}

$imc=$poids/($taille*$taille);

echo 'Bonjour '.$prenom.'

Votre indice de masse corporelle est de : '.$imc.'
';

if ($imc<16.5){
$verdict='Vous êtes en dénutrition.';
}
elseif ($imc<18.5){
$verdict='Vous êtes maigre.';
}
elseif ($imc<25){
$verdict='Vous avez une corpulence normale.';
}
elseif ($imc<30){
$verdict='Vous êtes en surpoids.';
}
elseif ($imc<35){
$verdict='Vous êtes en état d\'obésité modérée.';
}
elseif ($imc<40){
$verdict='Vous êtes en état d\'obésité sévère.';
}
else{
$verdict='Vous êtes en état d\'obésité massive.';
}

echo $verdict;
}
?>
Précédent


[/code]
(L'image de fond ne va pas s'afficher étant donné qu'elle est dans un dossier)

pour le bootstrap twitter : http://twitter.github.com/bootstrap/

Pour le code du bouton que je t’ai passer, met le n’importe où dans ton code hors Php, mais le mieux c’est de le mettre en bas de page donc à la fin du html, mais avant la fermeture du else php (pour évité qu’il s’affiche à l’affichage du form) donc juste après :

echo $verdict;

pour l’image de fond, tu peux utilisé background-image (ou background) en css sur le body, le css3 ne change rien pour ça :stuck_out_tongue:

Merci pour le lien !

Mon background fonctionne, y’a pas de soucis.



Mes problèmes actuels sur lesquels je travaille sont :


  • Le bouton “Précédent” n’a pas l’apparence du bouton “Valider”.



    - Les virgules qui ne sont pas acceptées pour la taille et le poids.

    [h=#FFFF99]$_POST[‘taille’] = preg_replace("#,#", ‘.’, $_POST[‘taille’]);[/h]


  • Quand une valeur non convenable est entrée ( par exemple “Bonjour” au lieu d’une taille correcte ), une erreur s’affiche quand même.



    Et j’ai remarqué qu’il y avait une erreur dans ton code, dans la condition de taille :

if(is_numeric($_POST['taille'])){<br /> if(stripos($_POST['taille'], '.')||stripos($_POST['taille'], ',')){<br /> $taille=$_POST['taille'];<br /> }else{<br /> $taille=$_POST['taille']/100;<br /> }

Il faut faire /100 et non *100 :wink:

Fait le en Js :smiley:

le bouton précédant à quelle apparence s’il a juste l’apparence d’un lien, c’est pas normal, s’il est juste pas de la même couleur, rajoute lui la class success



alors j’ai fait un petit “hack” sur la condition pour éviter d’écrire un message si le calcul à échouer

ensuite c’est “class” et pas “classe” dans le lien pour précédant…



j’avais pas mis de “else” pour le test de poids donc de message d’erreur

ensuite, j’ai changer ta gestion de l’affichage des résultats, on stock tout en variable puis on print à la fin (por faire suite à mon “hack”, il vide la variable pour éviter d’afficher quelque chose s’il y a eu une erreur)



et je croit que c’est tout ce que j’ai changer :slight_smile:

[code]





Devoir - Calcul de l’IMC









label{

display: inline;

}

input{

height: 28px;

}

input:invalid{

border-color: #953b39;

-webkit-box-shadow: 0 0 6px #d59392;

-moz-box-shadow: 0 0 6px #d59392;

box-shadow: 0 0 6px #d59392;

}

input:valid:not(.btn){

border-color: #356635;

-webkit-box-shadow: 0 0 6px #7aba7b;

-moz-box-shadow: 0 0 6px #7aba7b;

box-shadow: 0 0 6px #7aba7b;

}

input:focus, textarea:focus {

border-color: rgba(82, 168, 236, 0.8);

-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

outline: 0;

outline: thin dotted \9;

}



body {

background-image: url(images/bg.jpg);

background-repeat: repeat;

}











Système de détermination de la corpulence




<?php if(!isset($_POST['valider'])){ ?>

Veuillez entrer les données suivantes :




Entrez votre prénom :

Entrez votre taille :

Entrez votre poids :




<?php
}else{
$prenom=$_POST['prenom'];
if(is_numeric($_POST['taille'])){
if(stripos($_POST['taille'], '.')||stripos($_POST['taille'], ',')){
$taille=$_POST['taille'];
}
else{
$taille=$_POST['taille']/100;
}
}else{
echo 'mauvaise taille';
}
if(is_numeric($_POST['poids'])){
$poids=$_POST['poids'];
}

$imc=$poids/($taille*$taille);
$verdict = 'Bonjour '.$prenom.'

Votre indice de masse corporelle est de : '.$imc.'
';
if(empty($imc)){
$verdict = '';
}elseif ($imc<16.5){
$verdict.='Vous êtes en dénutrition.';
}
elseif ($imc<18.5){
$verdict.='Vous êtes maigre.';
}
elseif ($imc<25){
$verdict.='Vous avez une corpulence normale.';
}
elseif ($imc<30){
$verdict.='Vous êtes en surpoids.';
}
elseif ($imc<35){
$verdict.='Vous êtes en état d\'obésité modérée.';
}
elseif ($imc<40){
$verdict.='Vous êtes en état d\'obésité sévère.';
}
else{
$verdict.='Vous êtes en état d\'obésité massive.';
}

echo $verdict.'
';
echo 'Précédent';
}
?>


[/code]

@Hypijump : Je ne peux pas :wink:



@Dagda-Esus : Pour le bouton c’est réglé ! En effet il y avait ce petit “e” qui merdait tout :smiley:



J’ai réécrit tout mon code et tout fonctionne ! Je me pose juste deux questions :


  • Y’a t’il un moyen de donner aux phrases de $Verdict un style bien précis ? Dans le genre italique et gras.
  • Comment puis-je masquer les erreurs de wamp ? Ce quand une variable est incorrecte par exemple.

[HS ON]


[quote name=toto63]un collègue te recopie intégralement une question, toi cela marche, le collègue, cela veut jamais marcher (même en Ctrl+c, ctrl+v).[/quote]

ca s’appelle une fuite memoire…



[HS OFF]

moi ça s’affiche pas mais bon c’est une mauvaise gestion des erreurs là encore ^^

enfaite là il veux utiliser la variable “$poids” qui n’est pas définit pour un calcul… il n’y arrive pas donc te le dit :stuck_out_tongue:



soit tu fais un test conditionnel à l’arrache autour du calcul de l’imc avec 1 condition par erreur (c’est moche, pas pratique et long ^^) soit tu définit une variable $erreur=0; en début de code, pour chaque erreur tu fais un “$erreur++;” (tu incrémentes la variable erreur) et donc autour du calcul tu mais un “if($erreur==0)” et là ça te permet de te passer de mon hack puisque le “if” pourrait encadrer tout les elseif… (et là j’ai la flemme de te faire le code mais avec ce qu’il y a entre guillemets, tu pourrais te débrouiller :))



ah oui et au dessus j’ai remonté le bouton “précédant” pour qu’il soit dans la condition, fallais le mettre dans un echo (tu remarqueras que quand je te donne des solutions, je ne te donne pas la solution complète et que tu doit réfléchir pour l’implémenter justement pour que tu apprennes :p)



Sinon pour les erreurs faudrait rajouter un “
” en fin de ligne aussi… voir utiliser le bootstrap pour signaler que c’est des erreurs telque :

if(is_numeric($_POST['poids'])){<br /> $poids=$_POST['poids'];<br /> }else{<br /> echo '<span class="label label-important">mauvaise poids</span><br>';<br /> $erreur++;<br /> }

@Arkh Véridique :smiley:



( Heureusement je suis pas du genre à copier :wink: )



@Dagada-Esus



Mon code est fini en fait :cool:



Quand je parle d’erreur, je veut parler du grand rectangle provenant de Wamp je suppose !



Et sinon je me demandais si par le biais du CSS il y avait moyen d’attribuer un style au texte de $Verdict plutot que de mettre Texte



EDIT : Ce truc là …



oui, il te dit que la variable $poids utiliser dans le calcul n’est pas définit, donc faut sauter le calcul si tu as des “erreurs” dans les entrées utilisateur c’est ce que je t’expliquais



ensuite, non il n’y a pas de moyens d’écrire du html sans balises, il va falloir t’y faire :stuck_out_tongue:

Pour éviter de répéter les et les et donc formater manuellement tout ton site tu peux définir un style pour les balises (par exemple

,

…) dans ton css et y coller le format souhaité. De cette facon il suffira de changer le contenu du css pour modifier l’aspect de tout ton site :smiley:



Edit: Bon, si j’avais lu tout le post au lieu des 3 derniers commentaires j’aurais surement vu que le sujet avait été traité… :chant: -> Désolé

@Patou : Merci quand même :wink:



@Dagda : Tu as une idée de comment je peux “bypass” le calcul ? Un script dans la condition “else” ?