Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour à tous,
Ces derniers jours, je m'intéresse de nouveau à Zend Framework puisque le framework que j'utilisais jusque là (CakePHP) ne correspond plus à mes attentes. J'ai besoin de souplesse.
Le problème, c'est que je ne m'en sors pas avec Zend_Db et son utilisation avec MVC.
J'aimerai définir une unique fois mon adaptateur par défaut. En lui précisant que je souhaite avoir des objets en retour.
Mon but est ensuite de définir mes modèles et ses méthodes. Le problème, c'est que je n'arrive pas à déterminer de quel objet je dois faire hériter mes modèles pour pouvoir faire toutes les opérations dedans. Je veux pouvoir faire du $this->query(), du $this->fetchAll() et tout autre méthode utile pour créer des méthodes à mon modèle.
Ainsi, dans mon contrôleur, je veux voir apparaître :
$message = new Message(); $this->view->newMessages = $myModel->getNewMessages();
Que me conseillez-vous ? Je cherche une solution propre et élégante (d'un point de vue bonne pratiques, j'entends) et les articles que j'ai lu à ce sujet ne m'ont pas vraiment satisfait et mes expérimentations se sont révélées… Mitigées. :p
Question bonus, qui n'a pas grand chose à voir : où est-il conseiller d'insérer de la logique qui sera commune à la totalité de l'application (par exemple la définition d'une constante, etc.). Les variables que je définissais dans mon boostrap étaient inconnues à mes actions… Zend_Registry semble adapté mais j'ignore s'il s'agit d'une bonne pratique. N'est-t-il pas destiné aux informations liées à la configuration ?
Je vous remercie d'avance,
Sephi-Chan
Dernière modification par Sephi-Chan (17-10-2008 00:34:47)
Hors ligne
Salut,
J'aimerai définir une unique fois mon adaptateur par défaut. En lui précisant que je souhaite avoir des objets en retour.
Dans ton bootstrap ou dans ton fichier d'initialisation, ou encore celui dans lequel tu effectues la connexion à ta BDD (c'est un sujet récurrent, généralement on trouve la connexion à la BDD dans le bootstrap), juste après ta connexion tu peux faire :
Zend_Db_Table::setDefaultAdapter($objetDb);
Tes modèles utiliseront (sauf si tu leur dis le contraire) par défaut cet adaptateur DB.
Ensuite pour définir tes modèles, rien de bien compliqué, tu dois créer une classe héritant de 'Zend_Db_Table_Abstract' et définir à l'intérieur tes méthodes particulières.
Par exemple tu auras :
class Message extends Zend_Db_Table_Abstract { protected $_name = 'message'; protected $_primary = 'message_id'; public function getNewMessages() { $select = $this->select(...) ->where(...) ->order(...); return $this->fetchAll($select); } }
Si tu ne définies pas de '$_name', ta classe doit porter le même nom que ta table.
Ensuite dans ton action:
Zend_Loader::loadClass('Message'); $messages = new Message(); $nouveaux_messages = $messages->getNewMessages();
Pour les constantes, si tu les définies dans ton Bootstrap, elles seront accessibles de n'importe où : controlleurs/actions, vues, etc.
Inutile de les insérer dans le registre.
Voilà, c'est un début de réponse, n'hésite pas à poser des questions pour la suite (et à regarder la doc de zend aussi qui n'est pas trop mal faite pour Zend_Db :p).
A+ benjamin.
Dernière modification par Delprog (17-10-2008 09:25:58)
Hors ligne
comme dit plus haut, tu dois étendre Zend_Db_Table_Abstract et Zend_Db_Table_Row_Abstract.
J'ai le souvenir que c'est plutot bien expliqué dans le manuel.
Hors ligne
Merci pour vos réponses.
Je n'étais donc pas trop loin de la solution que je cherchais, mais je bloque encore un peu sur Zend_Db.
En fait, j'aimerai vraiment pouvoir écrire mes requêtes à la main (le chaînage des clauses me gonfle profondément et je n'ai pas besoin d'abstraction), ce que ne me permet pas Zend_Db_Table_Row_Abstract.
Je me paume dans la quantité impressionnante de classes. J'espère que je vais m'y habituer rapidement. :p
Sephi-Chan
Hors ligne
En fait, je me rends compte que ce n'est pas si compliqué que ça. Par contre, un problème subsiste et il m'énerve au plus au point.
try { $select = $this->select() ->from( array('u' => 'users'), array('id', 'username') ) ->where('id = ?', 1) ; echo $select; return $this->fetchAll($select); } catch(Exception $e){ echo '<p>'.$e->getMessage().'</p>'; }
La requête générée est bonne. Mais cette portion de code lance une exception qui n'est pas capturée ! Pourquoi !? Le catch devrait pourtant bien capter l'exception lancée à un niveau inférieur !?
Fatal error: Uncaught exception 'Zend_Db_Table_Row_Exception' with message 'Specified column "name" is not in the row' in /Applications/MAMP/htdocs/Dogmes/library/Zend/Db/Table/Row/Abstract.php:182 Stack trace: #0 /Applications/MAMP/htdocs/Dogmes/application/views/scripts/index/index.phtml(7): Zend_Db_Table_Row_Abstract->__get('name') #1 /Applications/MAMP/htdocs/Dogmes/library/Zend/View.php(107): include('/Applications/M...') #2 /Applications/MAMP/htdocs/Dogmes/library/Zend/View/Abstract.php(787): Zend_View->_run('./application/v...') #3 /Applications/MAMP/htdocs/Dogmes/library/Zend/Controller/Action/Helper/ViewRenderer.php(921): Zend_View_Abstract->render('index/index.pht...') #4 /Applications/MAMP/htdocs/Dogmes/library/Zend/Controller/Action/Helper/ViewRenderer.php(942): Zend_Controller_Action_Helper_ViewRenderer->renderScript('index/index.pht...', NULL) #5 /Applications/MAMP/htdocs/Dogmes/library/Zend/Controller/Action/Helper/ViewRenderer.php(981): Zend_Controller_Action_Helper_ViewRenderer->render() #6 /Applications/ in /Applications/MAMP/htdocs/Dogmes/library/Zend/Db/Table/Row/Abstract.php on line 182
Ce framework me rend fou ! Je ne comprends absolument pas pourquoi cette fichue exception est envoyée. Et également pourquoi elle n'est pas attrapée.
Sephi-Chan
Hors ligne
Hello,
T'aurais pas xDebug par exemple ?
Si oui, l'option "xdebug.show_exception_trace" est à "On" et attrape tout. Mets là à "Off".
A+
Dernière modification par mikaelkael (18-10-2008 12:39:40)
Hors ligne
Je m'excuse d'avance pour ce triple post, mais ça me semble adapté puisque j'apporte une solution à mon problème, au cas où ça puisse aider quelqu'un.
Voici donc mon contrôleur :
class UserController extends Zend_Controller_Action { /** * Liste les utilisateurs. */ public function indexAction(){ $this->view->title = "Accueil"; try { $user = new User(); $this->view->users = $user->get(1); } catch(Exception $e){ echo '<p>'.$e->getMessage().'</p>'; } } }
Et voici le modèle :
class User extends Zend_Db_Table_Abstract { protected $_name = 'users'; public function get($id){ $select = $this->select() ->from( array('u' => 'users'), '*' ) ->where('id = ?', $id) ; $ressource = $select->query(); return $ressource->fetchAll(); } }
Ça marche bien, il me manquait une étape.
Que puis-je modifier pour être plus respectueux des bonnes pratiques (et celles de Zend Framework) ?
En tout cas, merci pour l'aide apportée,
Sephi-Chan
Edit : Non, je n'ai rien de tel.
Dernière modification par Sephi-Chan (18-10-2008 12:42:55)
Hors ligne
Hello,
Désolé, j'avais mal lu. Ton exception est renvoyé plus loin dans ton code. C'est pour ça que tu ne l'attrapes pas où tu l'as prévu.
C'est le code de ta vue ("index.phtml") qui comporte l'erreur. Quelles sont les colonnes de table et le code de ta vue STP ?
A+
Hors ligne
Exact Mikaelkael, l'erreur était bien renvoyée par la vue !
Je ne m'attendais pas à ce que cette dernière renvoie quelque chose (dans CakePHP, l'inexistence d'une variable de vue lance une parse error classique). J'ai été bête de ne pas penser à ça.
En tout cas merci à vous tous.
Sephi-Chan
Hors ligne
Salut,
Sauf si j'ai mal lu, je pense qu'il y a plus simple que ta fonction 'Get' Sephi-Chan.
Penche toi sur la doc, car il existe une fonction find() qui est faite pour récupérer des enregistrements par clé_primaire.
Donc tu peux l'utiliser rien qu'en héritant de Zend_Db_Table_Abstract.
Mis à part ça, tu as compris le principe visiblement
A+ benjamin.
Hors ligne
C'est vrai qu'il y a le find(), mon get() me servait à créer tester l'utilisation de méthodes personnalisés. Merci de me la rappeler, en tout cas ! ^^
Sephi-Chan
Hors ligne
Sephi-Chan a écrit:
Bonjour à tous,
.....
Sephi-Chan
salut je pense que tu vas trouver matière à su mon blog
http://sekaijin.ovh.org/?p=3 * Organisation des dossiers
http://sekaijin.ovh.org/?p=4 * Zend_Framework BootStrap
http://sekaijin.ovh.org/?p=7 * Gérer la configuration d’une application
http://sekaijin.ovh.org/?p=10 * Le front Contrôleur
http://sekaijin.ovh.org/?p=15 * Utiliser une façace pour accéder au modèle
http://sekaijin.ovh.org/?p=17 * Utiliser une base de données avec Zend Framwork
A+JYT
Hors ligne