Bonjour,

Après avoir téléchargé le code du tuto panier, je cherche à ajouter de nouvelle fonctionalité,

<?php $ids = array_keys($_SESSION['panier']);
            if(empty($ids)){
                $insert1 = array();
            }else{
                $insert1 = $DB->query('INSERT INTO ORDERS (article) VALUES ('.implode($ids).')');
            }
            foreach($insert1 as $insert):

     endforeach; 

J'ai récupéré le code du fichier panier.php qui permet d'afficher les articles du panier de l'utilisateur, et j'aimerais le modifier pour effectuer un INSERT dans ma base de donnée plutôt qu'un select.

Ayant 2 articles dans le panier, ma requete écrit bien dans la DB mais écrit 1 seule ligne avec les valeurs ID des 2 articles,

Mon but étant de créer 2 lignes différente et non une ligne composé des 2 ID

Je pence que le problème vient du implode ?
Merci.

13 réponses


Salut, déjà je te déconseille de faire des query avec des requête qui utilisent des variables, utilise les requêtes préparés.

donc pour reprendre ce que je vois au dessus, tu as une variables ids de type array qui corresponds aux id des articles

Le plus simple étant de bouclé sur chaque id et de faire une requête.

Comme cela

$ids = array_keys($_SESSION['panier']);
            if(empty($ids)){
                $insert1 = array();
            }else{
               foreach($insert1 as $insert):
            $query = $DB->prepare('INSERT INTO ORDERS (article) VALUES(?)');
            $query->execute([$insert]);
                endforeach; 

            }

J'espère avoir pu t'aider.

Mais du coup c'est quoi $insert1 dans le else ?

La table "orders" n'a qu'un champ "article" ? qui correspond à l'id de l'article ?

Dans ton code, c'est si le le tableau ids est vide alors insert1 est un tableau vide, sinon je boucle sur insert 1 pour récupérer les clé. Je ne suis pas allé sur le tuto donc je ne pourrais pas trop te dire du coup, mais je suppose que le champ article correspond à l'id oui

EDIT: Oups oui en effet, j'ai fais une petite faute, c'est pas foreach $insert1 mais foreach $ids

leon06
Auteur

Exact $ids est un array qui contient tout les ID des articles du paniers, j'ai pour le moment mis un seul champs pour me simplifier la tache mais une fois le problème résolue j'ajouterais d'autre colonne à remplir ( date, user, quantité,prix etc..)

Merci pour votre aide, en me servant du code de Sparkosis j'ai une erreur que je n'avais pas avant (du à la requete préparée je présume):

Call to undefined method DB::prepare(

Ah, est ce que $DB est un objet PDO, ou est-ce une custom class ?

leon06
Auteur

Voila le code de mon db.class.php
<?php
class DB{

private $host = 'localhost';
private $username = 'root';
private $password = '';
private $database = 'test';
private $db;

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);
}

}

Ok donc c'est bien une class custom.
pas trés propre mais bon essaie comme ça: $query = $DB->db->prepare(....) ;

je pense que ça devrait fonctionner

Ça va fonctionner puisque dans sa classe DB, son attribut db est un objet "PDO", donc on a bien accès à la fonction PDO::prepare.

Par contre c'est pas très logique, puisqu'il semblerait qu'il essaie de ne pas utiliser directement les fonction de PDO, mais plutôt de passer d'abord par celles de sa classe DB.
C'est sa fonction query à lui qu'il essaie d'utiliser, c'est cette fonction là qui fait le prepare de "PDO".
Du coup :

<?php
    $DB->query(...);
?>

Mais sa fonction (query) n'a pas vraiment de sens...
On met $data à un tableau vide par défaut, pourtant sur un prepare on ne peut pas l'accepter.
On fait aussi un return systématique d'un fetchAll() (qui n'est utile que pour les requêtes de type SELECT, ET d'au moins 2 entrées récupérées), alors qu'il essaie de faire des INSERT.

En plus le constructeur vérifie si $host n'est pas NULL, alors que $host est définit "en dur" à 'localhost'.
Et le fait que les paramètres puissent être à NULL n'a pas de sens dans ce constructeur-là.

Tout est vraiment confus, en fait il va falloir se poser un moment, tout revoir, et une fois que tu auras mis un peu d'ordre, reviens nous dire si tu as toujours un problème. Là c'est trop.

je suis d'accord avec SLK, mais je crois que c'est une couche à PDO de base sur le tuto

Ah oui mais on peut faire cette couche supplémentaire avec ses propres fonction "query" et "prepare", c'est même une bonne idée je trouve.
C'est juste que là c'est mal fait quoi...

En effet oui, c'est un singleton un peu foiré mais c'est un début

leon06
Auteur

Merci pour votre aide j'ai finalement réussi, cela permet une fois la commande validée, de la créée dans la base de donnée, pour pouvoir générer des fichiers PDF (bon de livraison)

Bonsoir.
Si ton sujet est résolu, marques le comme tel.