[PHP] Construire nom variable pour travail sur grand nombre de champs

Construire nom variable pour travail sur grand nombre de champs [PHP] - PHP - Programmation

Marsh Posté le 04-01-2008 à 16:46:35    

Mesdames, Messieurs,
 
Tout d'abord une bonne année et un grand merci à ceux qui pourront m'aider.
 
 
Je débute en PHP / MySQL et cherche à remplir ma base de donnée via un formulaire que j'ai créé de mes petites mains. Pour resituer mon projet, ma base contient une quarantaine de champs qui vont devoir être mis à jour ou créer à partir du formulaire.
 
Pour faire simple, on va se baser sur un exemple plus petit : un table appelée "test" et cinq champs "id", "nom", "sexe", "annee", "ville".
 
Pour créer un contact, il faut donc :
 
1. remplir les champs,
2. envoyer l'information
3. récupérer les valeurs des variables $_POST dans des variables
4. générer la requete
(au début je l'avais fait sans l'étape 3 mais SQL n'arrivait pas à gerer les $_POST)
 
Ca donne un truc du genre :
 
A. le formulaire s'occupe des étapes 1 et 2
B. l'étape 3 consiste à faire du $nom = $_POST_['nom']; pour chaque champ
C. la requète doit être du type mysql_query ("INSERT INTO test VALUES '','$nom','$sexe','$annee','$ville') // Le champ id est en auto_increment.
 
Mais c'est un peu compliqué à faire à la main, surtout quand le nombre de champ dépasse les 10.
 
J'aimerais donc avoir une fonction qui reconstitue ces deux étapes :
 
I. $var = $_POST['var'] et boucle en faisant changer var en "id", "nom", ...
II. créer la requete (avec les apostrophe et virgule qui vont bien) en utilisant ces variables
 
Merci pour vos lumières.

Reply

Marsh Posté le 04-01-2008 à 16:46:35   

Reply

Marsh Posté le 04-01-2008 à 16:58:40    

c'est pas une bonne idée ce que tu veux faire ...  
Ecrire 10 champs c'est pas ça qui prend du temps.
 
Par contre tu devrais lire cet article: http://fr2.php.net/security.database

Reply

Marsh Posté le 04-01-2008 à 16:59:10    

PS :
 
J'arrive à faire une boucle pour extraire de ma base le nom de mes champs, ca donne :  
 
// Liste des champs
$listechamp = mysql_query("DESCRIBE test" );
 
// Boucle
while ($liste = mysql_fetch_array($listechamp))
{
  echo $liste['Field'].'<br />';
}
 
Le résultat est :
id
nom
annee
sexe
ville
 
Mais je n'arrive pas à créer mes variables, à faire un truc du genre :  
 
$nom = "Christophe";
$var = "nom";
echo '$'.$var;
 
Afficherait : Christophe


Message édité par jdubots le 04-01-2008 à 17:00:23
Reply

Marsh Posté le 04-01-2008 à 17:02:55    

Si tu peux faire des $var = $_POST['var'] pour récupérer le contenu de $_POST['var'], pourquoi tu ne peux pas utiliser directement les $_POST pour créer la requête? Du haut de mes 7 ans d'expérience, je ne vois que deux choses qui pourrait provoquer la perte du contenu de $_POST :
- la suppression de la variable (unset($_POST) ou unset($_POST['var']) )
- l'écrasement du contenu de la variable ($_POST = 'quelquechose' ou $_POST['var'] = 'quelquechose' )
 
PS : A noter que $_POST est une superglobale qui est disponible partout donc il n'y a pas besoin de faire un global($_POST) pour pouvoir y accéder.
 
PS2 : Que tu utilises  $var ou $_POST['var'] , n'oublie pas de neutraliser le contenu des variables sinon c'est la porte ouverte aux problèmes (attaque par "SQL injection" )

Reply

Marsh Posté le 04-01-2008 à 17:06:06    

Moi je continue à te dire que ça sert à rien ton truc et que c'est pas une bonne idée :o
Le jour ou tu ajouteras un champs dans ta table ( et pas dans ton formulaire pour une raison x ou y), ton truc se plantera lamentablement [:spamafote]
 
Si tu y tiens absolument, utilise le tableau post comme conseiller par omega2

Reply

Marsh Posté le 04-01-2008 à 17:43:29    

jdubots > Au vu de ce que t'as posté pendant que je saisissais ma réponse, je me dois de te signaler quelques trucs pour que tu puisses reprendre ou continuer sur de meilleures bases :

  • Une base de donnée est faite pour stocker et gérer des données, pas pour forcer les programmes à agir d'une manière donnée (ce que toi tu essayes de faire)
  • Un script ou un programme est seul maitre à bord, il n'est pas là pour servir de matelot sur un canot contrôlé par une base de donnée ou par un formulaire
  • Rien ne dit que les formulaires colleront éternellement de manière exacte à la structure de la table.


Pour te donner une idée des défauts de ta façon de faire, je vais te donner trois exemples qui te poseront problème :
1) Imagine toi que plus tard tu veuilles sauvegarder des photos des personnes. Tu vas donc créer une table contenant les photos. Maintenant si tu veux permettre l'envoie d'une photo quand tu crées une nouvelle personne ... tu ne peux pas le faire vu que ta table des personnes ne connait pas les photos et que ton code attend de savoir ce que la table connait pour savoir ce qu'il reçoit (et ignore donc bêtement tout ce que cette table ne connait pas)
2 ) Au bout de quelques années, tu te retrouves à devoir stocker, par exemple, la date de décès d'une personne ... oups, le formulaire de création ne contient pas cette donnée et ton code, qui suit bêtement la structure de ta table, râle par ce qu'il ne l'a pas reçu. Pourtant quel intérêt y aurait_il à avoir cette info dans le formulaire?
3) Pour une raison indéterminé, tu décides de stocker également le nombre de visite de chaque personne. Tu le rajoutes dans la table mais avant de mettre à jour le formulaire t'es dérangé dans ton travail et tu oublis de modifier le formulaire. Quand tu testes, tu n'as aucun message d'erreur alors que le formulaire n'envoie pas cette info. Bizarre? Non, c'est juste que t'as une variable dans ton code qui a le même nom que ta nouvelle colonne sans que tu t'en sois rendus compte. Variante : tu modifie bien le formulaire comme il faut mais ne reçoit jamais la valeur que tu as saisie par ce que cette valeur est écrasé par la variable qui existait déjà dans ton code avant le rajout de cette nouvelle colonne.
 
 
Dans le premier cas tu te retrouves à ignorer des données pourtant envoyé, dans le second t'as droit à des erreurs par ce que la table contient des éléments inconnus du formulaire, dans le troisième (et sa variante) , t'as un comportement anormal du à la collision entre les variables du code et les variables correspondant aux colonnes de la table.
 

Reply

Marsh Posté le 04-01-2008 à 18:13:18    

Merci pour ces éclaircissements, ma route en PHP est encore longue.
 
Si je comprends bien vos remarques, ma structure est très figée et nécessite de mettre à jour le formulaire, la query et la structure de la base pour toutes modifications ultérieures. Ma question est alors : que dois-je faire ?
 
Mon projet est de faire une base de données consultable sur mon site. Ces données sont stockées dans une base contenant 48 champs (nom, auteur, date, poids, taille, illustrations, ...).
 
On m'a conseillé, pour remplir et maintenir à jour cette base, de créer un "formulaire d'administration".
 
C'est mon premier formulaire. Si j'ai bien compris, quand on clique sur le bouton "submit", les informations de chaque champ (radio, input, textarea, ...) sont envoyées dans des variables de type $_POST['var'].
 
Grossièrement, je cherche à récupérer ces valeurs et les injectées dans ma table via deux query :
- INSERT INTO table VALUES ... si l'item n'était pas présent dans la base
- UPDATE table SET ... si l'item était présent et a été modifié.
 
J'ai déjà réussi à créer la structure qui vérifie si l'item existe et permet de choisir l'une query ou l'autre. J'ai d'abord essayé d'utiliser directement les $_POST['var'] mais j'avais des erreurs SQL. Après recherche sur le net, le plus simple semblait de les transformer en variable $var et les lister dans la requète. Je l'ai fait pour une base (de test) de 5 champs, mon script fonctionne.
 
Pour 48 champs, c'est plus pénible et je me suis dit que si la base passe un jour à 49, il faudra redéfinir non seulement le formulaire et la base manuellement (je pense que c'est obligatoire) mais aussi la query ! Je voulais "automatiser" cette dernière étape.
 
J'espère que c'est un peu plus clair. J'essaye d'acquérir le bon raisonnement pour bien utiliser ces outils et pas faire des trucs "bidouilles". Comment ferait un pro dans mon cas ?

Reply

Marsh Posté le 04-01-2008 à 18:46:26    

Le bon raisonnement est de toujours considérer le programme comme étant le pilier du traitement et la base de donnée comme le gérant des données.
 
Pour la récupération des données, le programme doit donc dans l'ordre :
- vérifier l'existence des données obligatoire (isset() + éventuellement strlen(trim($_POST['variable'])) s'il faut qu'elle contienne quelque chose)
- vérifier la validité (si tu attends un nombre, alors il faut que ça soit vraiment un nombre) et la non dangerosité des données (ça, ça dépend des données attendus)
- si tout est bon, construire la requête (ou les requêtes) à partir des données reçu en neutralisant celles dont le contenu pourrait poser problème à la base de donnée (pour les chaines de texte et mysql, il faut utiliser mysql_real_escape_string() ou mysqli_real_escape_string()).
 
Je me doute bien que c'est long de construire une requête qui contient 48 champs (bien qu'avec un peu de méthode et quelques copier collé, ça aille assez vite) mais il faut réaliser qu'en fonction des données la neutralisation n'est pas la même et empêche toute automatisation simple :  
- un texte reçu de l'extérieur sera neutralisé à l'aide de mysql_real_escape_string() (ou mysqli_real_escape_string() ) et devra être entouré de ".
- un nombre le sera à l'aide par exemple de intval() ou floatval() (respectivement entier et nombre à virgule flottantes)
- les fonctions de mysql (par exemple now() pour la date/heure courante) , pour leur part, ne doivent pas être modifier.
 
Si t'as eu des erreurs sql, c'est peut être simplement que t'as eu des ' ou des " qui trainait dans une des valeur sans avoir été neutralisé par un mysql_real_escape_string.


Message édité par omega2 le 04-01-2008 à 18:47:55
Reply

Marsh Posté le 06-01-2008 à 18:42:10    

[RESOLU]
 
En fait, j'ai suivi vos conseils et ai oublié mon idée de fonction automatisée. Je suis donc revenu à quelque chose de bien plus simple avec un simple envoi des infos vers la base. Néanmoins, j'ai dû conservé la transformation des variables superglobales ($_POST['var']) en variables standard ($var) car je n'ai pas réussi à faire une requète fonctionnelle avec ces variables (sûrement à cause des apostrophes.
 
Merci encore de votre aide.

Reply

Marsh Posté le 07-01-2008 à 12:11:46    

hum .... par hasard, tu ferais pas des constructions de requêtes en mettant les variables directement dans la chaine de caractère? Si tu fais ça alors c'est normal : "la variable $_POST['var'] est au milieu du texte" est égal à "la variable " . $_POST . "['var'] est au milieu du texte".

Reply

Marsh Posté le 07-01-2008 à 12:11:46   

Reply

Marsh Posté le 08-01-2008 à 18:26:38    

hum... je crois que tu as mis le doigt sur mon souci. En fait, j'ai commencé par tenter la requète suivante :
 
   mysql_query("INSERT INTO table VALUES('', $_POST['nom'], $_POST['annee'])" );
 
et, comme tu sembles t'en douter, ça ne marche pas terrible et renvoi une belle erreur MYSQL.
 
Donc, n'arrivant pas à m'en sortir, j'ai "rusé" en faisant :
 
   $nom = $_POST['nom'];
   $annee = $_POST['annee'];
 
   mysql_query("INSERT INTO table VALUES('', '$nom', '$annee');
 
et ça, ça fonctionne.
 
[edit] : dans ces deux requètes, la première valeur est vide, ce sont deux apostrophes accolés. Je l'ai même remplacé aujourd'hui par VALUES(NULL, '$nom', '$annee'). Cette valeur correspond au champ id, autoincrémenté.
 
D'ailleurs, j'en profite pour faire appel à vos lumières : quelqu'un peut-il me donner quelques détails sur "la durée de vie des variables" ? J'entends par là : quand une variable (normale ou superglobale) est créée (envoi d'un formulaire, affectation valeur "$var = 3;", ...) la fonction isset renvoie la valeur TRUE. Souvent, cette fonction est un critère de choix pour traiter le formulaire, par exemple. En tapant mon code, je me suis demandé "si un visiteur commence par suivre les pages du site, cela défini les variables du formulaire et la page d'arrivée traite ces variables (et éventuellement modifie leur valeur). Si mon visiteur réaccède à la page cible directement (sans passer par le formulaire), est-ce que les variables sont toujours définies ?
 
J'ai lu dans un tutorial que les variables de SESSION sont permanentes, que les super globales sont accessibles de partout, que les autres ne "effacées" après usage : qu'en est-il réellement ?
 
Merci.
 
PS : Pour poster des réponses, le système de saisie est génial et permet de mettre du code "HTML" dans les réponses : comment cela fonctionne ce langage, comment l'intégrer dans un site ? Merci ^^


Message édité par jdubots le 08-01-2008 à 18:31:52
Reply

Marsh Posté le 09-01-2008 à 10:04:04    

pour éviter les erreurs dans tes chaines, concatène les toi même avec des points '.'
 

Code :
  1. $chaine = 'un bout de chaine' . $une_variable . 'la suite de la chaine ' . $_POST['nom'] . 'fin de la chaine';


 
Pour l'insertion, tu peux utiliser  
 

Code :
  1. mysql_query('INSERT INTO test (nom,annee) VALUES("'.$_POST['nom'].'", "'.$_POST['annee'].'" )');


 
pour éviter de mettre une entrée systématiquement à NULL


---------------
oui oui
Reply

Marsh Posté le 09-01-2008 à 13:48:31    

art_dupond a écrit :


Pour l'insertion, tu peux utiliser  
 

Code :
  1. mysql_query('INSERT INTO test (nom,annee) VALUES("'.$_POST['nom'].'", "'.$_POST['annee'].'" )');


 
pour éviter de mettre une entrée systématiquement à NULL


 
$_POST directement dans la requête?  [:delarue5]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 09-01-2008 à 13:58:26    

c'était pour montrer que ça devrait marcher au niveau des ' :o

 


mais tu fais bien de dire que c'est mal :jap:


Message édité par art_dupond le 09-01-2008 à 13:59:05

---------------
oui oui
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed