acidline
Messages postés21Date d'inscriptionvendredi 9 décembre 2005StatutMembreDernière intervention21 juillet 2008
-
16 juil. 2008 à 17:15
bZx -
20 nov. 2010 à 15:22
Bonjour à tous,
Je me présente, je m'appelle Nicolas, j'ai 24ans et la POO en PHP est nouveau pour moi.
Je me suis mis en tête d'utiliser la class de news posté par FhX (lien sur phpcs)
Super leçon d'architecture Web en PHP, utilisation des design pattern (Factory, Singleton) mais je suis perdu lorsqu'il faut l'utiliser...
en gros mon problème est :
comment on récupère le resultat quand on fait un getMultipleNews(0,3) ?
j'ai comme code :
$NewsFactory = new NewsFactory();
$news = $NewsFactory->GetMultipleNews(0,3);
var_dump($news);
le truc c'est que le var_dump me renvoi bien un array mais qu'avec une seule news dedans... ! je comprends pas pourquoi...
Ensuite comment on fait pour utiliser la méthode AddNews, le truc c'est que cette méthode est typé NewsObject d'accord donc quand je fais ça est-ce correct ?
Code:
$monActu = array("titre"=>"Un test de titre", "contenu"=>"Un contenu");
$ajoutActu = new NewsObject($monActu);
$NewsFactory = new NewsFactory();
$news = $NewsFactory->AddNews($ajoutActu);
je sais pas si c'est bon mais ça fonctionne pas !
Bref, si quelqu'un avait des réponses et/ou des solutions, se serait merveilleux !!!
Merci de votre aide, moi je suis dans le brouillard et là je vois plus rien
Nicolas
ps: j'ai posté un commentaire demandant des exemples, je lui ai écrit un message privé et maintenant je poste sur le forum... je sais je suis un boulet !
// Il faut indiquer si les valeurs sont valides ou pas, afin d'indiquer au boucles (foreach, while) quand s'arreter)
// Je teste donc mon tableau pour savoir s'il vaut false, c'est la fin du fetching dans mysql, donc on arrete !
// Comme mon tableau avait été à l'originie initialisé à array () (voir en tete de la classe), la premiere fois que la méthode valid est appelée, elle possede array () et pas false.
// Si on avait pas mis la valeur par défaut à array (), la valeur aurait été nulle
J'ai mis en commentaires (en gras) les modifications que j'ai faites.
Maintenant ca marche chez moi, donc ca devrait etre bon chez toi aussi !
Si tu a aussi un probleme d'encodage, utilise utf8_encode (ou decode je sais jamais :p)
Oui je pouvais attendre jusque lundi, mais tu te serai arraché la tete tout le week end ! :)
Je t'invite par contre à regarder les classes d'abstractions sgbd que tu trouvera sur phpcs et réalisée par Fhx, Malalam, et moi même, entre autres, nous utilisons les itérateurs, qui montrent un très bon exemple de leur implémentation. Tu comprendra ptete mieux leur utilité et leur fonctionnement (vu que dans ton cas tu ne vérifiait pas la validité (méthode valid) par exemple :))
codefalse
Messages postés1123Date d'inscriptionmardi 8 janvier 2002StatutMembreDernière intervention21 avril 20091 17 juil. 2008 à 12:40
$news = $NewsFactory->GetMultipleNews(0,3);
$news ne retourne qu'une valeur car il faut itérér dessus pour avoir les autres
si tu fait un
foreach ($news as $new) {
var_dump ($new);
}
tu devrais avoir 3 var_dump d'affiché
Pour ton probleme d'ajout de news, ca devrait marcher
que te retourne un
var_dump ($ajoutActu); ?
codefalse
Messages postés1123Date d'inscriptionmardi 8 janvier 2002StatutMembreDernière intervention21 avril 20091 17 juil. 2008 à 14:23
A en voir le code, le problème se situerait dans son code.
En effet, par défaut, la sortie est un objet.
Il fait un fetch_array (return $this->{$this->_option['outputMethod']}( $this->db->fetch_array() );
) dans la méthode toObject, qui fait instancie la classe NewsObject avec le tableau en parametre.
Le probleme, c'est que NewsObject n'est là que pour une entrée. Il devrait faire plusieurs instances de NewsObject. Donc voila pourquoi tu n'a qu'une entrée !
Tu utilise quoi pour l'acces à la base de donnée ?
Parce que Fhx utilise une classe propre à lui apparement, tu l'a récupérée aussi ?
Personnellement, à moin bien t'y connaitre en poo, tu peux changer de classe :p
Pour récuperer les valeurs tu peux directement utiliser les tableaux et dans getMultipleNews, tu peux remplacer return $this->{$this->_option['outputMethod']}( $this->db->fetch_array() );
par return $this->db->fetch_array(); (en espérant qu'il te retourne un array complet)
Si tu veux passer par la classe NewsObject, va falloir implémenter du Iterator :p
Tu peux aussi contacter Fhx (en mp ou sur sa source directement) afin de lui indiquer que sa source à quelques problemes en espérant qu'il aie le temps de la remettre à jour :)
acidline
Messages postés21Date d'inscriptionvendredi 9 décembre 2005StatutMembreDernière intervention21 juillet 20081 17 juil. 2008 à 14:31
c'est exactement ce que je ne voulais pas entendre !!!
en effet j'utilise ma propre class mysql, je savais (et tu me l'as confirmé) que le problème venait de l'instanciation des objets NewsFactory, en fait tel quel, le resultat précédent et écrasé par le resultat suivant, d'ou la récuperation unique de la dernière actu demandé.
ta solution est valide, je l'ai essayé, mais c'est un peu bête de sortir de la fabrique sans passé par une sortie NewsObject !!!!
j'ai déjà demandé de l'aide à FhX en message privé mais il ne m'a pas donné signe de vie (et oui les vacances !)
je vais plancher sur Iterator, ça va donner l'occasion de l'implémenter...
je reste quand même ouvert aux solutions !!! plus on est de fous, plus on rit !
codefalse
Messages postés1123Date d'inscriptionmardi 8 janvier 2002StatutMembreDernière intervention21 avril 20091 17 juil. 2008 à 14:48
Je sais pas si tu à déjà joué avec des itérator en php. Si non je peux te donner une idée de structure pour le code de Fhx et donner quelque chose d'a peu pres fonctionnel.
Tu va faire une classe NewsIterator (par exemple) qui implémente Iterator, Seekable (optionnel) et Countable.
Tu implémente toutes les fonctions nécéssaire (renseigne toi du coté de la spl pour cela). Tu fait un constructeur qui accepte un tableau en entrée, tableau que tu stockera dans une variable privée.
Chaque appel à la méthode current retournera une instance de NewsObject avec le tableau $aTableau[$iIndex]. $iIndex étant un variable qui indique l'index de la position dans le tableau (qui démarre à -1 lors de l'instanciation, et qui est incrémenté de +1 à chaque appel de next).
Je te conseil par ailleur d'éviter de faire return new NewsObject ($aTableau[$iIndex]) dans la méthode current, au cas ou l'utilisateur ferait plusieurs fois appel à current.
Mais plutot de mettre dans next un truc du genre
$this->_iIndex++;
$this->_oCurrentNewsObject = new NewsObject ($aTableau[$this->iIndex]) ;
et de ne retourner que $this->_oCurrentNewsObject lors de l'appel à current ();
count () retourne count ($this->_aTableau);
Et dans la méthode GetMultipleNews de Fhx, tu fait
return new NewsIterator ($this->db->fetch_array());
Bon du coup tu perd toute la possibilité de l'option Objet/Xml mais bon ...
acidline
Messages postés21Date d'inscriptionvendredi 9 décembre 2005StatutMembreDernière intervention21 juillet 20081 17 juil. 2008 à 15:27
ok je vais tenter un truc du genre !
mais j'ai menti avant en fait tu m'as dit
Pour récuperer les valeurs tu peux directement utiliser les tableaux et dans getMultipleNews, tu peux remplacer returnoutputMethod']}(
$this->db->fetch_array() ); par return
$this->db->fetch_array(); $this->{$this->_option['(en espérant qu'il te retourne un array
complet)
oups ! le truc retourne pas un arret complet ! ce que je ne comprends pas...
je vais tenter de créer la class IteratorNews... je te tiens au jus... j'espere que tu vas avoir encore un peu temps à me consacrer !
//constructeur
public function __construct($mesActus) {
if(is_array($mesActus) {
$this->mesActus = $mesActus
}
}
//rambobine le tableau
public function rewind() {
reset($this->mesActus);
}
//retourne la position courante
public function current() {
return $this->_oCurrentNewsObject;
}
//retourne la clé
public function key() {
$mesActus = key($this->mesActus);
return $mesActus;
}
//accéde à la position suivante
public function next() {
$this->position++;
$this->_oCurrentNewsObject = new NewsObject($this->mesActus[$this->position]) ;
}
//valide l'objet en cours
public function valid() {
$mesActus = $this->current() !== false;
return $mesActus;
}
//méthode pour compter les objets
public function count() {
return sizeof($this->mesActus);
}
}
tu peux corriger le truc, je commence à comprendre l'interet des Iterateurs...
codefalse
Messages postés1123Date d'inscriptionmardi 8 janvier 2002StatutMembreDernière intervention21 avril 20091 17 juil. 2008 à 21:35
//retourne la clé
public function key() {
$mesActus = key($this->mesActus);
return $mesActus;
}
pourquoi ne pas faire
return key($this->mesActus);
//valide l'objet en cours
public function valid() {
$mesActus = $this->current() !== false;
return $mesActus;
}
idem
Après je n'ai rien de spécial à dire, ton code est correct.
Comme tu le vois, c'est ultra simple d'utiliser les itérateurs, et c'est super utile et très puissant !!!! :)
Par ailleur, les itérateurs, c'est qu'un début ! Ca fait partie de la Spl, si tu jete un oeil aux autres possibilités, tu va voir que les options sont infinies.
Par contre, ne pas oublier, php doit tourner en 5.2 !! (T'a vérifié sur ton serveur ? (je parle en connaissance de cause :p))
acidline
Messages postés21Date d'inscriptionvendredi 9 décembre 2005StatutMembreDernière intervention21 juillet 20081 18 juil. 2008 à 09:15
Bonjour CodeFalse,
j'ai envie de dire c'est le b....l ! j'ai un problème avec l'implémentation de l'itérateur, du style "Notice: Undefined offset: 1 in ..."
bref, en gros quand je fais un print_r dans le constructeur de NewsIterator j'ai qu'une news !!!!!!!!!!
ça veut dire que lorsque j'appelle new NewsIterator dans le return de GetMultipleNews j'ai toujours qu'une actu... je pete les plombs !
Revoici la méthode :
public function GetMultipleNews($start, $limit) {
if( !$this->flag) {
$requete = 'SELECT
id, titre, contenu, dateInsertion,dateModification
FROM actualites
WHERE publication="1"
ORDER BY id DESC LIMIT '.$start.', '.$limit;
Le truc c'est lorsque je fais un while direct dans la méthode c'est ok !
je sors un tableau associatif ... (mysql_fetch_assoc), devrais-je sortir en mysql_fetch_array ? (je vais tester)
codefalse
Messages postés1123Date d'inscriptionmardi 8 janvier 2002StatutMembreDernière intervention21 avril 20091 18 juil. 2008 à 09:42
Ah mon avis, le probleme vient de la classe de gestion à la bdd.
L'appel à la méthode get_array te retourne qu'une entrée. Peut-etre existe-t-il une autre méthode du style getAllArray ?
Bon, ce n'est pas ce qui est recommandé.
Dans le cadre d'un retour de query, il est préférable de passer l'instance de l'objet bdd à ton itérateur, qui fera un fetch dans le next, et récupere le résultat sous forme de tableau qu'il retourne.
Donc probablement que ton code ne devrait pas etre
//return $this->{$this->option['sortie']}($this->db->get_array($resultat) );
mais ca :
return new NewsIterator($this->db, $resultat);
Dans ton constructeur tu met
public function __construct ($oDb, $rResult) {
$this->_oDb = $oDb;
$this->_rResult = $rResult;
}
et là dans ton next tu met un
$this->_aCurrentArray = $this->_oDb->get_array($rResultat);
//constructeur
public function __construct ($Db, $Resultat) {
$this->Db = $Db;
if (is_array($Resultat) { $this->Resultat = $Resultat; }
}
public function rewind() {
}
public function current() {
return $this->actuCurrentArray;
}
public function key() {
}
public function next() {
$this->actuCurrentArray = $this->Db->get_array($this->Resultat);
}
public function valid() {
}
}
je sais pas si c'est bon, le truc c'est que si je fais un echo dans le constructeur de NewsIterator, je devrais avoir affiché le message 3 fois non ?! parce que j'ai q'un message qui s'affiche....
acidline
Messages postés21Date d'inscriptionvendredi 9 décembre 2005StatutMembreDernière intervention21 juillet 20081 18 juil. 2008 à 11:27
pardon pour l'erreur, effectivement $Resultat est une ressource mysql.
cependant, je reste avec une page blanche, j'essaye d'effectuer une trace de passage dans next et j'y rentre pas ! je pense que la classe NewsIterator est fausse... (je déprime)
j'ai essayé un truc du genre dans le return du GetMultipleNews
public $output = array(); // propriété de la class NewsFactory
while ($data = $this->db->get_array($resultat) ) {
$this->output[] = $data;
}
codefalse
Messages postés1123Date d'inscriptionmardi 8 janvier 2002StatutMembreDernière intervention21 avril 20091 18 juil. 2008 à 12:26
Tu passe dans next quand tu fait un foreach, tu a bien fait un foreach ?
parce que normallement tu passe ton objet et ta ressource à ton itérateur, et tu fait un foreach sur ton objet, ca devrait marcher :
$tonNewsIterator = $tonObj->getAllNews (0, 3);
foreach ($tonNewsIterator as $oValue) {
// $oValue sera une instance de NewsObject
// car dans ton next tu aura fait un $this->_aCurrentObject = new NewsObject ($this->_oDb->get_array ($this->_rResult));
// donc :
echo $oValue->titre;
}
acidline
Messages postés21Date d'inscriptionvendredi 9 décembre 2005StatutMembreDernière intervention21 juillet 20081 18 juil. 2008 à 14:28
je dois vraiment déconné grave car j'arrive à rien avec les Itérateurs
Je résume, dis moi là ou ça déconne :
La méthode GetMultipleNews
public function GetMultipleNews($start, $limit) {
$requete = 'SELECT id, titre, contenu, dateInsertion,dateModification
FROM actualites WHERE publication="1" ORDER BY id DESC LIMIT '.$start.', '.$limit;
$resultat = $this->db->Send_Query($requete, $this->linkBDD);
return new NewsIterator($this->db, $resultat);
}
La class NewsIterator
class NewsIterator implements Iterator{