Collection d'objet avec mysql et Iterator
Bonjour !
voila je fais une requete qui recupère tous les utilisateurs
j'avais commencer ça ici :
http://www.apprendre-php.com/forums/topic-125-collection-et-iterator-pour-applcation-crud.html
bon j'utilise la meme class dans le meme shema et je voudrais rajouter une methode qui récupère tous les utilisateurs ! pour ça pas de problème une requete SQL !
mais après c'est le traitement de ces informations qui m'interesse !
je voudrais reproduire ce shema fais en JAVA !
exemple: juste les methodes
public List<Contact> getContactOrdonneParNom() throws ContactDAOException {
String query = "SELECT * FROM " + T_CONTACT + " ORDER BY " + C_NAME;
ResultSet rs;
try {
rs = getDBConnect().executeQuery(query);
} catch (SQLException e) {
throw new ContactDAOException(MESSAGE_CONEXION_DB, e);
}
return MySQLContactDAO.resultSetToContact(rs);
}
public void removeContact(int idContact) {
}
private static List<Contact> resultSetToContact(ResultSet rs)
throws ContactDAOException {
List<Contact> result = new ArrayList<Contact>();
Contact contact;
try {
while (rs.next()) {
contact = new Contact(rs.getInt(C_ID), rs.getString(C_NAME), rs
.getString(C_FIRSTNAME), rs.getString(C_COMPANY), rs
.getString(C_PHONENUMBER), rs.getString(C_EMAIL), null);
Date date = rs.getDate(C_BIRTHDAYDATE);
contact.setBirthDayDate(MySQLContactDAO.dateToCalendar(date));
result.add(contact);
}
} catch (SQLException e) {
throw new ContactDAOException(MESSAGE_CONEXION_DB, e);
}
return result;
}
je sais qu'on fais une liste de contact dans cette exemple !
je vois comment ça marche mais je voudrais un oup de main pour reproduire en php !
si je peux ajouter les meme methode en php dans ma class MYSQLUserDAO
je penses que je vais devoir faire une collection et la parcourir avec Iterator !
mais j'aimerais quelque conseille pour commencer ça avec MYSQL!
merci de votre aide !
Réponses apportées à cette discussion
Pour faire une collection d'objets c'est tout simple. Voilà comment procéder grosso modo :
<?php class CollectionDao implements Countable, Iterator, ArrayAccess{ protected $collection = array(); // Tu réimplentes toutes les méthodes des interfaces // ... public function add($object) { $this->collection[] = $object; }} class UserDao{ protected $first_name = null; protected $last_name = null; // Methodes d'hydratation public function hydrate(ResultSet $rs) { $this->setFirstName($rs->first_name); $this->setLastName($rs->last_name); } // Tu implémentes les accesseurs qui vont bien} class UserDaoTable{ public function findAll() { $con = DatabaseConnection::getInstance(); $stmt = $con->prepare('SELECT table.* FROM table'); $rs = $con->executeQuery($stmt); $collection = new CollectionDao(); while ($rs->next()) { $object = new UserDao(); $object->hydrate($rs); $collection->add($object); } return $collection; }}
Tu peux bien sûr gérer la création de la collection dans une méthode d'une classe abstraite TableDaoAbstract que dériverait la classe UserDaoTable.
Enfin dans ton contrôleur, tu récupères ta collection ainsi :
<?php $collection = UserDaoTable::getInstance()->findAll(); // Ou encore (syntaxe Doctrine ORM par exemple)$collection = TableDaoAbstract::getTable('UserDao')->findAll();
Et enfin dans ta vue HTML, tu fais :
<?php // Grâce à iterator tu peux itérer sur ta collection dans foreachforeach ($collection as $object){ echo $object->getFirstName() . ' '. $object->getLastName();}
++
Merci Emacs pour toutes ces informations !
Alors j'ai lu le tutorial sur iterator de ton site que je trouve très bien cependant mon problème avec
itérator c'est que j'ai encore du mal à l'implémenter car je l'ai pas encore bien assimilé !
donc j'ai commencer à l'implémenter dans la classe collection dis moi ce que tu en penses ?
class CollectionDao implements iCollection, Countable, Iterator, ArrayAccess
{
protected $collection = array();
protected $position = 0;
public function add(Object $o)
{
$this->collection[] = $o;
}
public function clear()
{
$this->collection = array();
}
public function remove(Object $o)
{
unset($this->collection[$this->position] = $o);
}
public function key()
{
return $this->position;
}
public function next()
{
$this->position++;
}
public function current()
{
$this->collection[$this->position];
}
public function rewind()
{
return $this->position = 0;
}
public function valid()
{
return ($this->count()) > $this->position ;
}
public function count()
{
return count($this->collection);
}
}
j'ai aussi mis une methode remove mais je t'avouerais que je suis pas sur de l'avoir fais comme il faut lol
Merci pour ton aide, j'apprends beaucoup niveau objet ici !
Hello !
je voulais savoir par rapport à cette méhtode en meme temps si il valait mieux que je travaille avec les setters ?
à la base j'ai fais une class Person une class User qui herite de la class Person mais j'ai mis dans le constructeur les paramètres du style id,firstname etc et j'appel le constructeur parent dans la class User !
mais php ne gère pas bien la surcharge des méthodes comme java !
donc je me demande si je devrais pas rien mettre en paramètre et inserer un user dans la base
dans le style $user->setFirstname = $_POST['firstname'] ...
ton avis sur la question serais le bien venue ;)
Hello,
Essaie avec cette implémentation que j'ai fait en m'appuyant sur la doc officielle :
class CollectionDao implements iCollection, Countable, Iterator, ArrayAccess
{
protected $collection = array();
public function add(Object $o)
{
$this->collection[] = $o;
}
public function clear()
{
$this->collection = array();
}
public function remove(Object $o)
{
// A réimplémenter autrement
}
public function key()
{
return key($this->collection);
}
public function next()
{
return next($this->collection);
}
public function current()
{
return current($this->collection);
}
public function rewind()
{
reset($this->collection);
}
public function valid()
{
return (false !== current($this->collection));
}
public function count()
{
return count($this->collection);
}
}
Tu ferais même bien d'utiliser l'interface IteratorAggregate pour ta collection comme le montre la doc officielle : http://fr.php.net/iterator
Quant à ta question, c'est mal de passer les paramètres par le constructeur car ça t'oblige à connaître tous les paramètres et à les avoir sous la main. Dans la mesure du possible, fais un constructeur vide et mets un setter pour chaque attribut :
<?php
class Person
{
protected $id = null;
protected $firstName = null;
protected $lastName = null;
public function setId($id)
{
$this->id = $id;
}
public function setFirstName($fistName)
{
$this->firstName = $firstName;
}
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
}
++
Hugo.
Merci Hugo !
en observant tous ca j'ai vu que tu as ecris plus haut :
class UserDaoTable
{
public function findAll()
{
$con = DatabaseConnection::getInstance();
$stmt = $con->prepare('SELECT table.* FROM table');
$rs = $con->executeQuery($stmt);
$collection = new CollectionDao();
while ($rs->next())
{
$object = new UserDao();
$object->hydrate($rs);
$collection->add($object);
}
return $collection;
}
}
et je j'ai vu une méthode
executeQuery que je retrouve dans la doc du lien ci dessous !
http://creole.phpdb.org/docs/api/creole/ResultSet.html
je connaissais pas !
par contre je vois pas pour ResultSet j'ai vu que ca existait !
en somme si j'ai bien compris le principe:
rs recupère le resultat de la base
puis dans la boucle je transforme un tuple en objet ! on est dans l'orm je penses !
c'etait le bus mais j'ai une erreur du genre Call to undefined methode SPDO::executeQuery()
parce que je l'ai pas redifini dans SPDO mais en faite je la connaissais pas ou bien j'ai du raté un épisode !
et pour implementer arrayAccess je vais essayé les 2 mtéhodes histoire de mieux comprendre SPL
par contre je commence à regarder la doc c'est pas encore évident pour moi car je connais pas trop à quoi correspond OffsetExists et autre...
thanks !
Bonjour
je recois une erreur :
il me dis que j'appel un methode next() qui n'existe pas !
et Warning: PDO::query() expects parameter 1 to be string, object given in
tu as créer une methode executeQuery je pense car elle n'existe pas dans la doc php
ma méhtode à moi est celle d'origine:
public function execute($statement) { if(!$stmt = $this->PDOInstance->query($statement)) return false; return new PDOStatement($stmt); }
et ma methode que tu ma suggéré en php
public static function findAll() { $connection = self::getConnection(); $stmt = $connection->prepare('SELECT * FROM '.self::T_USERS); $rs = $connection->execute($stmt); $collection = new CollectionDao(); while($rs->next()) { $customer = new Customer(); $customer->hydrate($rs); $collection->add($users); } return $collection; }
c'est la methode next qui pose problème pourquoi ? devais je l'implementer quelque part d'autre ?
ou PDO normalement l'a déjà implementer ? si c'est le cas pourquoi je n'arrive pas a le faire fonctioner ?
++ Vini
Il faut que tu te crées ta propre classe de Statement et de ResultSet.
As tu eu des soucis comme: ... must therefore be declared abstract or implement the remaining methods ... pour ArrayAccess?