Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#26 03-06-2009 18:26:37

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Salut,

Perso c'est ce que je fait.

J'avoue ne pas avoir bien saisi :

sekaijin a écrit:

pas tout a fait le modèle doit encapsuler la couche de persistance

@++ Kaimite

Hors ligne

 

#27 18-06-2009 11:54:04

ramos
Membre
Date d'inscription: 19-03-2009
Messages: 14

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Le QuickStart actuel (v1.8) du Zend Framework est très intéressant pour faire un modèle bien fait.
Il suggère d'utiliser des Mapper.

Le Mapper est un objet qui encapsule la couche de persistance : c'est lui qui va gérer tous les Zend_Db_Table, Zend_Db_Table_Row, etc.
A partir de ces objets, le Mapper va construire des objets métier (des classes toutes simples qui ne contiennent que des attributs et pas de méthodes).

Et enfin, le contrôleur ne connaît et ne fait appel qu'au Mapper (pour récupérer/enregistrer des objets métier).

Voilà pour l'idée générale, maintenant les bienfaits de cette façon de faire :

- La vue n'a pas accès à la couche de persistance : on passe des objets métier à la vue, mais comme il n'y a aucune méthode sur ces objets, elle ne peut que les afficher et les repasser à un contrôleur.

- Les objets métier peuvent être sérialisés avec Zend_Dojo ou Zend_Amf par exemple. Ils sont super légers et n'ont que des attributs, pas de méthode. On est sûr de pouvoir les sérialiser sans erreur.

- On peux modifier la base de donnée sans modifier ni les objets métier, ni le contrôleur, ni la vue. On a que le Mapper à adapter. On a donc isolé le métier de la façon d'optimiser le stockage des données.

Voilà, j'espère que j'ai pu aider. Le principal défaut du Zend Framework je pense, c'est de ne pas proposer de Mapper Abstrait qui gèrerait déjà les opérations CRUD et les jointures... ce qui oblige soit à créer son propre Mapper Abstrait (pour les warriors), soit à se palucher toutes les opérations pour chaque Mapper... Bref, un défaut, mais l'idée est peut être déjà en développement ? En fait, c'est le cas ^^

Dernière modification par ramos (18-06-2009 11:57:36)

Hors ligne

 

#28 18-06-2009 16:13:45

Moimeme
Membre
Date d'inscription: 19-04-2007
Messages: 120

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

ramos tu as un exemple concret de ce que pourrait contenir le mapper ? et le rapport au zend_table et zend_row ...

Hors ligne

 

#29 18-06-2009 17:39:45

ramos
Membre
Date d'inscription: 19-03-2009
Messages: 14

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Oui, regarde le Quickstart de Zend Framework section Model and Database.

Dedans il y a un Mapper très simple.

Par contre, écrire tous les mappers comme celui là peut être fastidieux. J'attends avec impatience un composant genre Zend_Mapper qui fera une partie du boulot à ma place ^^

Hors ligne

 

#30 18-06-2009 20:56:30

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Salut,

J'ai regardé le code et il me vient une question bete...

Je vois souvent cette écriture

Code:

funtion getEmail () 
{
    return $this -> email;
}
...

$email = $user -> getEmail();

Pourquoi ne pas faire directement

Code:

$email = $user -> email;

Est-ce uniquement valable dans le vas ou la propriété serait private ou protected ?

Merci pour vos réponse.

Cordialement,
Kaimite

Hors ligne

 

#31 19-06-2009 08:43:44

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Perso, je m'en sers par la suite si je veux faire des modifications dans la valeur qui doit être retuorné
Dans le cas d'un email, ca pourrait être un filtre par exemple
Ca m'évite à modifier tout mon code


----
Gruiiik !

Hors ligne

 

#32 19-06-2009 09:07:58

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

oki,

De mon coté j'utilise une méthode :

Code:

renvoyerInfosPourXXX ()
{

}

La plupart du temps c'est renvoyerInfosPourWeb() et elle me renvoi un tableau associatif avec toutes les valeurs filtrées et préparées.

Je viens de recevoir une base avec une table de 72 champs et je trouve un peu galère de devoir faire 72 méthodes :

getXXX()

D'ailleurs a ceux qui utilisent cette méthode, utilisez vous une solution "automatisée" pour ce genre de grosses table ?

Merci pour les réponses.

Cordialement,
Kaimite

Hors ligne

 

#33 19-06-2009 10:11:24

ramos
Membre
Date d'inscription: 19-03-2009
Messages: 14

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Salut Kaimite,

La plupart du temps, il est bon d'utiliser des attributs privés (ou protected) et mettre en place des getters-setters dès le début.
La raison, c'est que tu pourra plus tard ajouter un traitement avant de renvoyer la valeur, sans avoir à modifier toutes les classes qui font appel à l'attribut email pour ton exemple.

C'est bien la plupart du temps, c'est extrêmement utilisé en Java, mais parfois ça ne sert à rien, voire génant (exemple : pour sérialiser une classe pour la passer à un framework comme GWT ou Flex, les attributs de cette classe doivent être public).

Typiquement, pour ta table de 72 colonnes, tu n'utilises pas de getter setter pour les attributs. Si tu utilises Zend_Db_Table, tu récupères un Zend_Db_Table_Row et les colonnes sont directement accessibles (soit par $row->email, soit par $row['email']). C'est un cas où justement les getter setter ne sont pas judicieux, à mon avis.

Enfin, on parlait de mapper tout à l'heure. Ce mapper utilise une Zend_Db_Table, et là c'est judicieux de faire un getTable() dans le mapper.

Hors ligne

 

#34 19-06-2009 10:27:52

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

oki.

Merci pour la réponse.

Je commence a mieux cerner tout ça smile

Encore un truc a regarder de plus près ! c'est ajouté dans la liste "à faire un jour ou l'autre" smile

Cordialement,
Kaimite

Dernière modification par Kaimite (19-06-2009 10:28:07)

Hors ligne

 

#35 19-06-2009 11:01:54

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Kaimite a écrit:

oki,

De mon coté j'utilise une méthode :

Code:

renvoyerInfosPourXXX ()
{

}

La plupart du temps c'est renvoyerInfosPourWeb() et elle me renvoi un tableau associatif avec toutes les valeurs filtrées et préparées.

Je viens de recevoir une base avec une table de 72 champs et je trouve un peu galère de devoir faire 72 méthodes :

getXXX()

D'ailleurs a ceux qui utilisent cette méthode, utilisez vous une solution "automatisée" pour ce genre de grosses table ?

Merci pour les réponses.

Cordialement,
Kaimite

__call est ton amis
Zend_dB doit surement l'utilisé pour des méthodes du type findOneById, findOneByName, ...


----
Gruiiik !

Hors ligne

 

#36 19-06-2009 11:06:55

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

ramos a écrit:

Salut Kaimite,

La plupart du temps, il est bon d'utiliser des attributs privés (ou protected) et mettre en place des getters-setters dès le début.
La raison, c'est que tu pourra plus tard ajouter un traitement avant de renvoyer la valeur, sans avoir à modifier toutes les classes qui font appel à l'attribut email pour ton exemple.

C'est bien la plupart du temps, c'est extrêmement utilisé en Java, mais parfois ça ne sert à rien, voire génant (exemple : pour sérialiser une classe pour la passer à un framework comme GWT ou Flex, les attributs de cette classe doivent être public).

Typiquement, pour ta table de 72 colonnes, tu n'utilises pas de getter setter pour les attributs. Si tu utilises Zend_Db_Table, tu récupères un Zend_Db_Table_Row et les colonnes sont directement accessibles (soit par $row->email, soit par $row['email']). C'est un cas où justement les getter setter ne sont pas judicieux, à mon avis.

Enfin, on parlait de mapper tout à l'heure. Ce mapper utilise une Zend_Db_Table, et là c'est judicieux de faire un getTable() dans le mapper.

Je ne sais pas comment est codé Zen_Db_* car je ne l'utilise pas.
Mais dans Doctrine, tu peux faire $row->email et $row['email'] et $row->getEmail() et $row->get('Email'). Tous les attributs sont protégés, il utilise des méthodes magiques et implémente les interfaces nécessaires au PHP. Dans tous les cas, tu peux rajouté toi-même une fonction getEmail pour faire un filtre, et donc, quelques soit la méthode que tu utilises ton getter sera utilisé comme proxy. (et encore, j'abrège la)


----
Gruiiik !

Hors ligne

 

#37 21-06-2009 20:41:29

mdelanno
Membre
Lieu: Nord
Date d'inscription: 26-08-2007
Messages: 90
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

ramos a écrit:

- Les objets métier peuvent être sérialisés avec Zend_Dojo ou Zend_Amf par exemple. Ils sont super légers et n'ont que des attributs, pas de méthode. On est sûr de pouvoir les sérialiser sans erreur.

De toute façon, quand tu sérialises un objet, il n'y a que les variables (et le nom de la classe) qui sont enregistrées (c'est d'ailleurs pour ça que la classe doit être incluse pour réveiller l'objet), donc l'argument pas de méthodes ne tient pas.

Hors ligne

 

#38 19-07-2009 14:00:15

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Kaimite a écrit:

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 smile

Au niveau des requêtes ça ne change pas grand chose :

Code:

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 !

Bonjour,

Pour rebondir sur la question de la gestion de la pagination en minimisant l'impact des requêtes sur les performances, il existe une fonction SQL, nommée SELECT FOUND_ROWS, qui permet de calculer le nombre de résultats de la requêtes en faisant abstraction de la LIMIT posée.
Dès lors faire les requêtes suivantes ramèneront respectivement les articles désirés (LIMIT) et le nombre total d'article dans la table (sans devoir faire une requête lourde qui compte tous les articles (COUNT(*)) :

Code:

SELECT SQL_CALC_FOUND_ROWS `tbl_articles`.`uid` FROM `tbl_articles` LIMIT 10 OFFSET 80;
SELECT FOUND_ROWS() AS zend_paginator_row_count;

Hors ligne

 

#39 19-07-2009 14:41:54

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

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Attention ceci n'est valable QUE pour MySQL
le code n'est donc plus portable.

je me posais la question il y a quelque temps sur la couche d'abstraction de ZF.
il serait peut être intéressant d'introduire dans la version future l'accès au caractéristiques du moteur

par exemple dans une classe dérivée de Zend_Db_Table pouvoir faire un test sur le moteur permettrait de mieux optimiser les accès à la base comme celui du SQL_CALC_FOUND_ROWS

par exemple dans le constructeur faire un appel conditionnel pour attacher un Zend_Db_Table_Select Adapté au moteur du coup côté application on a toujours une Zend_Db_Table utilisé comme d'hab mais qui s'appuis sur une Zend_Db_Table_Select optimisé en fonction du moteur. ce qui permet de conserver la probabilité et l'abstraction du moteur tout en proposant des optimisation propre au moteur.

par exemple

Code:

SELECT usr_isvalid = 1 AS ISVALID FROM user;

ne fonctionne pas sur tous les moteur SQL (et oui un truc aussi simple)
sur certains il faut écrire

Code:

SELECT CASE usr_isvalid WHEN 1 THEN true ELSE false END AS ISVALID FROM user;

en ayant accès dans les classes d'abstraction au caractéristiques du moteur on  peut facilement proposer une ou l'autre des requête. du coup il devient facile de rendre le code plus optimal et plus portable.

pour l'heure il faut en passer par les classes de réflexions sur l'adapteur de la base.

A+JYT

Hors ligne

 

#40 19-07-2009 14:53:16

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

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Kaimite a écrit:

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 smile

Au niveau des requêtes ça ne change pas grand chose :

Code:

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 !

une petite note au passage puisqu'on parle d'optimisation.
il faut éviter autant que ce peut les *
et particulièrement sur un COUNT. sur un count ça ne sert à rien de compter les élément de toutes les colonnes vu qu'on compte les lignes.

en faisant juste un peu de sémantique on comprends mieux.
SELECT COUNT(*) signifie COMPTER (TOUTE LES COLONNES)  pour chaque Ligne
alors que
SELECT COUNT(1) signifie COMPTER (1) pour chaque ligne

Les moteur moderne s'en sortent pas trop mal mais dans leur analyse les moteurs vont avec le * prévoir de remonter toutes les colonnes pour compter les lignes (en général il optimisent après car ils s'aperçoivent que les colonnes ne sont pas utilisées) alors qu'un COUNT(1) ne vas utiliser qu'une seule fois la constante 1 donc pas de remonté de colonne à priori et pas d'optimisation sur les colonnes
si sur les requête simple select count l'impact n'est souvent pas très pertinent il est étonnant de voir le comportement de certain moteur lorsque on place des cout dans des requêtes plus complexes contenant des group by et des sous requêtes.

A+JYT

Hors ligne

 

#41 19-07-2009 15:13:46

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Salut,
j'ai vu sur d'autres sites que le count(*) est plus optimise justement.
Voici un article qui explique tout ça.
http://www.mysqlperformanceblog.com/200 … -countcol/

cordialement,
Kaimite

Hors ligne

 

#42 19-07-2009 16:56:58

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Effectivement le SQL_CALC_FOUND_ROWS n'est pas générique et implémenter des méthodes d'abstraction dans ce sens serait un nouveau petit plus dans la performance.

Dans l'article relatif à COUNT, il est surtout mis en évidence que faire un COUNT() sur une colonne non-indexée (ou indexée mais couplée) est plus lent qu'un COUNT(*).
Ce que je retiens de cet article (commentaires entre autres) et d'articles connexes, c'est que COUNT(1) est toutefois plus rapide sur la majorité des SGBD car il ne parse pas toutes les colonnes des lignes pour le dénombrement. (et un COUNT() sur une colonne indexée NOT NULL reste mieux qu'un COUNT(*) toutefois).

Dernière modification par Eureka (19-07-2009 16:58:14)

Hors ligne

 

#43 20-07-2009 07:36:39

Kaimite
Membre
Lieu: Marseille
Date d'inscription: 16-06-2008
Messages: 144
Site web

Re: [Résolu] Bonnes pratiques : Où définissez-vous vos requêtes ?

Autant pour moi alors smile

Mon anglais a montré ses limites !

Cordialement,
Kaimite

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