Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1 2
Voilà une question toute bete...
Est-ce que vous les définissez directement dans le controller :
function listeAction () { $reqArticle = $this -> _model -> select() -> from($this -> _model -> _name) -> where("`actif` = '1'") -> where ("`rubriques_uid` = 3"); $listeArticles = $this -> _model -> fetchAll($reqArticle); ... ... ... }
Ou bien vous passez par une méthode de votre model :
function renvoyerArticlesDe ($rubriques_uid) { $Select = $this -> select() -> from ($this -> _name) -> where("`actif` = '1'") -> where ("`rubriques_uid` = ?", (int) $rubriques_uid); return $this -> fetchAll($Select); } // Puis dans le controller function listeAction () { $listeArticles = $this -> _model -> renvoyerArticlesDe(3); ... ... ... }
Ne faites pas attention aux erreurs du genre "$this -> _model -> _name" c'est juste pour l'exemple.
Merci de vos retours et bon w-e
Cordialement,
Kaimite
Dernière modification par Kaimite (05-09-2008 10:50:50)
Hors ligne
idem, dans le modèle.
ça me permet de ne pas surcharger mes controlleurs, et de pouvoir reutiliser les methodes (surtout valable pour les requetes un peu compliquées, cela evite de copier/coller du code complexe ou bien de devoir reflechir plusieurs fois au meme problème)
Hors ligne
Ben de toute façon, le contrôleur gère les actions, le modèle le traitement des données (interaction avec la bdd et autres) et les vues s'occupent de la présentation des données.
Donc en tout logique, dans le modèle
Hors ligne
dans les classes du modèle en fonction de ce quelles remontent.
les requêtes qui remontent des infos client list de clients sont mise dans la classe Model_Client_Table cette classe remonte déjà les enregistrement de Client elle contient naturellement les requêtes généré par Zend_Db c'est elle aussi qui porte les insert et update. c'est donc là que j'ajoute les requêtes dont j'ai besoin.
je fait ainsi pour chaque type d'objet que je manipule.
c'est parfois un peu plus compliqué de trouver où placer les méthode qui font appel à une jointure. mais généralement ça vient assez vite.
par exemple la requête qui me remonte toutes les factures impayée d'un client avec toutes leurs lignes de facturations, leur adresses de livraison et de facturation.
à priori cette requête touche la table facture, la table ligne de facture. la table adresse (pour la livraison), client pour pouvoir joindre de nouveau adresse (pour la facturation). dans un cas comme ça je laisse parler la sémantique. cette requête remonte la liste des FACTURES impayées. c'est donc là que je vais la placer.
mais ce n'est pas toujours aussi évident. j'utilise très souvent des index alphabétiques. ces index permettent à l'utilisateur de cliquer sur une lettre et obtenir la liste des éléments correspondant. utilise ces index pour toute sorte de choses. pour afficher ces index je fait une requête qui pour chaque valeur de l'indexe compte le nombre d'élément présent dans la table. ainsi je peu griser les lettres qui n'ont pas à être cliquées. comme je l'utilise beaucoup la requête étant toujours la même je me suis fais une méthode qui prend en paramètre le nom de la table dans laquelle compter les éléments.
Où placer une telle requête. ici je n'ai aucun éléments sémantique pour le faire. je l'ai mise dans le modèle. mais dois-je en faire une classe spécifique ? l'attacher à autre chose ? je n'ai pas trouvé de solution satisfaisante.
A+JYT
Hors ligne
Personnelment je travail avec un systeme en couche :
- couche DAO ( data access object ) : je définit tout les entités & leurs DAO ( là où il ya les requettes sql ou si tu veut utiliser zend_db )
chaque entité --> leur propre DAO
exmple :
etudiant : je définit une calsse etudiant :
class Etudiant { private $nom ; private $prenom ; public function __construct($nom , $prenom ) { } ... ... je définit les setters & les getters }
après :
class EtudiantDAO { private $paramsConnexion ; // intialiser dans le constructeur public function __construct($paramsConnexion){ $this->paramsConnexion = $paramsConnexion } public function ajouterEtudiant(Etudiant $e) { // intialiser la connexion // lancer la requette en récupérer les données a partir de $e avec les gets } public function modiferEtudiant(Etudiant $e) { // meme principe } public function supprimerEtudiant(Etudiant $e) { // meme principe } }
- une couche manager : pour l'etudiant DAO
- les managers sont des singletons
class EtudiantManager { // une seul instance de la classe EtudiantManager sera crée private $singleton ; // 1 instance de la couche dao , il peut i ya voir 1 seul manager pour +ieurs dao private $etudiantDao; private function __construct(() { // $paramsConnexion : je récupére les parmètre de connexion ( nom de bd , user , mot pass ) // a partir d'une fichier config a l'aide de zend_registry & zend_config $this->etudiantDao = new EtudiantDao( $paramsConnexion); } public function getUniqueInsantce() { if($this->singleton == null ) $singleton= new EtudiantManager (); return $singleton; } // aprs les meme fonction que la couche dao , il peut i yavoir differnts combinaisson d'utilsation de +ieurs //DAO public function ajouterEtudiant(Etudiant $e) { // on peut traiter les exception ici aussi $this->etudiantDao->ajouterEtudiant($e); } public function modiferEtudiant(Etudiant $e) { // on peut traiter les exception ici aussi $this->etudiantDao->modiferEtudiant($e); } public function supprimerEtudiant(Etudiant $e) { // on peut traiter les exception ici aussi $this->etudiantDao->supprimerEtudiant($e); } }
et enfin dans mes controlleur je récupére mes manager avec la fonction getUniqueInstance & je fait appel au # fonctions
class IndexController extends Zend_Controller_Action { private $etudiantManager ; // le manger sera intiailisé pour tout les actions public function init() { $this->etudiantManager = EtudiantManager::getUniqueInstance(); } public function addAction() { // vous pouver récupérer apartir des post ou get $etudiant =new Etudiant("MOUNIR" ,"XXX" ); $this->etudiantManager->ajouterEtudiant($etudiant) ; } }
Avec ce modele , vous aurai un système en couche + une architecture MVC & c cool ça non !!!
j'espère que mon explication va vous aidé un peut .
merci .
euh , ... j oublié de dire que la couche DAO + Manger seront dans le package models
Dernière modification par mega_info (01-09-2008 00:13:10)
Hors ligne
Bonjour,
Merci pour vos réponses.
En fait j'ai vu, certains exemples avec dans le controlleur :
$this -> view -> Articles = $this -> _model -> fetchAll();
Donc je me posais la question.
En, général je créé une méthode avec 2-3 parametres :
function renvoyerArticle ($rubriques_uid, $pourAdmin = false) { $Select = $this -> select () -> from ($this -> _name, "uid") -> where ("`rubriques_uid` = ?", (int) $rubriques_uid); if ($pourAdmin == false) { $Select -> where ("`actif` = '1'"); } $Rows = $this -> fechRows($Select); }
C'est pas tout a fait ça mais en gros...
J'ai maintenant une autre petite question.
Pour la pagination comment vous y prenez vous pour faire la requête qui calcul le nombre de pages nécessaires à l'affichage de tous les résultats ?
Pour l'instant j'utilise un système un peu comme suit :
Dans le controller :
$listeArticles = $this -> _model -> renvoyerArticles($rubriques_uid, NB_ARTICLES_PAR_PAGE, $pageEnCours); $nbPagesArticles = $this -> _model -> renvoyerNbPages($rubriques_uid);
Cela veut dire que dans mon model j'ai deux fonction très proche au niveau du code :
public function renvoyerArticlesDe ($rubriques_id, $nbParPage = 0, $aPartirDe = 0, $pourAdmin = false) { $select = $this -> select() -> from($this -> _name, 'uid') -> where('`rubriques_id` = ?', $rubriques_id); //--> SI POUR FRONT ON NE RENVOI QUE LES ARTICLES ACTIFS if ( !$pourAdmin ) { $select -> where ("`actif` = '1'"); } $select -> order ("date_ajout DESC"); //--> TEST SI PAGINATION if ( is_numeric($nbParPage) and $nbParPage > 0) { $select -> limitPage($aPartirDe, $nbParPage); } $Rows = $this -> fetchAll($select); if ( sizeof($Rows) > 0 ) { foreach ($Rows AS $Row) { $Row = $Row -> toArray(); $Retour[] = new Article($Row['uid']); } return $Retour; } else { return false; } } public function renvoyerNbPagesArticlesDe ( $rubriques_id, $nbParPage, $pourAdmin = false) { $select = $this -> select() -> from($this -> _name, 'COUNT(`uid`) AS nbArticle') -> where('`rubriques_id` = ?', $rubriques_id); //--> SI POUR FRONT ON NE RENVOI QUE LES ARTICLES ACTIFS if ( !$pourAdmin ) { $select -> where ("`actif` = '1'"); } $Row = $this -> fetchRow($select); if ( $Row != false ) { return ceil($Row -> nbArticle / $nbParPage); } else { return false; } }
En général les clause "where" seront les mêmes dans les deux requêtes. Y a t'il moyen d'éviter de les définir deux fois ?
Encore merci pour vos réponses.
Cordialement,
Kaimite
Hors ligne
A mon choix
1 - j'utilise LIMIT de sql et limit_min et limit_max
2- je lance après une autre raquette de SELECT count(*) sans LIMIT pour savoir le nombre d'enregistrement .
après tu devise la résultat de count sur le nombre d'enregistrement dans une page ( exemple : 10 éléments dans une page ) .
Hors ligne
pas super optimisé, 2 requetes SQL => 2 interogation du serveur avec les temps de connexion, identification, latence, etc.
function paginate($array, $nbItem, &$nbElt, $which = 1){ if ( count($array) > $nbItem ){ $newArray = array_chunk($array, $nbItem); $nbElt = count($newArray); if ( isset($newArray[$which-1]) ){ $array = $newArray[$which-1] ; }else{ throw new Exception(sprintf('Cannot acces %d sub array', $which)); } } return $array; }
Je suis pas sur du code, mais l'idée est la, la flemme de faire un copier coller des classes permettant de le gérer
Hors ligne
IL n'y pas un élement Paginator dans le nouveau Zend 1.6 ??
Hors ligne
@ndesaleux :
Si j'ai bien compris tu fais une seule requete sans LIMIT et c'est ta fonction qui extrait uniquement les informations voulues....
J'vais chercher dans ce sens.
@tout le monde :
Prenons un exemple (qui ne m'arrive pas souvent mais c'est pour savoir).
Cas 1 :
Je fais une requête unique (sans utiliser LIMIT) qui renvoit 10 000 enregistrements et je décide de n'afficher que les enregistrements du 120 au 140
Cas 2 :
Je fais une requête avec un LIMIT qui me renvoi les 20 enregistrements que je veux afficher.
Je fais une 2nde requête qui me renvoi un seul résultat pour calculer le nombre de page et déduire la LIMIT de la page suivante.
Quel cas est le plus optimisé.
Merci pour vos infos
Cordialement,
Kaimite
Hors ligne
Je viens de mettre à jour mon ZF avec la version 1.6 et j'ai testé le Zend_Paginator.
Très simple à mettre en place et à utiliser
Au niveau des requêtes ça ne change pas grand chose :
SELECT COUNT(*) AS zend_paginator_row_count FROM `tbl_articles` SELECT `tbl_articles`.`uid` FROM `tbl_articles` LIMIT 10 OFFSET 80
En tout cas c'est très simple à mettre en place !
Hors ligne
Je ne pense pas que faire une seule requète soit bien.
Si la base est petite, ca va, mais si ca se compte en millier de lignes, bonjour le temps que va prendre le select..
Hors ligne
Zend_Paginator sait gérer les objets Zend_Db_Select :
$select = $db->select()->from('personnes', array('nom', 'prenom')); $paginator = Zend_Paginator::factory($select); $paginator->setCurrentPageNumber((int)$_GET['page']); $paginator->setItemCountPerPage(2); foreach ($paginator as $item) { echo $item['nom'] - $item['prenom'], PHP_EOL; }
Hors ligne
En effet.
Je suis en train de mettre en place ma pagination.
Merci à nORKy pour en avoir parlé
J'en profite pour passer une petite infos que j'ai eu lors d'une formation sur le référencement.
Je veux paginer une liste d'articles. L'url de la page est :
http://www.exemple.com/articles/liste/rubrique/95
Pour ma pagination je vais donc avoir les urls du style :
http://www.exemple.com/articles/liste/r … /95/page/1
http://www.exemple.com/articles/liste/r … /95/page/2
http://www.exemple.com/articles/liste/r … /95/page/3
http://www.exemple.com/articles/liste/r … /95/page/4
...
Et bien si voulez vraiment optimiser votre référencement l'url "page/1" ne doit pas exister !
Pourquoi ? Tout simplement par ce que vous aurez une même page qui sera accessible par 2 urls différentes :
http://www.exemple.com/articles/liste/r … /95/page/1 et http://www.exemple.com/articles/liste/rubrique/95, pour Google : Deux pages différentes.
Pour y remédier il suffit, dans le helper de pagination, de détecter si c'est le "1" et de ne pas ajouter "page/1" à la fin de l'url.
Voilà
En tout cas merci pour vos remarques et bonne fin de journée
Kaimite
Hors ligne
Merci pour l'astuce Kaimite, c'est tellement bête qu'on y pense pas forcément
Hors ligne
Bonjour, une question qui fait suite à ce topic.
Est-ce que quand vous faites un truc du genre :
-je récupère les valeurs du formulaire, puis $modele=modeles->createRow, attribution des valeurs,$modele->save, etc...vous le faites dans le modele aussi ????? ou dans le controlleur?
Merci pour cette réponse car du coup je suis un peu dans le flou.
Pour ma part, toutes les requtes répétitives et ré-utilisées sont ecrite dans une fonction du modèle, quant à tout ce qui est de l'ordre de CRUD ou unique pour un controller/action donné, c'est dans le controller.
Ce que jai fait, c'est mal ? (pour MVC) ?
Merci encore.
Hors ligne
Salut,
Je dirais logiquement que c'est au model de gerer les actions la base de données (insert, update, delete).
Pour ma part mes models étendent une class perso afin d'y coder les méthodes communes à toutes mes tables.
@++ Kaimite
Hors ligne
pas tout a fait le modèle doit encapsuler la couche de persistance
c'est cette dernière qui assure la gestion des requête à la base si le modèle s'appuie sur une base bien sur.
ta classe perso qui étant les fonctions communes à toute tes table est typiquement une classe d'accès aux donnée
sur laquelle on bâtit la persistance.
le métier lui ne s'occupe pas de comment on lit ou écrit les donnée il s'occupe de ce qu'on peu faire avec quelle son les règles qui le régissent.
le contrôleur lui s'occupe de comment on utilise le modèle
Hors ligne
Merci pour ces réponses. Si j'ai bien compris sekaijin, si le controlleur s'occupe de comment on utilise le modèle, est-ce que c'est lui qui ecrit ?
Dans le cas contraire, ca veut dire que dans votre controller vous faites un truc du genre :
$modeles=new Modele(); modeles->creerModele($mes données...)
et donc dans la classe Modele :
public function creerModele($mes donnees) { $m=$this->createRow(); ----assignation des parametres ..... $m->save(); }
???
Hors ligne
Pages: 1 2