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;
}
?>
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.
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.
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.