J'ai une question qui se rapporte à la partie sur la création du mini-framework. Si je dois effectuer des traitements php et accès mysql, pour afficher des parties du layout (par exemple un bloc qui présente les 3 dernières news sur toutes les pages du site), ou va se trouver le code (qui sera assez proche du code présent dans le controller news au niveau de l'affichage des données) ?
Est-ce que je peux créer un Controlleur descendant du backController, et qui sera ensuite le parent de tous les controlleurs de mon application ? Ou alors peut-on ajouter au niveau du répertoire modele des classes effectuant ces travaux, et qui serait ensuite juste à appeler dans chacune des pages du site ?
Mon problème est le suivant : je vais avoir cette partie "dernières news" sur la page index, sur la page contact ... Sur toutes les pages du site en fait. Donc la méthode la plus simple serait de faire, dans chaque contrôleur, un appel au module news pour récupérer les 3 dernières news, puis un addVar. Là l'exemple est assez simple, mais si je dois en plus faire quelques opérations au niveau du contrôleur, ça se complique.
Il faudrait donc que je puisse mettre ce code (récupération des news, traitement, transmission au template commun, le layout) quelque part, accessible par tous les contrôleurs, pour ne pas avoir du code dupliqué.
Au lieu de retaper les mêmes attributs dans chaque contrôleur, vaut mieux en créer un et à chaque fois qu'on créé un nouveau on le fait héritier du backController. Ca ne devrait pas trops te surprendre maintenant que ta vue les NewsManager (PDO et MySqli)
Making functional apps for digital products @NEOTIC
Au lieu de retaper les mêmes attributs dans chaque contrôleur, vaut mieux en créer un et à chaque fois qu'on créé un nouveau on le fait héritier du backController. Ca ne devrait pas trops te surprendre maintenant que ta vue les NewsManager (PDO et MySqli)
Making functional apps for digital products @NEOTIC
Si je ne me trompe pas, avec le code que tu indiques, lorsque je vais aller sur la page contact ou index, je vais afficher ce que retourne l'action index du module news. Une route ne correspond qu'à un contrôleur.
De mon coté sur contact, je veux être redirigé vers le controleur qui m'affiche la page contact, mais qui m'affichera dans une colonne les dernières news également.
Bonjour, déjà merci d'avoir conçu ce cours, cependant j'ai un souci au chapitre 4 de la partie 1.Je reprend point par point pour être sûr de comprendre mais je n'arrive pas à insérer de données dans ma base.
Et j'ai tellement la tête dans le guidon que je vois pas ce qui pose problème. Voici mon code:
<?php
class Personnage
{
private $_id;
private $_nom;
private $_PV;
private $_force;
private $_niveau;
//hydrateur
public function hydrate(array $donnees)
{
foreach ($donnees as $key => $value)
{
// On récupère le nom du 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);
}
}
}
//Getters
public function id()
{
return $this -> _id;
}
public function nom()
{
return $this -> _nom;
}
public function PV()
{
return $this -> _PV;
}
public function force()
{
return $this -> _force;
}
public function niveau()
{
return $this -> _niveau;
}
//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 setForce($force)
{
$force = (int) $force;
if ($force>0 && $force<0)
{
$this->_force= $force;
}
}
public function setPV($PV)
{
$PV = (int) $PV;
if ($PV>=0 && $PV<10000)
{
$this->_PV= $PV;
}
}
public function setNiveau($niveau)
{
$niveau = (int) $niveau;
if ($niveau>=0 && $niveau <=100)
{
$this -> _niveau = $niveau;
}
}
}
class PersonnageManager
{
private $_db;
public function __construct($db)
{
$this->setDb($db);
}
public function add(Personnage $perso)
{
$q = $this->_db->prepare('INSERT INTO personnage SET nom = :nom, force = :force, niveau = :niveau, PV = :PV');
$q->bindValue(':nom', $perso->nom());
$q->bindValue(':force', $perso->force(), PDO::PARAM_INT);
$q->bindValue(':niveau', $perso->niveau(), PDO::PARAM_INT);
$q->bindValue(':PV', $perso->PV(), PDO::PARAM_INT);
$q->execute();
}
public function setDb(PDO $db)
{
$this->_db = $db;
}
public function test()
{ echo 'test';}
}
$kevin = new Personnage;
$kevin-> hydrate([
'nom' => 'kevin',
'force' => 5,
'PV' => 160,
'niveau' => 1,
]);
$db = new PDO('mysql:host=localhost;dbname=testpoo;charset=utf8', 'root', '');
$manager = new PersonnageManager($db);
$manager->add($kevin);
echo "je m'apelle ", $kevin->nom(),", j'ai ", $kevin->PV()," point de vie et je suis de niveau ",$kevin->niveau();
$req = $db->prepare('INSERT INTO personnage(nom, force, PV, niveau) VALUES(:nom, :force, :PV, :niveau)');
$req->execute(array(
'nom' => $kevin->nom(),
'force' => $kevin->force(),
'PV' => $kevin->PV(),
'niveau' => $kevin->niveau()
));
?>
Ma base de donnée 'testpoo'
nom de table : personnage
id int primary key auto_increment
nom varchar(40) unique
PV int
force int
niveau int
J'ai réussi à faire l'instance personnage et récupérer ses informations, j'arrive aussi à récupérer des données dans ma base testpoo, mais impossible d'insérer , même sans passer par le manager (pdo-php-mysql est bien activé).
Autre question que je passe une array dans la création de mon personnage $perso = new Personnage([]); rien ne se construit, Y'a t'il un rapport avec les '__' comme dans construct? Merci de vos réponses.
avant tout, merci à vyk12, l'auteur du cours. Pour l'avoir lu en sachant à peu près où j'allais, je le trouve vraiment facile à lire et bien organisé.
Il me reste néanmoins un problème avec les entités/managers/formulaires. Quand il s'agit de créer un entité unique comme par exemple un utilisateur, son manager et le formulaire correspondant, c'est assez "simple" en suivant le cours.
Par contre, imaginons que l'Utilisateur puisse appartenir à un et un seul Groupe et en même temps qu'il puisse parler une ou plusieurs Langue(s). Dans ce cas là, on se retrouve avec 3 entités et j'ai du mal à savoir comment faire le lien entre elles.
Est ce que notre classe Utilisateur va avoir des attributs Groupe et Langues ? Et si oui, pour y stocker quoi ? Les objets associés, juste des identifiants de ces objets, autre chose ? Et sinon où se fait le lien ?
Pareil pour les managers, sans POO, j'aurais eu tendance à faire une jointure pour récupérer toutes les informations d'un coup. Ici, comment on doit faire ? On récupère l'utilisateur via son manager ? Puis on utilise les autres managers un par un pour les autres données ? Le tout dans le contrôleur ?
Et pour finir les formulaires prennent en paramètres une seule entité, pourtant dans ce cas, je souhaiterais obtenir dans le même formulaire une liste déroulante pour les groupes, les infos de l'utilisateur, et une collection de champ pour les langues. Et je ne vois pas trop comment utiliser les FormBuilder et FormHandler dans ce cas là ?
J'ai peut être loupé quelque chose dans le cours mais quand j'essaye de m'attaquer à mon exemple, je ne sais plus où mettre les choses. Merci d'avance à ceux qui pourront m'aider.
Je reprend point par point pour être sûr de comprendre mais je n'arrive pas à insérer de données dans ma base.
Autre question que je passe une array dans la création de mon personnage $perso = new Personnage([]); rien ne se construit, Y'a t'il un rapport avec les '__' comme dans construct?
Pour ton premier problème, tu peux essayer de changer le mode d'erreur de PDO avec
$db = new PDO('mysql:host=localhost;dbname=testpoo;charset=utf8', 'root', '');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$manager = new PersonnageManager($db);
Au lieu que l'erreur soit silencieuse, tu auras alors une exception qui pourrait t'aider à voir le problème. A part ton "INSERT INTO personnage SET" qui est un mélange de insert et update, je ne vois pas d'erreurs et ça n'explique pas pourquoi ça ne marche pas sans manager.
Et pour ta seconde question, ça a effectivement un rapport avec le constructeur. Quand tu crées l'objet avec new, en lui donnant des paramètres, c'est le constructeur qui les utilise, donc c'est à lui d'appeler la méthode hydrate.
Il te manque donc, dans la classe Personnage :
public function __construct(array $donnees = array())
{
$this->hydrate($donnees);
}
Je tenais dans un premier temps à féliciter l'auteur pour ce tuto qui permet de passer le cap de la POO en douceur.
Cependant, il y a quelque chose que je ne comprend pas dans le TP. Lorsque l'on crée la classe "FrontendApplication", dans le constructeur de cette classe on instancie la classe mère "Application".
class FrontendApplication extends Application
{
public function __construct()
{
parent::__construct();
$this->name = 'Frontend';
}
La classe "Application" étant une classe abstraite, elle ne peut être instanciée selon ce qui a été dit précédemment dans le tuto.
Donc je voudrais savoir comment ce bout de code est sensé fonctionner vu que l'instance de la classe mère ne peut être créée?
ici la classe Application n'est pas instancié mais plutôt FrontendApplication qui hérite de la classe Application
vue qu'elle vien de préciser son nom avec $this->name
Making functional apps for digital products @NEOTIC
Selon toi la classe "Application" n'est pas instanciée, mais pourtant on a bien "parent::__construct();" qui à mon sens permet d'instancier une classe. Sinon à quoi bon exécuter le constructeur d'une classe si ce n'est pour l'instancier. Il me faudrait un petit éclaircissement de ce que l'on souhaite obtenir.
En tous cas, lorsque j'exécute ce code le "parent::__construct();" me renvoi "null", et les objets devant être instanciés depuis le constructeur de la classe "Application" ne sont pas créés.
Et juste à titre d'information quand tu dis qu'elle précise son nom avec $this->name c'est pour l'objet "FrontendApplication" et non "Application" puis que c'est ça que l'on crée avant tout selon moi?
parent::__construct() ne veut pas dire instancier une classe mais prendre les valeurs des propriétés initialisées dans la classe mère
c'est ce qu'on doit faire dans une classe fille si on veut avoir non seulement les attribut initialisées dans la classe mère et aussi de nouvelles attributs comme c'est le cas avec la classe FrontendApplication
- Edité par bechir_ 12 mai 2015 à 19:18:09
Making functional apps for digital products @NEOTIC
Pour revenir au problème rencontré dans le TP lors de l'exécution de la commande "parent::__construct()".
Hatll m'a expliqué que cette commande ne sert pas à instancier la classe mère mais à permettre l'utilisation des attributs de cette classe, comportement qui me parait un peut étrange. Pour moi le fait de créer une classe fille entrainait d'abord la création de la classe mère et de l'ensemble des propriétés, mais il semblerait que ce ne soit pas le cas en PHP.
Dans ce cas, est-ce qu'on pourrait m'expliquer quel est l’intérêt de faire de l'héritage si je ne peux bénéficier des propriétés de la classe mère sans avoir exécuté un "parent::__construct()"? Mis à part le fait de dire que la classe fille est également une instance de la classe mère.
"On vient de créer une classe Magicien héritant de toutes les méthodes de la classe Personnage. Que diriez-vous si l'on pouvait réécrire certaines méthodes, afin de modifier leur comportement ? Pour cela, il vous suffit de déclarer à nouveau la méthode et d'écrire ce que bon vous semble à l'intérieur...
Il suffit pour cela d'utiliser le mot-clé parent suivi du symbole double deux points (le revoilà celui-là ) suivi lui-même du nom de la méthode à appeler"
Et tu peux toujours recommencer le cours si tu n'a pas vraiment compris
Making functional apps for digital products @NEOTIC
FrontendApplication "étend" les fonctionnalités de la classe parent Application.
Elle va donc hériter de toutes ses propriétés protected et public, ainsi que de ses méthodes protected et public.
Cependant tu as la possibilité de remplacer le comportement d'une méthode de la classe parent dans ta classe enfant. Pour cela, il te suffit de réécrire la méthode. Il y a alors deux possibilités :
- tu souhaites changer complètement le comportement. Dans ce cas, tu n'as rien à faire, lorsque tu appeleras la fonction dans ton code, c'est la fonction de l'objet enfant qui sera appelé.
- tu souhaites étendre son comportement (par exemple parce que tu as une propriété dans ta classe enfant que tu dois initialiser). Dans ce cas tu commences par appeler la fonction de la classe parent, puis tu fais ton traitement spécifique à ta classe enfant dans la fonction de ta classe enfant.
Dans ton exemple, tu vas créer une instance de FrontendApplication. A ce moment, le constructeur de FrontendApplication est appelé. Celui-ci va, grâce à la ligne parent::__construct(), appelé la fonction parent et demander son exécution (mais ça ne va pas créer une nouvelle instance), puis le code suivant cette ligne va s'exécuté à son tour, toujours à l'intérieur de ton instance FrontendApplication.
Dans ton objet enfant, tu vas pouvoir faire un $this->httpRequest() par exemple pour appeler la fonction de base (puisqu'elle n'a pas été redéfinie dans la classe enfant). Et là ça ne te semble pas étrange. Avec le constructeur, tu ne peux pas faire la même chose, puisque tu as redéfinis la même fonction. Tu es donc obligé d'utiliser la notation parent:: pour indiquer que tu veux faire un appel à une fonction de la classe parent, et non pas une fonction de la classe enfant.
Bonjour je suis entrain de lire le cours sur la POO et je ne comprend pas exactement la différence entre une methode statique et une methode normal de même pour une variable statique et normale de plus quoi ils servent quels impact ont-ils sur le code(les statiques)
merci
On accède à une méthode statique sans avoir à créer d'instance de la classe, ce qui n'est pas le cas d'un méthode normale.
L'appel va se faire de la manière suivante : MaClasse::MaMethodeStatique. Cette méthode ne pourra pas utiliser de propriété de l'objet, sauf si celles-ci sont également statiques.
Une propriété statique est une propriété commune à toutes les instances de la classe.
Pour une méthode normale, il faut d'abord instancier la classe, puis appeler la méthode de l'instance (MonObjet->MaMethode), qui aura accès aux propriétés de l'objet instancié.
Je suis au chapitre 4 de la partie 1. J'utilise exactement le même code que dans le tuto mais j'ai des soucis avec mon manager.
Je n'arrive pas à utiliser les méthodes get() et getList(); elle ne renvoient rien, j'ai une page vide. Les autres méthodes fonctionnent. Voici l'intégralité de mon manager :
<?php
class personnages_manager
{
private $_db;
public function __construct($db)
{
$this->setDb($db);
}
public function add(personnage $perso)
{
// Préparation de la requête d'insertion.
$q = $this->_db->prepare(" INSERT INTO php_poo__personnages (id, nom, forcePerso, degats, niveau, experience) VALUES (NULL, :nom,:forcePerso,:degats,:niveau,:experience) ");
// Assignation des valeurs pour le nom, la force, les dégâts, l'expérience 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);
// Exécution de la requête.
$q->execute();
}
public function delete(personnage $perso)
{
$this->_db->exec('DELETE FROM php_poo__personnages WHERE id = '.$perso->id());
}
public function get($id)
{
// Exécute une requête 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 php_poo__personnages WHERE id = '.$id);
$donnees = $q->fetch(PDO::FETCH_ASSOC);
return new personnage($donnees);
}
public function getList()
{
// Retourne la liste de tous les personnages.
$persos = [];
$q = $this->_db->query('SELECT id, nom, forcePerso, degats, niveau, experience FROM php_poo__personnages ORDER BY nom');
while($donnees = $q->fetch(PDO::FETCH_ASSOC))
{
$persos[] = new personnage($donnees);
}
return $persos;
}
public function update(personnage $perso)
{
// Prépare une requête de type UPDATE.
$q = $this->_db->prepare('UPDATE php_poo__personnages SET forcePerso = :forcePerso, degats = :degats, niveau = :niveau, experience = :experience WHERE id = :id');
// Assignation des valeurs à la requête.
$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);
$q->bindValue(':id', $perso->id(), PDO::PARAM_INT);
// Exécution de la requête.
$q->execute();
}
public function setDb(PDO $db)
{
$this->_db = $db;
}
}
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Lead Developer PHP
Making functional apps for digital products @NEOTIC
-
Lead Developer PHP
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Lead Developer PHP
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Making functional apps for digital products @NEOTIC
-
Lead Developer PHP
Lead Developer PHP