Partage
  • Partager sur Facebook
  • Partager sur Twitter

POO en PHP - expérience n'apparait pas

    20 mai 2019 à 13:52:13

    Bonjour,

    J'ai terminé le premier TP du cours Programmez en orienté Objet en PHP. J'ai travaillé cet après-midi sur le premier point des Améliorations Possibles du TP (niveau et force).

    Dans ma classe Manager.php, je demande à afficher le niveau et l'expérience du joueur et des joueurs pouvant être frappés. Hors, étrangement, le niveau apparait comme il se doit mais l'expérience, elle, n'apparait pas que ce soit pour le joueur ou pour les personnes pouvant être frappés.

    Je ne comprends pas pourquoi car je procéde de la même manière pour les deux fonctionnalités. Les attributs, setters et getters existent pour niveau comme expérience. Dans ma classe PersonnagesManager, j'ai assigné une valeur par défaut à ses champs via hydrate, donc il y a bien une valeur assignée.

    Je joins mon code ci-dessous et remercie par avance ceux qui voudront bien le regarder. Voyez-vous quelque chose qui pourrait expliquer pourquoi "expérience" n'apparait pas du tout.

    Personnages.php :

    <?php
    
    require_once 'PersonnagesManager.php';
    require_once 'manager.php';
    
    class Personnage 
    {
        
    //attributs
    private $_id;
    private $_nom;
    private $_degats;
    private $_niveau;
    private $_experience;
    
    //constantes 
    const CEST_MOI = 1;
    const PERSONNAGE_TUE = 2;
    const PERSONNAGE_FRAPPE = 3;
     
    // constructeur appelant la fonction hydrate lors de la création d'un personnage     
    public function __construct(array $donnees)   
    {
        $this->hydrate($donnees);
    }
            
        
    // fonction hydrate    
    public function hydrate(array $donnees)    
        {
            foreach ($donnees as $key=>$value)
            {
                $method='set' .ucfirst($key);
                
                if(method_exists($this, $method))
                {
                    $this->$method($value);
                }
            }
        }    
    
        // getters
        
    // getter de l'attribut id
    public function id()
    {
        return $this->_id;
    }
        
    
    // getter de l'attribut nom 
    public function nom()
    {
        return $this->_nom;
    }
        
        
    // getter de l'attribut degats
    public function degats()
    {
        return $this->_degats;
    }
        
        
    // getter de l'attribut niveau
    public function niveau()
    {
        return $this->_niveau;
    }
        
    
    // getter de l'attribut experience
    public function experience()
    {
        return $this->_experience;        
    }
        
        // setters
        
    // setter de id
    public function setId($id)
    {
        $id = (int) $id;   
            if ($id > 0)
                {
                    $this->_id = $id;
                }
    }
        
    
    // setter de nom
    public function setNom($nom)
    {
        if(is_string($nom))
            {
                $this->_nom=$nom;
            }
    }
        
    
    // setter de degats
    public function setDegats($degats)
    {
        $degats = (int) $degats;
            
            if($degats>=0 && $degats<=100)
                {
                    $this->_degats=$degats;
                }
    }
    
        
    // setter de niveau
    public function setNiveau($niveau)
    {
        $niveau = (int) $niveau;
        {
            $this->_niveau = $niveau;
        }
    }
        
        
    // setter d'expérience
    public function setExperience($experience)
    {
        if(is_int($experience))
        {
            $this->_experience = $experience;
        }
    }
        
        
    // Méthodes    
    public function frapper(Personnage $perso) 
    {
        
        // A REVOIR VU CORRIGE
        if ($perso->id() == $this->_id)
        {
          return self::CEST_MOI;
              
          /* Avant tout : vérifier qu'on ne se frappe pas soi-même. Si c'est le cas, on stoppe tout en renvoyant une valeur signifiant que le personnage ciblé est le personnage qui attaque. */
        
        // On indique au personnage qu'il doit recevoir des dégâts. Puis on retourne la valeur renvoyée par la méthode : self::PERSONNAGE_TUE ou self:: PERSONNAGE_FRAPPE
            
        } // pas besoin de placer de else si on est hors accolades !!!
        
        return $perso -> recevoirDegats();
        return $perso -> gainExperience();
        return $perso -> nextLevel();
    }   
    
        
    public function recevoirDegats()
    {      
        // On augmente de 5 les dégâts.
        $this->_degats += 5;
        
        
        // Si on a 100 de dégâts ou plus, la méthode renverra une valeur signifiant que le personnage a été tué.
       if($this->_degats >= 100)
       {
           return self::PERSONNAGE_TUE;
       }
        
        // Sinon, elle renverra une valeur signifiant que le personnage a bien été frappé.
     // si rien de spécifié : 
    return self::PERSONNAGE_FRAPPE;
        
    }     
      
        
        
    public function nomValide()
      {
        return !empty($this->_nom);
      }
       
    
    // fonction créer pour le Aller plus loin : gainExperience() vise à ajouter 10 points d'expérience à chaque fois que l'on frappe un personnage
    public function gainExperience()
    {
        $experience = (int) $experience;
        
        if($perso->frapper($persoAfrapper))
        {
           $this->_experience +=10;
        }
    }
        
    // fonction qui permet d'accéder au niveau d'expérience supérieur, si on a atteint 100 d'expérience alors on passe au niveau du dessus. Il y a 100 niveaux    
    public function nextLevel()
    {
        $niveau = (int) $niveau;
        
        if($this->_experience = 100)
        {
            $niveau=$niveau++;
        }
    }  
    }

    PersonnagesManager.php :

    <?php
        
    require_once 'manager.php';
    require_once 'Personnage.php';
    
    class PersonnagesManager
    {
      private $_db; // Instance de PDO
    
        
      public function __construct($db)
      {
        $this->setDb($db);
      }
        
          
        // setter de db
      public function setDb(PDO $db)
      {
        $this->_db = $db;
      }
        
        
        // METHODES
    
        // création d'un personnage
      public function add(Personnage $perso)
      {
        $q = $this->_db->prepare('INSERT INTO personnages(nom, niveau, experience) VALUES(:nom, :niveau, :experience)');
        
          
        $q -> bindValue(':nom', $perso->nom());
       //$q -> bindValue(':niveau', $perso->niveau(), PDO::PARAM_INT);
       // $q -> bindValue(':experience', $perso->experience(), PDO::PARAM_INT); 
        $q->execute();
        
        $perso->hydrate([
          'id' => $this->_db->lastInsertId(),
          'degats' => 0,
          'niveau' => 1, 
          'experience' => 0,
        ]);
      }
       
        
        
        // fonction pour compter les personnages
        public function count()
      {
        return $this->_db->query('SELECT COUNT(*) FROM personnages')->fetchColumn();
      }
      
    
        
        // suppression d'un personnage
      public function delete(Personnage $perso)
      {
        $this->_db->exec('DELETE FROM personnages WHERE id = '.$perso->id());
      }
    
        
        
        // est-ce qu'un personnage existe (id ou nom)
        public function exists($info)
        {
            if (is_int($info)) // On veut voir si tel personnage ayant pour id $info existe.
            {
                return (bool) $this->_db->query('SELECT COUNT(*) FROM personnages WHERE id = '.$info)->fetchColumn();
            }
        
            // Sinon, c'est qu'on veut vérifier que le nom existe ou pas.
        $q = $this->_db->prepare('SELECT COUNT(*) FROM personnages WHERE nom = :nom');
        $q->execute([':nom' => $info]);
        
        return (bool) $q->fetchColumn();
        }  
        
        
        
        // obtenir un personnage via son id ou son nom
      public function get($info)
      {
        if (is_int($info))
        {
          $q = $this->_db->query('SELECT id, nom, degats, niveau, experience FROM personnages WHERE id = '.$info);
          $donnees = $q->fetch(PDO::FETCH_ASSOC);
          
          return new Personnage($donnees);
        }
        else
        {
          $q = $this->_db->prepare('SELECT id, nom, degats, niveau, experience FROM personnages WHERE nom = :nom');
          $q->execute([':nom' => $info]);
        
          return new Personnage($q->fetch(PDO::FETCH_ASSOC));
        }
      }
     
    
          
        // obtenir la liste des personnages
        // on veut obtenir ici une liste des personnages que l'on peut frapper donc on s'exclut vu qu'on ne veut pas se frapper soi-même. Pour cela on fait WHERE nom <> : nom
        // <> signifie : n'est pas égal ou différent de !=
      public function getList($nom)
      {
        $persos = [];
        
        $q = $this->_db->prepare('SELECT id, nom, degats, niveau, experience FROM personnages WHERE nom <> :nom ORDER BY nom');
        $q->execute([':nom' => $nom]);
        
        while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
        {
          $persos[] = new Personnage($donnees);
        }
        
        return $persos;
      }
    
        
        
        // mettre à jour un personnage
      public function update(Personnage $perso)
      {
        $q = $this->_db->prepare('UPDATE personnages SET degats = :degats, niveau = :niveau, experience = :experience WHERE id = :id');
        $q -> bindValue(':degats', $perso->degats(), PDO::PARAM_INT);
        $q -> bindValue(':niveau', $perso->niveau(), PDO::PARAM_INT);
        $q -> bindValue(':experience', $perso->experience(), PDO::PARAM_INT);
        $q->bindValue(':id', $perso->id(), PDO::PARAM_INT);
        $q->execute();
      }
    
    }

    manager.php :

    <?php
    // On enregistre notre autoload.
    function chargerClasse($classname)
    {
      require $classname.'.php';
    }
    spl_autoload_register('chargerClasse');
    
    // Démarrage de session ---> attention on doit toujours démarrer la session après l'autoload ou les require
    session_start();
    
        // si on coche se déconnecter
            if(isset($_GET['deconnection']))
                {
                    session_destroy();
                    header('Location: .');
                    exit();
                }
    
        // si une session existe, on restaure l'objet
            if(isset($_SESSION['perso']))
                {
                    $perso = $_SESSION['perso'];
                }
    
    // on créé un objet de type PDO
    $db = new PDO('mysql:host=localhost;dbname=""', '""', '""');
    
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); // On émet une alerte à chaque fois qu'une requête a échoué.
    
    
    // Création d'une instance de PersonnagesManager : il faut un objet de cette classe !
    $manager = new PersonnagesManager($db);
    
    // si la session perso existe, restaure l'objet
    if(isset($_SESSION['perso']))
    {
        $perso=$_SESSION['perso'];
    }
    
    // Utilisation de Créer un personnage
    if (isset($_POST['creer']) && isset($_POST['nom'])) // Si on a voulu créer un personnage.
    {
      $perso = new Personnage(['nom' => $_POST['nom']]); // On crée un nouveau personnage.
      
      if (!$perso->nomValide())
      {
        $message = 'Le nom choisi est invalide.';
        unset($perso);
      }
      elseif ($manager->exists($perso->nom()))
      {
        $message = 'Le nom du personnage est déjà pris.';
        unset($perso);
      }
      else
      {
        $manager->add($perso);
      }
    }
    
    // Utilisation d'utiliser un personnage
    elseif (isset($_POST['utiliser']) && isset($_POST['nom'])) // Si on a voulu utiliser un personnage.
    {
      if ($manager->exists($_POST['nom'])) // Si celui-ci existe.
      {
        $perso = $manager->get($_POST['nom']);
      }
      else
      {
        $message = 'Ce personnage n\'existe pas !'; // S'il n'existe pas, on affichera ce message.
      }
    }
    
    elseif(isset($_GET['frapper']))
    {
        if(!isset($perso))
    {
        $message = "Merci de créer un personnage ou de vous identifier";
    }
    
        else
        {
            if(!$manager->exists((int) $_GET['frapper']))
            {
                $message = "Le personnage que vous voulez frapper n\'existe pas !";
            }
            
            else
            {
                $persoAFrapper = $manager->get((int) $_GET['frapper']);
                $retour = $perso->frapper($persoAFrapper);
            
            switch ($retour)
          {
            case Personnage::CEST_MOI :
              $message = 'Mais... pourquoi voulez-vous vous frapper ???';
              break;
            
            case Personnage::PERSONNAGE_FRAPPE :
              $message = 'Le personnage a bien été frappé et vous avez gagné 10 d\'expérience!';    
              $manager->update($perso);
              $manager->update($persoAFrapper);
              break;
            
            case Personnage::PERSONNAGE_TUE :
              $message = 'Vous avez tué ce personnage et vous avez gagné 10 d\'expérience!';
              $manager->update($perso);          
              $manager->delete($persoAFrapper);
              break;
          }
        }
      }
    }
    ?>
    <!-- html -->
    
    <!DOCTYPE html>
    <html>
      <head>
        <title>TP : Mini-jeu de combat</title>
        
        <meta charset="utf-8" />
      </head>
      <body>
        <p>Nombre de personnages créés : <?= $manager->count() ?></p>
    <?php
    if (isset($message)) 
        // On a un message à afficher ?
        {
            echo '<p>', $message, '</p>'; // Si oui, on l'affiche.
        }
        
            
    if(isset($perso)) // si on utilise un personnage (new ou existant)
        {
        ?>
          
          <!-- lien permettant de se deconnecter -->
          <p> <a href="?deconnection"> Deconnection </a></p>
          
          <fieldset> 
              <legend> Mes informations </legend>
                <p> 
                    Nom :   <?php echo htmlspecialchars($perso->nom()); ?> <br/>
                    Dégâts : <?php echo $perso->degats(); ?> <br/>
                    Niveau : <?php echo $perso->niveau(); ?> <br/>
                    Expérience : <?php echo $perso->experience(); ?> <br/>
                </p>
          </fieldset>
          
          
          <fieldset>
                <legend> Qui frapper ? </legend>
                    <p>
                        <?php 
                        
                        $persos=$manager->getList($perso->nom());
        
                        if(empty($persos)) 
                        {
                            $message= 'Il n\'y a personne à frapper !';
                        }
                        
       
                        else
                        {
                            foreach ($persos as $unPerso)
        echo '<a href="?frapper='. $unPerso->id(). '">'. htmlspecialchars($unPerso->nom()). '</a> (dégâts : '. $unPerso->degats(). ' - niveau : ' . $unPerso->niveau(). ' - expérience : ' . $unPerso->experience().')<br />';
                        }
                        
                        ?>
                        
                    </p>
              
          </fieldset>
          
          <?php 
              
        }
            else
            {
                ?>
             
          
        <form action="" method="post">
          <p>
            Nom : <input type="text" name="nom" maxlength="50" />
            <input type="submit" value="Créer ce personnage" name="creer" />
            <input type="submit" value="Utiliser ce personnage" name="utiliser" />
          </p>
        </form>
          
          <?php 
            }
            ?>
          
                
      </body>
    </html>
    <?php 
    if(isset($perso))
    {
        $_SESSION['perso'] = $perso;
    }
    ?>





    Merci.

    • Partager sur Facebook
    • Partager sur Twitter
      20 mai 2019 à 16:32:32

      Bonjour.

      Voici tes erreurs de code.

      Classe Personnage

      • Méthode frapper: Seule la ligne 148 sera exécutée, les deux suivantes ne le seront pas
      • Méthode gainExperience: les variables experience, perso et persoAfraper ne sont pas définies.
      • Méthode nextLevel: la variable niveau n'est pas définie et la méthode ne fait aucune modification sur la classe ou autre.

      Page manager.php:

      • Le code de la ligne 21 à 24 ne sert absolument à rien.
      • Partager sur Facebook
      • Partager sur Twitter

      Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

        21 mai 2019 à 5:10:54

        Bonjour Lartak,

        Merci pour tes réponses.

        J'ai fait apparaitre les valeurs "expérience", mon problème venait de ma base de donnée et au fait que je n'avais pas assigné de valeur par défaut dans mon fichier.

        J'ai supprimé les deux derniers return pour frapper.

        J'ai conservé les lignes de code 21 à 24 dans manager car sans elle, j'ai des erreurs, le programme supprimant la session. Elles semblent donc bien nécessaire au fonctionnement de session.

        Pour frapper, j'avais oublié d'enlever le commentaire devant une ligne d'où un nombre d'argument dans ma fonction Créer qui refonctionne à présent.

        Je ne comprends pas ce que tu veux dire concernant la méthode gainExperience. Je ne comprends pas vraiment ce qui manque ici...

        Merci.

        • Partager sur Facebook
        • Partager sur Twitter

        POO en PHP - expérience n'apparait pas

        × 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