Partage
  • Partager sur Facebook
  • Partager sur Twitter

pdo requête préparer

code promotion et panier

Sujet résolu
    5 décembre 2024 à 13:58:52

    Bonjour,

    suite à un autre sujet poster ici j'ai vu que j'avais 2 connexion pour mon panier et mon code promotion a ma base de donnée.

    J'essaye de les réduire à une seule avec pdo vu que mon panier se base sur les requêtes préparé pdo.

    seulement j'ai une erreur qui s'affiche sur laquelle je bute :

    Warning: PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?' at line 1 in /var/www/html/produit/db.class.php on line 43

    public function __construct($host = null, $username = null, $password = null, $database = null){
    		if($host != null){
    			$this->host = $host;
    			$this->username = $username;
    			$this->password = $password;
    			$this->database = $database;
    		}
    
    		try{
                $this->db = new PDO('mysql:host='.$this->host.';dbname='.$this->database, $this->username, $this->password, array(
                        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8',
                        PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING
                    ));
    		}catch(PDOException $e){
    			die('<h1>Impossible de se connecter a la base de donnee</h1>');
    		}
    	}
    
    	public function query($sql, $data = array()){
    		$req =$this->db->prepare($sql);
    		$req->execute($data);
    		return $req->fetchAll(PDO::FETCH_OBJ);
    	}
    
    	public function count($sql, $data = array()){
    		$req = $this->db->prepare($sql);
    		$req->execute($data);
    		return $req->fetchColumn();
    	}
    
    	public function kaka($sql, $data = array()){
    		$req =$this->db->prepare($sql);
    		$req->execute($data);
    		return $req->fetchAll(PDO::FETCH_ASSOC);
    	}

    <?php			
    if(isset($_POST['promo'])) {
    	$codeconnect = htmlspecialchars($_POST['promo']);
    	if(!empty($codeconnect)) {
    		$codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?");
    		$usercode = $codeuser;
    		if($usercode = $codeconnect) {
    			echo "<p> votre code est valide </p>";
    		} else {
    			echo "<p>Mauvais code de promotion !</p>";
    		}
    	}
    	}
    			
    ?>

    -
    Edité par lutinjoyeux 5 décembre 2024 à 14:01:34

    • Partager sur Facebook
    • Partager sur Twitter
      5 décembre 2024 à 14:01:24

      Tu as une erreur de syntaxe [SQL] dans ta requête mais tu ne la donnes pas ...

      PS : il ne t'avait pas été déconseillé ce genre de try/catch ni l'emploi de SET NAMES (en faveur du paramètre charset du DSN) ?

      -
      Edité par julp 5 décembre 2024 à 14:02:43

      • Partager sur Facebook
      • Partager sur Twitter
        5 décembre 2024 à 14:03:21

        excuse moi j'ai enlever la partie connexion identifiant   l'erreur est à la ligne 33

        si je m'en occupe aussi j'essaye juste de terminer mes erreurs de double connection avant de M'occuper de sa

        -
        Edité par lutinjoyeux 5 décembre 2024 à 14:04:38

        • Partager sur Facebook
        • Partager sur Twitter
          5 décembre 2024 à 14:08:32

          Si tu mets un marqueur, le ?, tu fournis sa valeur à quel moment ? Ta méthode kaka attend un tableau facultatif en second argument pour justement y préciser les binds à faire. Enfin, c'est toi qui a écrit cette méthode ...

          $codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?"); => $codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?", [$_POST['promo']]);

          > $codeconnect = htmlspecialchars($_POST['promo']);

          Pourquoi tu mets un htmlspecialchars ici ? Ce n'est pas là que tu risques de trouver une XSS !

          > if($usercode = $codeconnect) {

          Ca risque d'être toujours vrai (confusion =/==)

          Pour éviter de répéter ton code, tu pourrais écrire :

              private function do_query($sql, $data, $mode) {
                  $req =$this-&gt;db-&gt;prepare($sql);
                  $req-&gt;execute($data);
                  return $req-&gt;fetchAll($mode);
              }
          
              public function query($sql, $data = []) {
                  return $this-&gt;do_query($sql, $data, PDO::FETCH_OBJ);
              }
           
              public function kaka($sql, $data = []) {
                  return $this-&gt;do_query($sql, $data, PDO::FETCH_ASSOC);
              }
          

          -
          Edité par julp 5 décembre 2024 à 14:29:58

          • Partager sur Facebook
          • Partager sur Twitter
            5 décembre 2024 à 14:28:10

            <?php			
            if(isset($_POST['promo'])) {
            	$codeconnect = $_POST['promo'];
            	if(!empty($codeconnect)) {
            		$codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?");
            		$usercode = $codeuser;
            		if($usercode == $codeconnect) {
            			echo "<p> votre code est valide </p>";
            		} else {
            			echo "<p>Mauvais code de promotion !</p>";
            		}
            	}
            	}
            			
            public function kaka($sql, $data = array()){
            		$req =$this->db->prepare($sql);
            		$req->bindParam('promo', $codeuser, PDO::PARAM_INT);
            		$req->execute();
            		return $req->fetchAll(PDO::FETCH_ASSOC);
            	}
            
            je bute encore PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /var/www/html/produit/db.class.php on line 44 toujours la ligne execute

            • Partager sur Facebook
            • Partager sur Twitter
              5 décembre 2024 à 14:34:48

              Non, j'avais édité pour donner la solution en plus.

              Non seulement procéder ainsi limiterait grandement le réemploi de la méthode mais, question de portée, la variable $codeuser n'existe pas pour commencer.

              -
              Edité par julp 5 décembre 2024 à 14:35:32

              • Partager sur Facebook
              • Partager sur Twitter
                5 décembre 2024 à 14:37:59

                Parse error: syntax error, unexpected token "&" in /var/www/html/produit/db.class.php on line 30

                $req =$this-&gt;db-&gt;prepare($sql);


                sa correspond à quoi $mode ?

                -
                Edité par lutinjoyeux 5 décembre 2024 à 15:22:14

                • Partager sur Facebook
                • Partager sur Twitter
                  5 décembre 2024 à 16:04:21

                  Ca fait des années que ce forum est buggué : les &lt; sont des <, &amp; des & et les &gt; des >

                  > ça correspond à quoi $mode ?

                  A ce que tu lui passes en troisième argument, soit PDO::FETCH_OBJ si tu passes par la méthode query et PDO::FETCH_ASSOC par kaka

                  • Partager sur Facebook
                  • Partager sur Twitter
                    5 décembre 2024 à 16:42:42

                    d'accord merci, je me disais bien je trouver pas dans le manuel php  arf

                    private function do_query($sql, $data, $mode) {
                            $req =$this->db->prepare($sql);
                            $req->execute($data);
                            return $req->fetchAll($mode);
                        }
                    
                        public function query($sql, $data = []) {
                            return $this->do_query($sql, $data, PDO::FETCH_OBJ);
                        }
                     
                        public function kaka($sql, $data = []) {
                            return $this->do_query($sql, $data, PDO::FETCH_ASSOC);
                        }
                    
                    	public function count($sql, $data = array()){
                    		$req = $this->db->prepare($sql);
                    		$req->execute($data);
                    		return $req->fetchColumn();
                    	}
                    <?php			
                    if(isset($_POST['promo'])) {
                    	$codeconnect = $_POST['promo'];
                    	if(!empty($codeconnect)) {
                    		$codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?");
                    		if($codeuser == $codeconnect) {
                    			echo "<p> votre code est valide </p>";
                    		} else {
                    			echo "<p>Mauvais code de promotion !</p>";
                    		}
                    	}
                    }
                    			
                    ?>
                    
                    PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;


                    j'ai encore cette erreur sur cette ligne :

                    $req->execute($data);
                    sa vient de mon $codeuser ?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      5 décembre 2024 à 16:50:15

                      Je t'ai donné la solution 3 posts plus tôt :

                      > $codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?"); => $codeuser = $DB->kaka("SELECT * FROM promotion WHERE promo = ?", [$_POST['promo']]);

                      Je n'avais pas tilté mais avec le fetchAll, $codeuser serait un tableau de tableaux, ton test if($codeuser == $codeconnect) { ne saurait être vrai. Ce serait plus par la méthode count (avec un SELECT COUNT(*)) que kaka qu'il faudrait passer.

                      -
                      Edité par julp 5 décembre 2024 à 16:55:37

                      • Partager sur Facebook
                      • Partager sur Twitter
                        5 décembre 2024 à 16:57:42

                        $codeuser = $DB->count("SELECT * FROM promotion WHERE promo = ?", [$_POST['promo']]);
                        tu veux dire ainsi ? sa me met toujours sur le ELSE si c'est sa
                        • Partager sur Facebook
                        • Partager sur Twitter
                          5 décembre 2024 à 17:01:38

                          Non il faut que tu changes SELECT * en SELECT COUNT(*) et if($codeuser == $codeconnect) { en if($codeuser == 1) {

                          Si ton code fonctionnait ce serait vraiment un coup de bol : il faudrait que la première colonne renvoyée par le SELECT * soit celle de ta colonne promo (ie avec SELECT promo ça pourrait fonctionner) mais après ça dépend encore de la casse et si ton interclassement est insensible à la casse. Bref, pour faire court, la méthode basée sur un SELECT COUNT(*) est bien plus viable.

                          -
                          Edité par julp 5 décembre 2024 à 17:06:08

                          • Partager sur Facebook
                          • Partager sur Twitter
                            5 décembre 2024 à 17:14:18

                            ok du coup je peut retirer public function kaka j'imagine ?

                            il me reste a passer le code discount (float) qui se trouve dans ma colonne Promotion dans ma construction panier et le multipliait par le total.

                             la je devrais utiliser Query si je dis pas de bêtise
                            • Partager sur Facebook
                            • Partager sur Twitter
                              5 décembre 2024 à 17:34:08

                              > ok du coup je peut retirer public function kaka j'imagine ?

                              C'est toi qui voit et si tu ne l'utilises nulle part ailleurs.

                              > il me reste a passer le code discount (float) qui se trouve dans ma colonne

                              Il te faudrait une méthode sans fetchAll :

                                  public function get($sql, $data = []) {
                                      $req =$this-&gt;db-&gt;prepare($sql);
                                      $req-&gt;execute($data);
                                      return $req-&gt;fetch(PDO::FETCH_ASSOC);
                                  }
                              

                              Et si tu veux faire les 2 en même temps (vérifier qu'il existe et l'utiliser) :

                              $codeuser = $DB-&gt;get("SELECT * FROM promotion WHERE promo = ?", [$_POST['promo']]);
                              if ($codeuser) {
                                  echo "<p> votre code est valide </p>";
                                  # $total *= $codeuser['discount'];
                              } else {
                                  echo "<p>Mauvais code de promotion !</p>";
                              }
                              

                              (un fetchColumn donc ta méthode count + SELECT discount ça fonctionnerait aussi si c'est la seule information dont tu as besoin)

                              • Partager sur Facebook
                              • Partager sur Twitter
                                5 décembre 2024 à 17:57:30

                                d'accord c'est limpide :) par contre le calcul total se fait sur une autre page (panier.class) je pensai du coup faire une session a la page livraison ou se situe le codeuser etc pour la promotion.

                                et importer sur ma page panier class le session discount

                                sa donne sa

                                if(isset($_POST['promo'])) {
                                	$codeconnect = $_POST['promo'];
                                	if(!empty($codeconnect)) {
                                		$codeuser = $DB->get("SELECT * FROM promotion WHERE promo = ?", [$_POST['promo']]);
                                		if ($codeuser) {
                                			echo "<p> votre code est valide </p>";
                                			$_SESSION['discount'] = $codeuser['discount'];
                                		} else {
                                			echo "<p>Mauvais code de promotion !</p>";
                                		}
                                	}
                                }
                                et la page panierclass :

                                return $total * $_SESSION['discount'] + $_SESSION['port'] ;
                                

                                C'est bon aussi ? il me manque as définir array key "discount" sur la page panier class 


                                -
                                Edité par lutinjoyeux 5 décembre 2024 à 17:58:18

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  5 décembre 2024 à 18:21:49

                                  A toi de me dire :) Je pense qu'avec ce code, $_SESSION['discount'] peut ne pas exister donc plutôt return $total * ($_SESSION['discount'] ?? 1) + $_SESSION['port'] ; (ou return $total * (1 - ($_SESSION['discount'] ?? 0)) + $_SESSION['port'] ; suivant ce que représente le discount) ?

                                  Attention :

                                  • aux décimaux, ce n'est pas du calcul exact, tu pourrais avoir des surprises (arrondis)
                                  • les sessions peuvent potentiellement durer plus longtemps que tu ne le penses, perso, je retesterais sa validité complète à la fin (paiement). Idem pour les frais de port mais je suis peut être parano. Ok pour garder ces informations en session de façon indicative en guise de cache mais je revérifierais/recalculerais tout au moment du paiement

                                  -
                                  Edité par julp 5 décembre 2024 à 18:32:27

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    5 décembre 2024 à 18:31:34

                                    le discount représente (0.9) par exemple

                                    ah oui effectivement je vois trés bien un total de 19,33333333333 du coup :D

                                    pour l'arrondi

                                    return round($total * ($_SESSION['discount'] ?? 1) + $_SESSION['port'] , 3) ;

                                    alors pas d'erreur et le code promo marche c'est good valide ?


                                    -
                                    Edité par lutinjoyeux 6 décembre 2024 à 15:12:01

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    pdo requête préparer

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    • Editeur
                                    • Markdown