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

Symfony PHP Discussion :

Variable statique dans Respository : bonne pratique ?


Sujet :

Symfony PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Points : 22
    Points
    22
    Par défaut Variable statique dans Respository : bonne pratique ?
    Bonjour à tous,

    Dans un respository, j'ai une fonctionn countCabinets() qui me revoit simplement un nombre. Cette fonction sera appelé à de nombreux endroits dans une même page : dans le controller, dans certains services et même dans le menu.

    Quelle est la meilleure pratique selon-vous dans ce cas, afin de ne pas répéter la requête dans une même page ? Créer dans le respository une variable statique stockant dans un tableau tous les résultats countCabinets() afin de le rappeler ensuite est-il une bonne pratique ?

    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
     
        protected static $count_cabinets;
     
        public function countCabinets()
        {
            if (isset(self::$count_cabinets)) {
                return self::$count_cabinets;
            }
            $rsm = new ResultSetMappingBuilder($this->_em);
            $rsm->addScalarResult('count_cabinets', 'count_cabinets', 'integer');
            $query = $this->_em->createNativeQuery('
                SELECT
                    COUNT(c.id) AS count_cabinets
                FROM
                    cabinet c
                WHERE
                    c.date_suppression IS NULL
            ', $rsm);
            return self::$count_cabinets = $query->getSingleScalarResult();
        }
    J'ai un doute sur la meilleure façon d'aborder ce problème ...

    Merci d'avance

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    Non, c'est une mauvaise pratique.
    Si tu veux optimiser ce genre de traitement, utilise un système de cache de requêtes

  3. #3
    Membre à l'essai
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Salut et merci de ta réponse, je m'en doutais un peu

    Cependant si je sais utiliser le système de cache [ en envoyant un ID et, éventuellement, une durée ], ça me parait compliqué à mettre en place, imaginons que countCabinet() ait eu un argument quelconque repris dans le Where, ça aurait multiplier le nombre d'ID à enregistrer en cache par les possibilités de ce dit-argument. De plus, le countCabinet() original est une requête avec plusieurs jointures ... il faudrait donc vider ce cache (donc, l'ID correspondant) dès qu'il y a une intervention sur une des tables jointes ... vraiment compliqué à mettre en place :-S

    Si tu as quelques conseils, n'hésites pas

  4. #4
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    J'ai du mal à comprendre ta logique.

    Soit ta requete est identique et ton système(qui est un cache mal foutu) fonctionnera... soit elle sont différentes et ca n'ira pas. (tu retournera le resultat de la première requetes, pas les suivantes.

    Le mieux dans ce cas la est, selon moi d'utiliser qq chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $qb = $this->createQueryBuilder('l');
            $qb->andWhere('l.urlName IS NOT NULL')
            $query = $qb->getQuery();
            $query->useResultCache(true);
            $query->setResultCacheLifetime(3600);
        	return $query->getResult();
    Si tu as peur que ton cache soit invalide, soit tu défini une valeur faible(ton cache ne sera pas invalide longtemps) soit tu défini juste des bons index en SQL et ca ira assez vite, soit tu regarde si il existe un moyen d'invalider un cache doctrine.

    bon courage.
    La solution choisie m'interesse si tu peux la donner.

    pierre

  5. #5
    Membre à l'essai
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Salut et merci de ta réponse

    Effectivement passer par un système de cache tel que APC me parait plus cohérent, mais le soucis c'est que la requête peut changer en fonction de l'utilisateur connecté. Par exemple, imaginions que countCabinet() ait un ou plusieurs arguments qui se retrouvent dans le Where, ces arguments ne doivent pas se marcher dessus dans la construction de l'ID.

    Voici un code que je viens de "bricoler" :

    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
    25
    26
    27
    28
    29
    30
    31
    32
     
        public function countCabinets()
        {
            $rsm = new ResultSetMappingBuilder($this->_em);
            $rsm->addScalarResult('count_cabinets', 'count_cabinets', 'integer');
            $query = $this->_em->createNativeQuery('
                SELECT
                    COUNT(c.id) AS count_cabinets
                FROM
                    cabinet c
                WHERE
                    c.date_suppression IS NULL
            ', $rsm);
            $id = $query->getSQL();
            /*
             * On charge le moteur "APC Cache"
             */
            $cacheDriver = new \Doctrine\Common\Cache\ApcCache();
            /*
             * Si le résultat de la requête est déjà en cache, on la renvoit
             */
            if ($cacheDriver->contains($id)) {
                return $cacheDriver->fetch($id);
            } else {
                /*
                 * Sinon, on enregistre la requête en cache
                 */
                $result = $query->getSingleScalarResult();
                $cacheDriver->save($id, $result);
                return $result;
            }
        }
    Ici, il n'y a pas d'argument - pour faire simple - mais imaginons que la requête ait un argument qui fait changer le Where (typiquement un ID provenant d'une autre table) ... c'est pour ça que j'ai utilisé la requête entière comme ID ( avec $query->getSQL() ), mais je doute, la encore, du coté bonne pratique ... :-S

  6. #6
    Membre à l'essai
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Je précise que je suis dans ce cas d'un back-office, donc un peu plus complexe qu'un blog avec des articles ... il s'agit de mettre en cache par exemple les X :
    - Nombre d'articles (X)
    - Nombre d'articles dans catégorie A (X)
    - Nombre d'articles dans catégorie B (X)
    - Nombre de catégorie (X)

  7. #7
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    Ok, quelle taille fait ta base d'article.

    Parce que je pense vraiment que tu t’embêtes pour rien...
    Pour chaque requêtes SQL, tu auras une association entre ta requete SQL et le resultat mis dans un tableau associatif.
    Donc select count(*) from article where categorie = A sera bien différent de select count(*) from article where categorie = B

    Si tu rapelle 10 fois la requete 1, tu auras 10 fois le même resultat et juste une seule vraie requete en BDD.
    Dés que tu fera une requete qui n'est pas encore connue ou expirée... tu auras le même comportement appliqué sur cette nouvelle requete, en parralele.

    Pierre

Discussions similaires

  1. Bonnes pratiques d'optimisation JS et gestion interne des variables
    Par nouknouk dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/11/2009, 14h42
  2. [PHP 5.2] Bonne utilisation des variable transmis dans l'URL.
    Par NuDub dans le forum Langage
    Réponses: 6
    Dernier message: 23/05/2009, 18h30
  3. Réponses: 4
    Dernier message: 01/10/2008, 08h59
  4. Réponses: 5
    Dernier message: 17/04/2008, 09h11
  5. De la bonne pratique des variables globales...
    Par say dans le forum C++Builder
    Réponses: 9
    Dernier message: 25/11/2005, 09h47

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