IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Boucle de récupération de champ POST php en PDO ? [PDO]


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut Boucle de récupération de champ POST php en PDO ?
    Bonjour,

    Voilà je décide de me lancer sur PDO.

    Pour le moment je réadapte mes sites et tout semble fonctionner.

    Je pense avoir bien compris le système.

    Je trouve par contre que niveau écriture cela va allonger mon code.. ouioui je chipote mais bon

    Je cherche une solution pour traiter simplement mes formulaires en POST qui peuvent être a rallonge.

    Pour le moment avec mysql j'utilisais cette fonction qui me faisait gagner pas mal de lignes d'écritures et donc de temps :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(list($champ,$value)=each($_POST)) {  $$champ = mysql_real_escape_stirng(trim($value)); }
    Je souhaite maintenant passer le tout à PDO et donc idéalement avec des requêtes préparées pour bien sécuriser le tout. Le but serait de faire quelque chose dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(list($champ,$value)=each($_POST)) { $sql->bindParam(":$champ", $value); }
    Seulement j'ai une erreur : Invalid parameter number: number of bound variables does not match number of tokens

    J'imagine que le problème vient du fait que tous les éléments en POST sont enregistrés dans l'objet SQL alors que je ne les utilise pas tous ?

    Est-ce possible ? Est-ce bien d'utiliser ce système ? Vaut-il mieux tout saisir ? Comment faites vous avec des formulaires vraiment long... (plus de 50 éléments).

    Du coup second question.. vaut il mieux utiliser les requêtes préparées pour toutes requêtes même les plus simples ?

    Merci.

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    L'interêt d'une requête préparée ne se juge pas en termes de complexité de la requête.
    Tu ne peux effectivement pas "bind" toutes les données de POST.
    Tu peux avoir un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $postvars = array('toto', 'titi');
    foreach ($postvars as $var) {
           $sql->bindParam(":$var", $_POST[$var]);
    }
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut
    Merci pour le retour.

    Ok pour le tableau mais finalement j'ai plusieurs instructions sur les pages de traitement et du coup quoi qu'il arrive j'aurai plusieurs objet $sql donc ingérable.

    Le but de bindParam étant de sécuriser les données tout en spécifiant le type de celle-ci pour ensuite attraper avec catch les erreurs possible, je pense qu'il est finalement mieux de tout saisir non ? sauf si j'ai qu'un objet $sql et que toutes les données sont de mêmes types dans ce cas j'exclue les input qui ne m'intéresse pas dans un tableau.. pour aller plus vite :p

    Et pour un DELETE unique si l'id a supprimer provient d'un formulaire il est mieux de passer via une requête préparée et bindparam/bindvalue que de faire un simple exec ?

    Merci encore.

  4. #4
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 386
    Points : 10 413
    Points
    10 413
    Par défaut
    Nan pdo ça ne rallonge pas, au contraire cela peut te faire gagner beaucoup de temps par rapport à mysql, et en même temps tu gagne en sécurité.

    La voix royale pour simplifier l'écriture est de faire des requêtes préparées et de passer un tableau dans le execute. Petite astuce on peut utiliser aussi la structure tableau pour construire le formulaire, et dans ce cas cela donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?php 
    if(isset($_POST['identifiants'])){
    	try{
    		$sql = "INSERT INTO membres (mail, adresse, tel)  VALUES (:mail, :adresse, :tel)";
    		$query = $connexion->prepare($sql);
    		$query->execute($_POST['user']);
    	}
    	catch (PDOException $e){
    		echo $e->getMessage();// uniquement en développement
    	}
    }
    ?>
    <form action="#" method="post">
        <input type = "submit" name = "identifiants" value = "envoyer"/>
        adresse<input type="text" name="user[adresse]" value="" />
        mail<input type="text" name="user[mail]" value="" />
        tel<input type="text" name="user[tel]" value="" />   
    </form>

    Après rien ne t'empêche de compléter le tableau (ou de contrôler ses éléments)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php 
    if(isset($_POST['identifiants'])){
            $user = $_POST['user'];
            $user['droits'] = 1;
    	try{
    		$sql = "INSERT INTO membres (mail, adresse, tel, droits)  VALUES (:mail, :adresse, :tel, :droits)";
    		$query = $connexion->prepare($sql);
    		$query->execute($user);
    	}
    	catch (PDOException $e){
    		echo $e->getMessage();// uniquement en développement
    	}
    }
    ?>
    Quand même plus simple qu'avec mysql, non ?

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut
    Bonjour,

    Merci pour la réponse

    Oui à priori je vais gagner en temps d'exécution surtout pour les requêtes qui se répètent. Pour le moment j'avance sur des requêtes unique donc en terme de saisi je trouve cela plus long.

    Avant j'avais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <?php
    // l'id est récupérédans une boucle de Post
    while(list($champ,$value)=each($_POST)) { $$champ = htmlspecialchars(trim($value)); }
    $sql = mysql_query("DELETE FROM ma_base WHERE id='$id'");
     
    // UN autre exemple
    $select_id_process = mysql_query("SELECT * FROM doc ORDER BY id_process DESC LIMIT 0,1");
    ?>
    Et maintenant j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <?php
    // l'id est récupérédans une boucle de Post
    while(list($champ,$value)=each($_POST)) { $$champ = (trim($value)); }
    $delete = $pdo->prepare("DELETE FROM ma_base WHERE id=:id"); 
    $delete->bindPAram(':id',$id);
    $delete->execute();
     
    // Conversion de l'autre exemple
    $select_id_process = $pdo->prepare("SELECT * FROM doc ORDER BY id_process DESC LIMIT 0,1");
    $select_id_process->execute();
    ?>
    Donc un chouille plus long en terme d'écriture.. ici on n'a qu'une valeur à récupérer mais quand il s'agit d'un long formulaire je peux en effet appliquer le tableau qui est une très bonne idée.

  6. #6
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 386
    Points : 10 413
    Points
    10 413
    Par défaut
    Dans quasiment dans tous les cas tu peux gagner une ligne en évitant le bindParam (comme montré dans mes exemples) en passant un tableau dans le execute.

    Et puis avec ta première syntaxe mysql tu as une faille de sécurité (injection sql possible dans ton delete).

  7. #7
    Membre confirmé Avatar de rikemSen
    Homme Profil pro
    Analyste Développeur Web - Fizzup.com
    Inscrit en
    Décembre 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Analyste Développeur Web - Fizzup.com
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 387
    Points : 540
    Points
    540
    Par défaut
    Bonjour,

    Je ne vais pas répondre directement au problème mais juste souligner un petit truc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php
    // l'id est récupérédans une boucle de Post
    while(list($champ,$value)=each($_POST)) { $$champ = (trim($value)); }
    $delete = $pdo->prepare("DELETE FROM ma_base WHERE id=:id"); 
    $delete->bindPAram(':id',$id); // <----- bindParam(':id',$id, PDO::PARAM_STR); ----- ou ------ bindParam(':id',$id, PDO::PARAM_INT);
    $delete->execute();
     
    // Conversion de l'autre exemple
    $select_id_process = $pdo->query("SELECT * FROM doc ORDER BY id_process DESC LIMIT 0,1"); // on passe de "prepare" à "query"
    //$select_id_process->execute();// inutile en cas de requête sans données utilisateur ou paramètre
    ?>
    Si ce que tu as à dire n'est pas plus beau que le silence, alors tais toi.

    - Pensez à voter pour les messages qui vous ont été utiles ainsi que de mettre

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut
    @ABCIWEB Oui pas de soucis j'aurai bien mi un mysql_real_escape_string dans mon code La je l'ai saisi à la va vite...

    @rikemSen je peux donc utiliser query pour une requête de type selection simple sans paramètre top ! Même si finalement j'utilise des données figées comme par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <?php
    $id // Provient de la base.. je ne mets pas le fetch + PDO:FETCH_OBJ complet)
    $sql = $pdo->query("SELECT * FROM membres WHERE inscription='2015-02-12'");
    ?>
    & idem si je fais un insert figé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <?php
    $id // Provient de la base.. je ne mets pas le fetch + PDO:FETCH_OBJ complet)
    $sql = $pdo->exec("INSERT INTO membres(id)VALUES(:id)");
    ?>
    Oui j'utilise bindPAram pour ensuite pouvoir paramétrer le type de données pour après rapporter ou non une erreur.

    J'ai 3 jours de PDO et je crois que m'en sors bien merci pour vos conseils

    Par contre pour le moment en comparaison de mysql_query de base pour toutes les opérations & pdo je ne trouve pas que PDO soit vraiment plus rapide. Je mets à jour des scripts importants (>1000 lignes) combinant des insert/update/delete nombreux quotidiens > 5000 & je vois pas tellement de différence de rapidité pour le moment... Au niveau du chronométrage du timing c'est assez kifkif..

  9. #9
    Membre confirmé Avatar de rikemSen
    Homme Profil pro
    Analyste Développeur Web - Fizzup.com
    Inscrit en
    Décembre 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Analyste Développeur Web - Fizzup.com
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 387
    Points : 540
    Points
    540
    Par défaut
    L'intérêt de PDO n'est pas à sa rapidité mais à sa couche d'abstraction d'accès aux données; il fonctionne avec plusieurs SGBDR tandis que mysql(i)_ est pour .... Mysql .

    Tu peux passer par query oui du moment qu'il y a pas d'entrée utilisateur.
    Si ce que tu as à dire n'est pas plus beau que le silence, alors tais toi.

    - Pensez à voter pour les messages qui vous ont été utiles ainsi que de mettre

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut
    Super ! Sujet résolu.

    Merci à tous

  11. #11
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 386
    Points : 10 413
    Points
    10 413
    Par défaut
    Citation Envoyé par gyllom Voir le message
    Oui j'utilise bindPAram pour ensuite pouvoir paramétrer le type de données pour après rapporter ou non une erreur.


    Par contre pour le moment en comparaison de mysql_query de base pour toutes les opérations & pdo je ne trouve pas que PDO soit vraiment plus rapide. Je mets à jour des scripts importants (>1000 lignes) combinant des insert/update/delete nombreux quotidiens > 5000 & je vois pas tellement de différence de rapidité pour le moment... Au niveau du chronométrage du timing c'est assez kifkif..
    1/ J'aimerais bien savoir comment tu compte rapporter une erreur de type avec le bindParam ? T'as un exemple de code ?

    2/ Je parlais plus haut de rapidité d'écriture. En même temps tu gagne en sécurité et portabilité.
    Et l'autre intérêt des requêtes préparées c'est qu'on y gagne aussi en temps d'exécution quand on fait une requête dans une boucle. Par contre faudrait ne pas mettre la préparation de ta requête à l'intérieur de ta boucle (cf ton code), sinon tu perds tout l'intérêt en termes de rapidité d'exécution et cela devient même plus long.

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut
    @ABCIWEB

    1/ Mauvaises expressions utilisées.. plus un terme de controle du type de données

    2/ Pas de soucis il est en dehors de ma boucle

    Merci

  13. #13
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 386
    Points : 10 413
    Points
    10 413
    Par défaut
    1/ Pas mieux pour un contrôle. Tu ne contrôle rien avec un bindParam d'ailleurs tu peux faire le test d'envoyer un "string" comme variable dans un bindParam avec PARAM_INT, tu verras que tu ne récupéreras pas d'erreur même dans un bloc try/catch.
    Et comme de toutes façons le type sera imposé par celui que tu auras défini dans ta bdd, le fait de passer un tableau dans le execute() aura le même résultat. Plus d'informations ici.
    Si tu veux contrôler tes variables pour intercepter une erreur de type il faut le faire en php avant de faire ta requête.


    2/ Ah oui j'ai lu trop vite. En fait tu ne fais pas de requête multiples. Mais souviens toi de ce que j'ai dit pour le jour où tu auras besoin de faire des requêtes multiples car c'est une erreur de débutant qu'on voit souvent (et dans ce cas on perd en performance).

  14. #14
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2012
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2012
    Messages : 48
    Points : 29
    Points
    29
    Par défaut
    Il est vrai que si je zappe bindparam je gagne en code..

    Si je passe tout dans un array au moment du execute niveau sécurité injection sql cela revient au même ? J'étais pour le moment quasi incollable niveau sécurité donc cela doit durer.. Execute est fonctionnel pour tous types de données ?

    Pour exemple j'ai des variables qui par moment peuvent être vide. Avec un bindParam cela ne fonctionne pas par contre cela fonctionne avec un bindValue. Aucun soucis de ce côté avec execute() ?

    Yes je contrôle en PHP.

    En fait je fais un paquet de requêts multiples mais pas ici :p mais merci

  15. #15
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    bindparam lie la variable à la requête ; sa valeur n'est prise en compte qu'au moment de l’exécution
    bindvalue lie la valeur directement.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [8] Récupération valeur champs type file créer en flash avec PHP
    Par sooprano dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 21/04/2011, 13h06
  2. Récupération des champs dynamique js en php
    Par sfarouk dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 12/03/2011, 17h48
  3. php et récupération des champs du formulaire
    Par kadiato dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 12
    Dernier message: 07/05/2009, 16h45
  4. [AJAX] [AJAX/PHP] récupération de paramètres POST
    Par TheLostMind dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/12/2008, 08h08
  5. [PHP-JS] Récupération de champs après onchange
    Par didi dans le forum Langage
    Réponses: 6
    Dernier message: 03/05/2008, 09h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo