Partage
  • Partager sur Facebook
  • Partager sur Twitter

bindValue VS bindParam

Pourquoi avoir utilisé bindParam dans ce cas-ci ?

Sujet résolu
    29 février 2016 à 15:50:32

    Bonjour,

    Je suis en train d'étudier un script php d'inscription et connexion à un espace membre (http://www.julp.fr/blog/posts/2-de-bonnes-bases-pour-un-espace-membre) dont voici un extrait:

    <?php
    session_start();
    if (!array_key_exists('id', $_SESSION)) {
        header('Location: connexion.php');
    } else {
        require('shared.php');
    
        $stmt = $bdd->prepare('SELECT * FROM utilisateurs WHERE id = :id');
        $stmt->bindParam('id', $_SESSION['id'], PDO::PARAM_INT);
        $stmt->execute();
        $user = $stmt->fetch();
    
        echo 'Bienvenue ', htmlspecialchars($user['login'], ENT_NOQUOTES);
    }

    J'aimerais comprendre pourquoi on a utilisé ici bindParam et non bindValue ? J'ai cru comprendre qu'il fallait uniquement utiliser bindParam si l'on projetait d'utiliser la requête préparée plusieurs fois (donc si l'on exécute la même requete préparée plusieurs fois en utilisant des paramètres différents... ce qui n'est pas le cas ici). Pourquoi alors dans ce cas-ci avoir utilisé bindParam ? Merci pour votre aide :]

    -
    Edité par BigBenJr 29 février 2016 à 15:50:48

    • Partager sur Facebook
    • Partager sur Twitter
      29 février 2016 à 15:59:03

      Salut,

      Voici le lien à la documentation qui est très bien expliqué.

      http://php.net/manual/fr/pdostatement.bindparam.php

      En fait la grosse différence c'est quand ta variable est évalué.

      A+

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        29 février 2016 à 16:09:21

        Bonjour,

        la différence est subtile mais les 2 peuvent être utilisés même si on réutilise la requête préparée.

        Pour les exemples ci-dessous, imaginons que je veuille insérer des utilisateurs.

        J'ai un tableau $users qui contient les info des utilisateurs à ajouter.

        Avec binValue, une valeur est associée au marqueur:

        $name = null;
        $email = null;
        /** @var PDOStatement $stmt */
        $stmt = $bdd->prepare('INSERT INTO utilisateurs (name, email) VALUES (:name, :email);');
        
        // A chaque itération du foreach il faut attribuer $name et $email aux marquers correspondants
        foreach ($users as $user) {
            $name = $user['name'];
            $email = $user['email'];
            $stmt->bindValue(':name', $name);
            $stmt->bindValue(':email', $email);
            $stmt->execute();
            $stmt->closeCursor();
        }



        Avec binParam, c'est une variable qui est associée au marqueur, si sa valeur change, alors la valeur associée au marquer change:

        $name = null;
        $email = null;
        /** @var PDOStatement $stmt */
        $stmt = $bdd->prepare('INSERT INTO utilisateurs (name, email) VALUES (:name, :email);');
        $stmt->bindParam(':name', $name);
        $stmt->bindParam(':email', $email);
        
        // A chaque itération du foreach, la valeur de $name et $email change. le marqueur prendra ces nouvelles valeurs.
        foreach ($users as $user) {
        
            $name = $user['name'];
            $email = $user['email'];
            $stmt->execute();
            $stmt->closeCursor();
        }

         Dans le 2eme exemple, PDO va en interne faire un bindValue en reprenant les marqueurs indiqués dans bindParam et  les valeurs de $name et $email.

        -
        Edité par Anonyme 29 février 2016 à 16:15:01

        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          29 février 2016 à 16:11:26

          DOUBLON

          -
          Edité par Anonyme 29 février 2016 à 16:15:32

          • Partager sur Facebook
          • Partager sur Twitter
            29 février 2016 à 16:16:09

            Ce n'est en effet pas spécialement utile par rapport à un bind avec bindValue car bindParam prend vraiment son vraiment tout son sens sur de l'exécution multiple, ce qui n'est pas le cas ici.

            T'es sûr pour le closeCursor dans l'itération ?

            EDIT : c'est vrai que c'est plus lié au résultat (bien qu'un INSERT n'en renvoie jamais chez MySQL), l'objet PDOStatement n'est pas touché (surtout les inputs binds dans ce contexte)

            -
            Edité par julp 29 février 2016 à 16:39:48

            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              29 février 2016 à 16:19:24

              PDOStatement::closeCursor() libère la connexion au serveur, permettant ainsi à d'autres requêtes SQL d'être exécutées, mais laisse la requête dans un état lui permettant d'être de nouveau exécutée.

              Il est possible de le mettre dans la boucle ou après.

              Je préfère le mettre à l'intérieur, question de choix (possibilité d'exécuter d'autres requêtes en parallèle). Je n'ai pas remarqué de différence de performances/comportement entre les 2.

              -
              Edité par Anonyme 29 février 2016 à 16:21:19

              • Partager sur Facebook
              • Partager sur Twitter
                2 mars 2016 à 7:16:46

                Le diable se cache dans les détails... merci pour vos explications !

                @Valaendra: Est-ce qu'il y a une différence en terme de performance entre ton 1er et 2e exemple ?

                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  2 mars 2016 à 8:52:37

                  Pas de différences notables bien que bindParam s'avère légèrement plus rapide (on perçoit une différence dès 10000 itérations).

                  Après, la différence est si faible que c'est négligeable ;)

                  • Partager sur Facebook
                  • Partager sur Twitter

                  bindValue VS bindParam

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown