IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Zend_Db PHP Discussion :

Gestion des dépendances


Sujet :

Zend_Db PHP

  1. #1
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut Gestion des dépendances
    Bonjour,

    je suis en train de lire le tuto de Julien Pauli sur la présentation du ZF et notamment la gestion des dépendances (ce point là).

    Ma première question concerne les instructions de ce type :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $tblLivres = new Livres();
    $monLivre = $tblLivres->find('978-2841773381')->current();

    j'ai bien compris que le current() renvoie un ensemble de type 'row' mais pourquoi dans ce cas passer par un rowset puis le transformer en row ? Un fetchRow ne serait il pas plus approprié ici ?

    Ma deuxième question est celle ci : j'ai a peu près bien compris les méthodes "magiques" find<tableClass>Via<IntersectionTableClass>(), find<tableClass>() et findParent<tableClass>() mais est-il possible de récupérer uniquement certains champs via ces méthodes et pas tous les champs de la table concernée ?

    Enfin, j'ai une dernière question

    Il est marqué :

    Abuser des méthodes de récupération des dépendances va générer une charge insoutenable pour le SGBD. Ces méthodes sont là, mais en pratique on les utilise très très peu.
    Quel est le problème ?

    Si on défini et configure notre protected $_referenceMap, c'est justement et uniquement pour pouvoir faire ses opérations non ?

    Merci de vos éclaircissements

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 178
    Par défaut
    Hello,

    j'ai bien compris que le current() renvoie un ensemble de type 'row' mais pourquoi dans ce cas passer par un rowset puis le transformer en row ? Un fetchRow ne serait il pas plus approprié ici ?
    Le find recherche sur la clé primaire, typiquement ce qu'il y a de plus rapide. Libre à toi d'utiliser un fetchRow.

    Ma deuxième question est celle ci : j'ai a peu près bien compris les méthodes "magiques" find<tableClass>Via<IntersectionTableClass>(), find<tableClass>() et findParent<tableClass>() mais est-il possible de récupérer uniquement certains champs via ces méthodes et pas tous les champs de la table concernée ?
    Les magiques sont des raccourcis vers des méthodes findDependentRowset, findParentRow, etc… qui elle permettent de passer un select pour préciser ce que tu veux.

    Quel est le problème ?

    Si on défini et configure notre protected $_referenceMap, c'est justement et uniquement pour pouvoir faire ses opérations non ?
    Yep 100% d'accord, cependant comme tout raccourcis, les magiques masquent une complexité qui peut amener rapidement un codeur inattentif a fetcher énormément de données.
    Je conseil donc de laisser tomber les magiques mais de continuer à utiliser les relations par les méthodes qui leurs sont dédiées en évitant de fetcher des données inutiles.
    Pour te rassurer, j'utilise énormément les relations sans blem de perf.

  3. #3
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Ok, merci pour toutes ces réponses.

    Finalement, la méthode la plus rapide reste quelque chose comme ceci alors ?

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $result = $db->fetchAll($db->select()->join(...));

    Dans ce cas de figure, est on obligé de définir $_referenceMap dans le modèle ?

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 178
    Par défaut
    Hello,

    Si tu joins à là main, effectivement la déclaration des dépendances n'est plus utile.

    Par contre, tu te prives de la possibilité de faire des trucs comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $row->findDependentRowset(
    									$dependentTable),
    									null,
    									$depndentTable->select()
    														->order('order_field DESC')
    														->limit(1)
    Comme je te disais, des méthodes basées sur les liaisons existent.

  5. #5
    Membre chevronné Avatar de manuscle
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2004
    Messages : 488
    Par défaut
    Salut!

    Justement je me pose cette question de performance mysql car j'hésite entre faire une requête avec multi jointures ou utiliser les magiques, j'explique mon cas:

    J'ai un article avec plusieurs traductions, donc une table articles(id_article, id_categorie etc...) et une table articleLang(langue, id_article, titre) qui contient les trads dans chaque langue.
    Seulement tout les article ne sont pas traduits, j'ai besoin de lister les articles avec ou sans trad.

    Si je fait une requete avec jointure elle ressemblera à ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $select = "SELECT a.* FROM articles AS a LEFT JOIN articlesLang AS al ON al.id_article = a.id_article WHERE langue = 'en'
    Le probleme est que si je n'est pas de traduction je n'est pas de ligne de resultat mais j'aimerais en avoir une dans la langue par defaut (fr) ou avec des champs vides. Je ne sais pas comment faire en Mysql mais peut etre y a t-il une solution ?!.

    Alors j'ai testé en passant par les classes de table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    // Table articles
    $TArticles = new TArticles();
    // Table articlesLang
    $TArticlesLang = new TArticlesLang();
     
    $article = $TArticles->fetchAll();
    foreach ($articles as $article) {
        $select = $TArticle->select()->where('langue LIKE ?', 'en');
        $articleLang = $article->findDependentRowSet('TArticlesLang', null, $select)->current();
     
        // Pas d'anglais, on cherche dans la langue par defaut (fr)
        if(!$articleLang) {
            $select = $TArticle->select()->where('langue LIKE ?', 'fr');
            $articleLang = $article->findDependentRowSet('TArticlesLang', null, $select)->current();
        }
     
        // Pas de langue par defaut, on crée un row vide en lecture seule
        if(!$articleLang) {
            $articleLang = $TArticlesLang->createRow();
            $articleLang->setReadOnly(true);
        }
         echo $article->id_article . ' => ' . $articleLang->titre . '<br />';
    }
    C'est plutot assez gourmand comme code mais l'avantage est que je conserve les objets et j'ai des champs vides. Est-ce une solution interressante ou y-a-t-il mieux?

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 178
    Par défaut
    Wow,

    Une boucle sur un fetchAll qui fait des sous-requêtes , j'espère que tu es sur que le fetchAll ne va pas te renvoyer trop de résultats, sinon bye bye les perfs !

    Ensuite, je te conseil dans des cas comme ça de ne pas faire un like sur la langue mais une simple égalité + un index sur ton champ de langue.

    Enfin, pour les trads de mes données j'ai mis en place un code centralisé capable de joindre automatiquement la table de trad sur 1 Zend_Db_Select.

    Le left join ne devrait pas exclure les lignes de la table de gauche qui n'ont pas de correspondance dans la table de droite.

  7. #7
    Membre chevronné Avatar de manuscle
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2004
    Messages : 488
    Par défaut
    Citation Envoyé par patbator Voir le message
    Wow,

    Une boucle sur un fetchAll qui fait des sous-requêtes , j'espère que tu es sur que le fetchAll ne va pas te renvoyer trop de résultats, sinon bye bye les perfs !
    Oui oui j'ai un limit dans la requete, mais ça ne me plait pas non plus... et je blocke

    Citation Envoyé par patbator Voir le message
    Enfin, pour les trads de mes données j'ai mis en place un code centralisé capable de joindre automatiquement la table de trad sur 1 Zend_Db_Select.
    ça t'ennuie de partager ton code? En fait dans cas tu obtiens un rowSet contenant les traductions?

    Citation Envoyé par patbator Voir le message
    Le left join ne devrait pas exclure les lignes de la table de gauche qui n'ont pas de correspondance dans la table de droite.
    Pourtant lorsque j'execute cette requete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT a.* FROM articles AS a 
    LEFT JOIN articlesLang AS al ON al.id_article = a.id_article WHERE langue = 'es'
    Il n'y a pas de traduction en espagnol mysql me retourne 0 ligne...

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 178
    Par défaut
    Hello,

    Pour ce qui est de partager le code exact, je peux pas mais je peux préciser le principe qui s'appuie sur le design pattern délégation et donner quelques extraits.

    J'ai défini une interface de table traductible avec les méthodes devant être partagées «I18n_interface», dedans j'ai une méthode joinI18n qui reçoit un Zend_Db_Select et doit y rajouter les clauses pour joindre les trads.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function joinI18nModel(Zend_Db_Select $select, $fields = '*');
    Ensuite j'ai créé une classe «I18n_delegate» qui implémente l'interface «I18n_interface».
    Cette classe reçoit le nom de la table de trad et une instance d'une Zend_Db_Table dans son construct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	/**
    	 * @param string $model
    	 * @param Zend_Db_Table_Abstract $master
    	 */
    	public function __construct($model, Zend_Db_Table_Abstract $master)
    	{
    		$this->__model  = new $model;
    		$this->__master = $master;
    	}
    Enfin pour chaque table que je veux traductible, je dis qu'elle implémente aussi «I18n_interface», dans son construct je crée un «I18n_delegate».
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	static protected $_i18nDelegate;
     
    	public function __construct($config = array())
    	{
    		parent::__construct($config);
     
    		// si ma classe n'a pas encore de délégué, je le crée
    		if (null == self::$_i18nDelegate) {
    			self::$_i18nDelegate = new I18n_Delegate($this->_i18nModelName, $this);
    		}
    	}
    Ensuite pour chaque méthode de l'interface, la table ne fait que sous appeler le délégué.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	public function joinI18nModel(Zend_Db_Select $select, $fields = '*')
    	{
    		return self::$_i18nDelegate->joinI18nModel($select, $fields);
    	}
    Et dans le délégué tu as le vrai code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    	public function joinI18nModel(Zend_Db_Select $select, $fields = '*')
    	{
    		$i18nTable		= $this->__model->info(Zend_Db_Table_Abstract::NAME);
    		$masterTable	= $this->__master->info(Zend_Db_Table_Abstract::NAME);
     
    		$masterPks		= $this->__master->info(Zend_Db_Table_Abstract::PRIMARY);
     
    		$joinConds		= array();
    		foreach ($masterPks as $masterPk) {
    			$joinConds[] = $masterTable . '.' . $masterPk . ' = ' . $i18nTable . '.' . $masterPk;
    		}
    		$joinConds		= implode(' AND ', $joinConds);
     
    		$select->join($i18nTable, $joinConds, $fields);
    	}

  9. #9
    Membre chevronné Avatar de manuscle
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2004
    Messages : 488
    Par défaut
    Merci beaucoup pour l'explication!
    Je vais examiner ça et essayer de m'en inspirer!

    ça faisait un moment que je voulais faire un truc dans le genre mais je ne savais pas trop comment m'y prendre.

    Encore merci!

Discussions similaires

  1. Gestion des dépendances
    Par hoshi dans le forum Eclipse C & C++
    Réponses: 1
    Dernier message: 24/07/2007, 18h39
  2. [RPM] gestion des dépendances sous RedHat
    Par Longrais dans le forum Administration système
    Réponses: 3
    Dernier message: 16/04/2007, 20h28
  3. gestion des dépendances
    Par aemag dans le forum Oracle
    Réponses: 1
    Dernier message: 27/02/2007, 11h03
  4. [Maven2] et gestions des dépendances
    Par Palmer dans le forum Maven
    Réponses: 3
    Dernier message: 23/02/2007, 10h48
  5. gestion des dépendances
    Par zola dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 07/05/2006, 13h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo