Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 19-03-2008 15:44:22

larenzu
Membre
Date d'inscription: 04-03-2008
Messages: 77

probleme dans mon model

Rebonjour a tous le monde

voici mon souci qui me rend fou.

j'ai mon model utilisateur.php :

Code:

 
<?php
 
Zend_Loader::loadClass("Zend_Db_Table_Abstract");
Zend_Loader::loadClass("Zend_Db_Table_Row_Abstract");
 
 
class Utilisateur_Table extends Zend_Db_Table_Abstract {
 
    protected $_name = 'utilisateur';
    protected $_rowClass = 'Utilisateur_Row';
 
   
}
class Utilisateur_Row extends Zend_Db_Table_Abstract {
    
}

voici mon controleur UtilisateurController.php :

Code:

 
<?php
 
require_once 'Zend/Controller/Action.php';
 
class Admin_UtilisateurController extends Zend_Controller_Action {
    
     function init()
    {
        $this->initView();
        $this->view->baseUrl = $this->_request->getBaseUrl();
        Zend_Loader::loadClass('Utilisateur_Table');
    }
    
    public function indexAction() {
    $this->view->title = "Voici les utilisateurs";
    $user = new Utilisateur_Table();
    $this->view->users = $user->fetchAll();
    }
 
}

Si je laisse comme ca j'ai l'erreur suivante :

Code:

 
Fatal error: Uncaught exception 'Zend_Exception' with message 'File "Table.php" was not found' in D:\wamp\www\capanet\library\Zend\Loader.php:159 Stack trace: #0

Je ne comprend pas du tout pourquoi d'autant plus que si j'enleve le _Table au nom de la classe de mon model ca marche....

Quelqu'un a une idée ?

Hors ligne

 

#2 19-03-2008 15:49:58

bertra
Membre
Date d'inscription: 06-02-2008
Messages: 130

Re: probleme dans mon model

A mon avis le choix du nom de la classe Utilisateur_Table avec un underscore n'est peut être pas idéal du fait que zf se serve justement de ce caractère pour l'architecture.

Dernière modification par bertra (19-03-2008 15:50:18)

Hors ligne

 

#3 19-03-2008 16:03:21

or4cle
Membre
Date d'inscription: 18-02-2008
Messages: 70

Re: probleme dans mon model

indeed, si mes souvenirs sont bons, j'ai lu dans un tuto de Julien Pauli, loadClass utilise le mécanisme d'organisation des classes/fichiers du ZF pour charger ce qu'on lui demande
et avec la norme de ZF, quand tu charges par ex. "Zend_Loader::loadClass("Zend_Db_Table_Row_Abstract");"
il va chercher Zend/Db/Table/Row/Abstract.php
donc toi, il cherche Utilisateur/Table.php

Hors ligne

 

#4 19-03-2008 16:20:54

larenzu
Membre
Date d'inscription: 04-03-2008
Messages: 77

Re: probleme dans mon model

ah d'accord mais alors pourquoi sekagin dans ses post sur son blog utilise les class Nomdelaclass_Table

Hors ligne

 

#5 20-03-2008 19:43:34

Mr.MoOx
Administrateur
Lieu: Toulouse
Date d'inscription: 27-03-2007
Messages: 1444
Site web

Re: probleme dans mon model

Voilà.
Tu dis que ton fichier c'est utilisateur.php. Or vu le nom de ta classe il devrai être en fait:
Utilisateur/Table.php comme dit au dessus. D'où ton message d'erreur citant "Table.php" machin truc smile
Sekaijin ne le précise peut être pas (chui pas allé voir) mais il ne fait peut êtres pas Zend_Loader::loadClass() et plutôt require(_once).

Hors ligne

 

#6 22-03-2008 10:17:30

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: probleme dans mon model

non je fais bien des load mais j'ai un dossier modèle qui est organisé en sous dossier
/application
   /modele
      /utilisateur
          /table.php
          /row.php

A+ JYT

Hors ligne

 

#7 31-03-2008 16:33:39

bertra
Membre
Date d'inscription: 06-02-2008
Messages: 130

Re: probleme dans mon model

sekaijin a écrit:

non je fais bien des load mais j'ai un dossier modèle qui est organisé en sous dossier
/application
   /modele
      /utilisateur
          /table.php
          /row.php

A+ JYT

@sekaijin :
Pour information, je vois que tu sépare table et row dans ton modele.
Je cherche a savoir où mettre le code metier dans mon application. Je pense qu'il faut séparer modèle et métier.
Si on prend un exemple Commande et ligne de commande.
Dans mon modèle , je vais avoir cette structure :
/application
   /modele
      /commande
          /table.php
          /row.php
     /lignedecommande
          /table.php
          /row.php

Je ne sais pas ou mettre les traitements du genre getNombreDeLignes(), pour moi ce n'est ni un objet Table, ni un objet Row qui doit faire ca. Ca serait plutot un objet Commande, je pourrais donc le mettre dans une biblliotheques d'objet metiers. Ca me parait logique comme ça, mais du coup je ne saurais plus comment faire les lien entre les objets tables et les objets métiers...

Dernière modification par bertra (31-03-2008 16:43:40)

Hors ligne

 

#8 01-04-2008 08:58:47

or4cle
Membre
Date d'inscription: 18-02-2008
Messages: 70

Re: probleme dans mon model

Je verrais bien çà dans un fichier "Commande.php" dans le répertoire "models" peut-être ?
çà s'apparente beaucoup à l'archi de ZF si on regarde "Zend/Db" par exemple

Hors ligne

 

#9 01-04-2008 09:22:15

bertra
Membre
Date d'inscription: 06-02-2008
Messages: 130

Re: probleme dans mon model

Merci pour ta réponse (c'était celle que j'attendais smile).
Cependant comment faire le lien maintenant entre mon objet métier commande et mon objet Table.
En fait je me demande ou est ce que je dois déclarer un objet Table, et et ce que je dois utiliser le même pour tout mes objets métier (je ne pense pas qu'il soit bon d'en déclarer un par objet métier...).C 'est dommage qu'il n'y ait aucun exemple sur le net qui reprenne ce genre de problème courant non ?

Hors ligne

 

#10 04-04-2008 21:28:16

kiminox
Membre
Date d'inscription: 15-01-2008
Messages: 37

Re: probleme dans mon model

Je ne comprends pas ta dernière question : l'utilisation de Zend_Db_TableAbstract permet simplement de faire un mapping entre ta BD et ton code métier. Quand tu instancies une instance de ta classe TableRow et que tu lui affectes des valeurs par des setter, puis que tu fais un save, c'est comme si tu faisais à la main une requete SQL du type :
insert into maTable (col1, col2...) values (12, 'toto', ...);
L'intérêt d'utiliser un mapping est de rajouter une couche d'abstraction te permettant de t'affranchir de l'implémentation de ta base de données par rapport à ton code métier.
En effet, à un moment dans ton code métier, tu as besoin d'enregistrer un enregistrement : à ce moment, tu t'en fiches de savoir que tu es sous MySQL ou Postgres...tu as juste besoin d'insérer un enregistrement et de récupérer l'identifiant.
De manière duale, dans ton code métier de bas niveau, tu t'occupes d'enregistrer une ligne dans une table : à ce moment, ton seul souci est de ne pas violer les contraintes d'intégrité de ta base, après la signification de cette insertion, à ce niveau, tu t'en fiches.

Donc pour répondre à ta question : tu devrais penser en "couche". Chaque couche s'occupant de son métier seul.
Une piste : lorsque ta méthode fais plusieurs centaines de lignes, tu peux te dire que tu t'es probablement fourvoyé quelque part...

Je te conseille de définir une couche de service : souvent très utile car on a besoin de manière récurrente d'effectuer du code "transverse". Exemple :
créer un client pour un hôtel :
- WEB : formulaire avec les informations nécessaires (nom, prenom, adresse, etc...) + choix de la formule (exemple : formule complet avec repas midi et soir)
- service créer client :
---> appel sous-service création d'un objet Client
---> appel sous-service création d'une formule + relation Client-formule
---> appel service contrôle carte Bleu + paiement
---> appel service envoi mail confirmation

Chaque service peut ainsi être appelé par d'autres services et sont indédendants.

Yoong

Hors ligne

 

#11 05-04-2008 09:37:08

bertra
Membre
Date d'inscription: 06-02-2008
Messages: 130

Re: probleme dans mon model

kiminox a écrit:

Je ne comprends pas ta dernière question : l'utilisation de Zend_Db_TableAbstract permet simplement de faire un mapping entre ta BD et ton code métier. Quand tu instancies une instance de ta classe TableRow et que tu lui affectes des valeurs par des setter, puis que tu fais un save, c'est comme si tu faisais à la main une requete SQL du type :
insert into maTable (col1, col2...) values (12, 'toto', ...);
L'intérêt d'utiliser un mapping est de rajouter une couche d'abstraction te permettant de t'affranchir de l'implémentation de ta base de données par rapport à ton code métier.
En effet, à un moment dans ton code métier, tu as besoin d'enregistrer un enregistrement : à ce moment, tu t'en fiches de savoir que tu es sous MySQL ou Postgres...tu as juste besoin d'insérer un enregistrement et de récupérer l'identifiant.
De manière duale, dans ton code métier de bas niveau, tu t'occupes d'enregistrer une ligne dans une table : à ce moment, ton seul souci est de ne pas violer les contraintes d'intégrité de ta base, après la signification de cette insertion, à ce niveau, tu t'en fiches.

Ok, ca pas de souci.

kiminox a écrit:

Donc pour répondre à ta question : tu devrais penser en "couche". Chaque couche s'occupant de son métier seul.
Une piste : lorsque ta méthode fais plusieurs centaines de lignes, tu peux te dire que tu t'es probablement fourvoyé quelque part...

Je te conseille de définir une couche de service : souvent très utile car on a besoin de manière récurrente d'effectuer du code "transverse". Exemple :
créer un client pour un hôtel :
- WEB : formulaire avec les informations nécessaires (nom, prenom, adresse, etc...) + choix de la formule (exemple : formule complet avec repas midi et soir)
- service créer client :
---> appel sous-service création d'un objet Client
---> appel sous-service création d'une formule + relation Client-formule
---> appel service contrôle carte Bleu + paiement
---> appel service envoi mail confirmation

Chaque service peut ainsi être appelé par d'autres services et sont indédendants.

Yoong

Oui, pourquoi pas .
Pour revenir sur ma question du début. Mon probleme est que dans les exemples qu'on trouve sur le net, qui utilisent Zend_Db_Table, on appelle l'object dérivé de Zend_Db_Table par un nom métier (ex : Client).
Donc Client est un objet de type Zend_Db_Table. Dans mon application, j'ai besoin de manipluer des objets Client, de leur demander leur nom (client->getNom()....).
Ma question est :
Est ce que je peux affecter ces methodes (getNom(), getAdresse()...)a cet objet Client heritant de Db_Table ?
Ou dois-je en creer un autre ? (mais alors je l'apppelle comment et je le place où ?)
Ou dois je utiliser un autre nom que Client pour mon objet Client drivé de Db_Table (genre table.php que je mettrait dans un repertoire client) afin de garder l'objet Client comme un veritable objet metier(c'est cette methode que j'ai choisi pour le moment).
J'espere que ma question est plus claire, j'espere egalement que je ne suis pas passé a cote de quelque chose et que cette question est bien justifiée smile.
Dans tous les cas si la methode que j'ai choisi n'est pas la bonne, je suis pret a en changer.

Hors ligne

 

#12 05-04-2008 10:33:53

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: probleme dans mon model

bertra a écrit:

...
@sekaijin :
Pour information, je vois que tu sépare table et row dans ton modele.
Je cherche a savoir où mettre le code metier dans mon application. Je pense qu'il faut séparer modèle et métier.
Si on prend un exemple Commande et ligne de commande.
Dans mon modèle , je vais avoir cette structure :
/application
   /modele
      /commande
          /table.php
          /row.php
     /lignedecommande
          /table.php
          /row.php

Je ne sais pas ou mettre les traitements du genre getNombreDeLignes(), pour moi ce n'est ni un objet Table, ni un objet Row qui doit faire ca. Ca serait plutot un objet Commande, je pourrais donc le mettre dans une biblliotheques d'objet metiers. Ca me parait logique comme ça, mais du coup je ne saurais plus comment faire les lien entre les objets tables et les objets métiers...

l'objet métier dans cette représentation est le row
Model_Command_Row est une commande Model_Lignedecommande_Row une ligne de commande

ce sont donc ces classes qui porte les fonctions métier
les classe Tables elles serve à l'accès aux données
Model_Command_Table est un accès au gisement de commande idem pour Model_Lignedecommande_Table

Une commande est fait de plusieurs lignes de commande naturellement j'écrirais
$maCommande->getNombreLignes(); c'est donc bien l'objet métier qui porte la méthode.

la question à se poser c'est quel est l'objet  le plus à même à traiter cette demande
dans ce cas il s'agit de ligne commande la méthode getNombreLignes de Model_Commande_Row doit donc demander à la classe la plus appropriée de faire le travail.

Code:

function getNombreLignes() {
   $lct = new Model_Lignedecommande_Table();
   return $lct->getNombreLigneCommandeByCommandeID($this->id);
}

pour ma part j'utilise une façade entre le contrôleur et le métier
la classe Model contient les méthodes que je veux utiliser dans mes contrôleurs
j'ai donc dedans des méthodes comme getCommandeById newCommand etc.
du coup mon contrôleur n'a pas à savoir quelles classes métier instancier pour avoir la méthode il invoque la façade et c'est elle qui choisit l'objet le plus approprié

si le métier évolue sans changement dans l'usage seule la façade change et tous les contrôleurs en bénéficient

mais je me sers aussi de la façade dans le métier lui-même
ainsi dans l'exemple ci-dessus ma commande pour la méthode getNombreLignes ne demandera pas le traitement à lignedecommande mais à la façade
cela permet de séparer au mieux les interactions entre les classes, l'évolution de l'une n'entraine pas de changements dans l'autre.
A+JYT

Hors ligne

 

#13 05-04-2008 15:45:00

kiminox
Membre
Date d'inscription: 15-01-2008
Messages: 37

Re: probleme dans mon model

bertra a écrit:

Oui, pourquoi pas .
Pour revenir sur ma question du début. Mon probleme est que dans les exemples qu'on trouve sur le net, qui utilisent Zend_Db_Table, on appelle l'object dérivé de Zend_Db_Table par un nom métier (ex : Client).
Donc Client est un objet de type Zend_Db_Table. Dans mon application, j'ai besoin de manipluer des objets Client, de leur demander leur nom (client->getNom()....).
Ma question est :
Est ce que je peux affecter ces methodes (getNom(), getAdresse()...)a cet objet Client heritant de Db_Table ?
Ou dois-je en creer un autre ? (mais alors je l'apppelle comment et je le place où ?)
Ou dois je utiliser un autre nom que Client pour mon objet Client drivé de Db_Table (genre table.php que je mettrait dans un repertoire client) afin de garder l'objet Client comme un veritable objet metier(c'est cette methode que j'ai choisi pour le moment).
J'espere que ma question est plus claire, j'espere egalement que je ne suis pas passé a cote de quelque chose et que cette question est bien justifiée smile.
Dans tous les cas si la methode que j'ai choisi n'est pas la bonne, je suis pret a en changer.

Dans les exemples du ZF, les méthodes telles que client->getNom() sont directement implémentées dans ton Client, héritant de Zend_Db_Table. Bon, quant à savoir si la méthode est statique ou pas, tout dépend de test besoins.
Personnellement, j'utilise en plus une couche DAO (Data Access Object) pour effectuer mes requêtes.
Ainsi, la méthode client->getNom() utilise un dao clientDao qui fait la requête et c'est la méthode client->getNom() qui s'occupe de la signification des résultats retournés. De cette manière, si je dois changer de base, ben je réécris au besoin la requête dans le DAO mais je ne touche pas au code métier.

Donc, oui, tu peux utiliser getClient dans ton objet Client car cela concerne un Client.

Yoong

Hors ligne

 

#14 05-04-2008 17:50:04

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: probleme dans mon model

dans la plus part des exemple que l'on trouve sur le net la solution consiste à créer un objet Zend_Db_Table associé à un élément métier Les Clients

Code:

$clients = new Zend_Db_Table()

$clients n'est donc pas un client mais un moyen d'accéder au client
on ne peu demander getNom à une collection de clients ça n'a pas de sens.
les méthode comme Find ou fetch retourne un enregistrement de la table mais ce ne sont toujours mas des clients
ce sont juste des enregistrements soit des tableau associatif soit de simples objets

si tu veux pouvoir définir des méthodes sur ses objets il te faut créer une classe (a priori Client) et dire à ta table ($clients) que les enregistrements qu'elle te donnera seront des instances de Client

là tu pourra mettre des accesseurs comme getNom et tout autre méthode métier

mais pour que cela fonctionne ZF impose que ta classe client dérive de Zend_Db_Table_Row

tu as alors deux façon d'associer ta classe client à ta table
soit tu le fait à chaque intanciation d'une Zend_Db_Table (de mémoire qulque chose comme)
dans la plus part des exemple que l'on trouve sur le net la solution consiste à créer un objet Zend_Db_Table associé à un élément métier Les Clients

Code:

$clients = new Zend_Db_Table();
$clients->setRowClassName('Client');

soit tu crée une classe dérivé dans laquelle tu fixe une fois pour toutes l'association avec le membre protégé $_classRow

tu as donc deux classes la classe d'accès aux données dérivé de Zend_Db_Table et la classe métier dérivée de Zend_Db_Table_Row
A+JYT

Hors ligne

 

#15 07-04-2008 17:02:18

bertra
Membre
Date d'inscription: 06-02-2008
Messages: 130

Re: probleme dans mon model

Merci pour ces réponses smile

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages