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 :

Appliquer un pattern sur les données [1.x]


Sujet :

Symfony PHP

  1. #1
    Invité
    Invité(e)
    Par défaut Appliquer un pattern sur les données
    Bonjour,

    Dans ma base de données j'utilise beaucoup d'identifiant sous forme 1.2.3.4
    hors en javascript les "." ne fonctionnent pas des masses pour identifier les objets et de plus les paramètres passés en get ne sont pas bien géré au niveau du routing symfony.

    J'ai commencé a utiliser des str_replace pour remplacer les . par des _ mais je suis obligé de le faire également dans l'autre sens et a force je suis obligé de tester si il y a des . ou des _ car je ne sais meme plus.

    Je cherche donc un moyen de filtrer ces données au niveau de l'ORM. En effet, si je pouvais dire a doctrine qu'en base de données les champs sont sous forme "1.2.3.4" mais que dès lors que j'y accède en php ils doivent m'être retournés comme "1_2_3_4" ca serait super.

    D'après mes recherches google je dois m'intéresser aux filtres du coté de symfony mais je n'ai pas trouvé d'explications.

    Merci de votre aide.

  2. #2
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Pour bien situer le problème, qu'est-ce qui t'empêche d'ajouter un getter à la classe concernée dans le modèle, du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    lib/model/doctrine/MaClasse.class.php
     
    MaClasse extends BaseMaClasse {
     /* @ method public function getMaColonne() 
      générée par Symfony pour récupérer les données, on n'y touche pas
      @return "1.2.3.4"
    */
     
    public function getMaColonneFormatted() {
    return str_replace(".", "_", $this->getMaColonne());
    }
    (et un setter faisant le travail inverse, bien entendu)

  3. #3
    Invité
    Invité(e)
    Par défaut
    Salut,

    Oui j'y ai pensé mais je ne sais pas si Doctrine utilise ce getter lorsque je fais des findByMaColonne() ou meme lorsque je modifie un objet et que je l'enregistre en base de données quelle format va-t-il utiliser pour cette colonne?

  4. #4
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Symfony passe par les getter et setter a chaque accès aux données. Que tu y accède pas un : getDonnee() ou un $record['donnee'] elle va transiter par le setter.

    Elle est également utilisée pour l'hydratation.

    Le seul cas particulier où tu passeras à côté c'est si, dans une requête, tu renommes volontairement ton champ dans la méthode select() du DQL.

    Par contre, je simplifierais la solution de Herode en ne changeant pas le nom de la variable.
    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
     
    // lib/model/doctrine/MaClasse.class.php
     
    MaClasse extends BaseMaClasse {
     /* @ method public function getMaColonne() 
      générée par Symfony pour récupérer les données, on n'y touche pas
      @return "1.2.3.4"
    */
     
    public function getMaColonne() {
      return str_replace( ".",  "_", parent::_get('maColonne') );
    }
     
    public function setMaColonne( $valeur) 
    {
      // Éventuelle test de conformité avec un événement si non conforme
      parent::_set( 'maColonne', str_replace( '_', '.', $valeur ) );
      return $this;
    }
     
    }
    Ce qui permet de rester transparent au niveau des form généré notamment.

    edit 9:20
    A noter que les méthodes :
    parent::setMaColonne()
    ne fonctionnent pas, cette méthode étant construite à la volée. Il convient donc d'appeler le setter de base : _set(). Idem pour le getter.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  5. #5
    Invité
    Invité(e)
    Par défaut
    Super

    Du coup il y a d'autres données que je pourrais aussi pré-formater.
    Je suis sur autre chose actuellement je pense tester cette méthode d'ici lundi, je passerai en résolu à ce moment là ou au pire je reviendrai vers vous.

    Merci beaucoup.

  6. #6
    Invité
    Invité(e)
    Par défaut
    J'ai fait un petit test mais malheureusement j'ai un petit souci.
    En effet, comme je le pensais au départ, les méthodes utilisées dans doctrine ne doivent pas se baser sur les getter et setter personnalisés.

    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
     
    //Modèle
    class MaTable extends BaseMaTable
    {
       public function getId(){
           return str_replace(".","_", parent::_get("Id"));
       }
     
       public function setId($id){
           parent::_set("id",str_replace('_','.',$id));
       }
    }
     
    //Action
    class monActions extends sfActions {
     
        public function executeIndex(sfWebRequest $request) {
            $id = $request->getParameter('id');
     
            $this->monObjet = Doctrine_Core::getTable('maTable')->findOneById($id);
            //ne renvoie aucun résultats car $id = "1_2_3_4"
            //alors que dans la base de données id = 1.2.3.4
        }
    }
    Y a t-il un moyen de faire cette manipulation dans une couche encore plus basse que le modèle pour que Doctrine y passe aussi?
    Peut-on forcer Doctrine à utiliser ces getter et setter?

    Où alors je me suis planté quelque part?

  7. #7
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Citation Envoyé par Mr_LoOnY Voir le message
    En effet, comme je le pensais au départ, les méthodes utilisées dans doctrine ne doivent pas se baser sur les getter et setter personnalisés.
    Tu entends quoi par là ?
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  8. #8
    Invité
    Invité(e)
    Par défaut
    le findOneBy("1_2_3_4") ne va pas se baser sur le _get("id") que je viens de créer. il va directement comparé "1_2_3_4" avec la base de données.
    En fait, c'est logique il crée une requête, il n'a pas besoin de passer par le modèle.
    A mon avis pour changer ça il va falloir aller autre part.

  9. #9
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Non, pas spécialement, il faut créer une méthode findOneById() qui est aussi une méthode générée "magiquement".

    Puis il faut un peu factoriser le code de setId() pour faire une méthode qui d'un avec "_" passe à un avec ".". Méthode que tu utiliseras dans findOneById() pour récupérer le bon enregistrement.

    En fait, il va falloir faire cela pour chaque méthodes magiques utilisées.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  10. #10
    Invité
    Invité(e)
    Par défaut
    Mais est-ce que le findOneById() que je vais créer sera aussi utiliser pour le findOneByIdAndUnAutreChamp() et aussi pour le findById().

    Je pense qu'au final ca sera tout aussi long que d'encapsuler mon id dans des str_replace a chaque fois.

  11. #11
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Non, il ne sera valable que pour le findOneById(). Il faudra faire la même chose pour chaque find en automatique que tu comptes utiliser. Il est vrai que comme ce sont des méthodes automatique que je n'utilise presque jamais (plus par habitude qu'autre chose) et je n'avais pas pensé à elles.

    Par contre, il me semble important, vu ton application, de procéder de cette manière. Ceci va te permettre d'avoir un seul type de champ et de limiter la conversion au modèle et de ne pas mélanger les couches entre modèle et contrôleur.

    Tu as une autre possibilité, non testée, qui serait de créer deux méthodes static pour tes modifications et de les appelées dans ton modèle et dans ton contrôleur.

    Modèle :
    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
     
    // lib/model/doctrine/MaClasse.class.php
     
    MaClasse extends BaseMaClasse {
     /* @ method public function getMaColonne() 
      générée par Symfony pour récupérer les données, on n'y touche pas
      @return "1.2.3.4"
    */
     
    public function getMaColonne() {
      return self::IdToTrait( parent::_get('maColonne') );
    }
     
    public function setMaColonne( $valeur) 
    {
      // Éventuelle test de conformité avec un événement si non conforme
      parent::_set( 'maColonne', self::IdToPoint( $valeur ) );
      return $this;
    }
     
    static function IdToPoint( $id )
    {
      return str_replace( '_', '.', $id );
    }
    static function IdToTrait( $id )
    {
      return str_replace( '.', '_', $id );
    }
     
    }
    Dans le contrôleur pour récupérer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ...
    $data = $doctrine_core::getTable('MaClasse')->findOneById(self::IdToPoint( $IdATrouver ) );
    ...
    Et tu gardes bien ton intégrité au niveau des données.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  12. #12
    Invité
    Invité(e)
    Par défaut
    Etant donné le nombre de colonne que je vais devoir traiter je pourrais même sortir ces méthodes et créer une sorte de helper (enfin un méthode globale à toute l'application) me permettant de switcher des _ aux . et inversement.

    Ca serait en fait un espèce d'alias de str_replace().

    D'ailleurs ou est-ce que je peux déclarer une méthode pour qu'elle soit connue dans l'ensemble de l'application?

  13. #13
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Personnellement je ferais une méthode pour chaque objet du modèle, au moins un shunt, au cas où, dans un modèle, le format changerait, tu ne sois pas obliger de modifier tous le code.

    Le code que tu met dans lib/ est visible par toute l'application.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  14. #14
    Invité
    Invité(e)
    Par défaut
    Si je fais une méthode générique getIdPoint($id) et getIdUs($id) qui me retourne respectivement str_replace("_",".",$id) et str_replace(".","_",$id).
    Si un jour le format change je n'aurais qu'à modifier cette méthode non ?
    Je pense que c'est assez bien factorisé là.

  15. #15
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    Je suis un peu parano mais : que fais-tu si le format change dans une seule entité (table) ?

    D'où ma notion de shunt pour chaque entité. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // classe MaClasse
    ...
    static function IdToTrait( $id )
    {
      return IdToTrait ( $id );
    }
    L'avantage est qu'en cas de modification pour une entité, si tu respectes le code de passer systématiquement par la méthode d'encodage de la table, tu n'as qu'une modification a faire.

    Mais, je suis un peu parano et habituer à reprendre du code d'autre quelques années après leur passage...
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  16. #16
    Invité
    Invité(e)
    Par défaut
    Oui je suis d'accord mais je dois avoir une cinquantaine de colonnes comme ca donc autant de méthodes à générer. De plus je pourrais utiliser les getter et setter sans modifications puis lors d'un findOneById() je devrais utiliser les méthodes statics idToPoint pour formater juste à ce moment là.
    Ca fait donc des traitements différents.

    Alors qu'avec une méthode globale de traitement je sais qu'à chaque utilisation d'un champs de ce type je devrai l'encapsuler dans cette methode.
    Ca sera donc systématique.

    Je pense continuer sur cette voix, mais je suis d'accord avec toi et j'ai quand même appris des choses

    Merci pour le coup de main.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Filtrer sur les données vides dans un formulaire
    Par jevany dans le forum Access
    Réponses: 7
    Dernier message: 29/05/2006, 08h50
  2. MAX et Jointure sur les données correspondantes
    Par lepeule dans le forum Langage SQL
    Réponses: 1
    Dernier message: 12/04/2006, 16h18
  3. [debutant] Question sur les données.
    Par Norabfr dans le forum Débuter
    Réponses: 4
    Dernier message: 03/01/2006, 13h47
  4. Filtre sur les données des 3 derniers mois?
    Par Arkalys dans le forum Access
    Réponses: 2
    Dernier message: 21/10/2005, 09h02

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