POO ajout d'objet dans la BDD : rien ne se passe [Résolu/Fermé]

Signaler
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
-
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
-
Bonjour,

Je suis en trai de me former un tutoriel de Programmation orienté objet en php.

Je suis bloqué au chapitre manipulation de données stockées.

Pour l'organisation, j'ai crée les fichiers :

classes/Personnage.classes.php

qui contient le code suivant (en principe la liste des getters, setters et l'hydratation dynamique) :

<?php
 
  
class Personnage
{
    private $_id;
    private $_nom;
    private $_forcePerso;
    private $_degats;
    private $_niveau;
    private $_experience;
 
    //Liste des getters
     
    public function id()
    {
        return $this->_id;
    }
     
    public function nom()
    {
        return $this->_nom;
    }
     
    public function forcePerso()
    {
        return $this->_forcePerso;
    }
     
    public function degats()
    {
        return $this->_degats;
    }
     
    public function niveau()
    {
        return $this->_niveau;
    }
     
    public function experience()
    {
        return $this->_experience;
    }
     
  
    //Liste des setters
     
    public function setId($id)
    {
        $id = (int) $id;
         
        if($id> 0)
        {
            $this->_id = $id;
        }
    }
     
    public function setNom($nom)
    {
        if (is_string($nom))
        {
            $this->_nom = $nom;
        }
    }
     
    public function setForcePerso($forcePerso)
    {
        $forcePerso = (int) $forcePerso;
         
        if($forcePerso >=1 && $forcePerso<=100)
        {
            $this->_forcePerso = $forcePerso;
        }
    }
     
    public function setDegats($degats)
    {
        $degats = (int) $degats;
         
        if($degats>=0 && $degats<=100)
        {
            $this->_degats = $degats;
        }
    }
     
    public function setNiveau($niveau)
    {
        $niveau = (int) $niveau;
         
        if ($niveau>=1 && $niveau<=100)
        {
            $this->_niveau = $niveau;
        }
    }
     
    public function setExperience($experience)
    {
        $experience = (int) $experience;
         
        if ($experience>=1 && $experience<=100)
        {
            $this->_experience = $experience;
        }
    }
     
        //Hydratation dynamique
     
    public function hydrate(array $donnees)
    {
        foreach($donnees AS $key => $value)
        {
            //On recupere dynamiquement le setter correspondant à l'attribut'
            $method = 'set'.ucfirst($key);
             
            //Si le setter correspondant existe :
            if(method_exists($this,$method))
            {
                //on appelle le setter
                $this->$method($value);
            }
             
        }
    }
     
}
 
 
 
?>


J'ai également :

classes/PersonnageManager.classes.php

qui contient (en principe les requetes de Création Selection Update et Suppression des données) :

<?php
 
class PersonnageManager
{
     
    private $_db;
     
    public function __construct($db)
    {
        $this->setDb($db);
    }
     
    public function add(Personnage $perso)
    {
        //Preparation de la requete d'insertion'
        $q = $this->_db->prepare('INSERT INTO personnages SET nom = :nom, forcePerso = :forcePerso, degats = :degats, niveau = :niveau, experience = :experience');
         
        //Assignation des valeurs pour le nom, la force, les degats, l'experience, et le niveau du personnage'
        $q->bindValue(':nom', $perso->nom());
        $q->bindValue(':forcePerso', $perso->forcePerso(), PDO::PARAM_INT);
        $q->bindValue(':degats', $perso->degats(), PDO::PARAM_INT);
        $q->bindValue(':niveau', $perso->niveau(), PDO::PARAM_INT);
        $q->bindValue(':experience', $perso->experience(), PDO::PARAM_INT);
         
        //Execution de la requete
        $q->execute();
         
    }
     
    public function delete(Personnage $perso)
    {
        //execute une requete de suppression
        $this->_db->exec('DELETE FROM personnages WHERE id = '. $perso->id());
    }
     
    public function get($id)
    {
        //execute une requete de type SELECT avec une clause WHERE, et retourne un objet Personnage
        $id = (int) $id;
         
        $q = $this->_db->query('SELECT id, nom, forcePerso, degats, niveau, experience FROM personnages WHERE id ='. $id);
        $donnees = $q->fetch(PDO::FETCH_ASSOC);
         
        return new Personnage($donnees);
    }
     
    public function getList()
    {
        $persos = array();
         
        $q = $this->_db->query('SELECT id, nom, forcePerso, degats, niveau, experience FROM personnages ORDER BY nom');
         
        while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
        {
            $persos[] = new Personnage($donnees);
        }
         
        return $persos;
    }
     
    public function update(Personnage $perso)
    {
        //Prepare une requete de type UPDATE
        $q = $this->_db->prepare('UPDATE personnages SET forcePerso = :forcePerso, degats = :degats, niveau = :niveau, experience = :experience WHERE id = :id');
         
        //Assignation des valeurs à la requete
        $q->bindValue(':forcePerso', $perso->forcePerso(), PDO::PARAM_INT);
        $q->bindValue(':degats', $perso->degats(), PDO::PARAM_INT);
        $q->bindValue(':niveau', $perso->niveau(), PDO::PARAM_INT);
        $q->bindValue(':experience', $perso->experience(), PDO::PARAM_INT);
         
        //Execution de la requete
        $q->execute();
    }
     
    public function setDb(PDO $db)
    {
        $this->_db = $db;
    }
}
 
?>


puis au meme niveau que le repertoire classe le fichier test_personnage_bdd.php

avec le code :

<?php
 
require('classes/Personnage.classes.php');
require('classes/PersonnageManager.classes.php');
 
$perso = new Personnage(array(
    'nom' => 'Victor',
    'forcePerso' => 5,
    'degats' => 0,
    'niveau' => 1,
    'experience' => 0,
 
));
 
$db = new PDO('mysql:host=localhost;dbname=test_poo','root','');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$manager = new PersonnageManager($db);
 
$manager->add($perso);
 
?>




ceux ci affichent une erreur du type :

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'nom' cannot be null' in D:\wamp\www\POO\Donnees-stockees\classes\PersonnageManager.classes.php on line 26

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'nom' cannot be null in D:\wamp\www\POO\Donnees-stockees\classes\PersonnageManager.classes.php on line 26


Désolé si je met de long code mais je commence à me perdre sur l'erreur.

Merci pour votre aide

8 réponses

Messages postés
991
Date d'inscription
mercredi 20 février 2013
Statut
Membre
Dernière intervention
24 novembre 2018
91
Salut salut,

Dans ta fonction add, au moment ou tu fais le bind des paramètres :
...
 $q->bindValue(':nom', $perso->nom());
...

Le message d'erreur te dis que le nom n'est pas instancié, quand tu fais $perso->nom() c'est comme si tu lui demandais d'exécuter la méthode nom or elle n'existe pas. Enlève les parenthèse pour faire référence au paramètre "nom" de l'objet : $perso->nom
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
3
En supprimant les parenthèse, donc on a : $q->bindValue(':nom', $perso->nom); ca a generé une erreur :

Notice: Undefined property: Personnage::$nom in D:\wamp\www\POO\Donnees-stockees\cop-coller.php on line 103


Mais je pense que ce n'était pas au niveau de la methode puisqu'il existe dans le fichier classes/Personnage.classes.php.

On a bien une methode getter :

public function nom()
{
return $this->_nom;
}

mais c'est qui se passe c'est qu'il semble que la fonction add n'a pas pu recuperer cette valeur de retour ? Et si c'est ca qu'est ce qui manque ?
Messages postés
991
Date d'inscription
mercredi 20 février 2013
Statut
Membre
Dernière intervention
24 novembre 2018
91
lol autant pour moi j'ai dit n'importe quoi , je supposais que les getters étaient de la forme getNom()
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
3
désolé alors pour cette convention.
Je suis toujours prenant pour d'autres suggestion de ta part.
Messages postés
991
Date d'inscription
mercredi 20 février 2013
Statut
Membre
Dernière intervention
24 novembre 2018
91
Alors moi j'aime bien les constructeur en objet :p

Comme ça je n'ai pas vu l'endroit où ça bug, tu peux essayer de faire un echo de la requête juste avant le execute() pour voir à quoi elle ressemble.

Juste comme ça, dans test_personnage_bdd.php si tu fais echo $perso->nom(); après la création du perso, il renvoit bien le nom?
Résolu? ===> [RESOLU]
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
3
echo $perso->nom(); ne retourne rien sur la page.
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
3
donc c'est au niveau de cette methode qui pose problème. Des liaisons qui manquent peut-être ?
Messages postés
991
Date d'inscription
mercredi 20 février 2013
Statut
Membre
Dernière intervention
24 novembre 2018
91
Est ce que tu es sûr de la syntaxe pour la construction de l'objet personnage?
Habituellement j'utilise des constructeurs pour créer mes objets.

Parce que tu fais :
$perso = new Personnage(array( 
    'nom' => 'Victor', 
    'forcePerso' => 5, 
    'degats' => 0, 
    'niveau' => 1, 
    'experience' => 0, 
  
));

Or les noms des variables de l'objet Personnage sont écrites avec un"_" devant (_nom,_forcePerso , etc), ça doit être pour cela que lorsque tu fais $perso->nom() il ne renvoie rien


Résolu? ===> [RESOLU]
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
3
J'ai essayé avec plusieurs syntaxe dont :

'_nom' => 'Victor',
$_nom => 'Victor',
$this->nom() => 'Victor',
$this->nom => 'Victor',

mais sans succès.
Messages postés
991
Date d'inscription
mercredi 20 février 2013
Statut
Membre
Dernière intervention
24 novembre 2018
91
Je ne sais pas si on peut crée un objet comme tu l'as fait , essais ça, ça devrait fonctionner :
$perso=new Personnage();
$perso->setNom("Victor");
$perso->setForcePerso(10);
$perso->setDegats(0);
$perso->setNiveau(1);
$perso->setExperience(1);

Sinon fais un constructeur ou une méthode équivalente.
Messages postés
56
Date d'inscription
mercredi 21 mars 2012
Statut
Membre
Dernière intervention
7 novembre 2017
3
Merci beaucoup à cette baguette kyser !!! Ca marche avec ca.