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 :

Stockage des sessions en base de donnée [1.x]


Sujet :

Symfony PHP

  1. #1
    Membre éclairé
    Avatar de bricecol
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2007
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 364
    Points : 654
    Points
    654
    Par défaut Stockage des sessions en base de donnée
    Bonjour tout le monde.

    Je souhaiterais stocker les sessions symfony en BDD.

    Pour cela, je me suis renseigné sur 2 tutos :


    Pourquoi vouloir cela ? Pour avoir accès à la session de l'utilisateur courant depuis une barre d'outil firefox et ie... Et je pourrais aussi par exemple faire des stats sur les personnes connectés etc etc...

    Voici donc mon fichier config/databases.yml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    all:
      doctrine:
        class: sfDoctrineDatabase
        param:
          dsn:          mysql:host=localhost;dbname=mabase
          username:     username
          password:     password
          persistent:   true
    La description de la table session dans mon fichier config/doctrine/schema.yml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Session:
      columns:
        id:       { type: string(32), notnull: true, primary: true, fixed: true }
        content:  { type: string(4000), notnull: true }
        time:     { type: integer(4), notnull: true }
    Ce qui me génère la table SQL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    id	    char(32) PRIMARY KEY			 	 	 	 	 	 	
    content	    text		 	 	 				
    time	    int(11)
    Pour finir, voici mon fichier apps/monapp/config/factories.yml
    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
    all:
      user:
        class: myUser
        param:
          timeout:   864000 # 10 jours (10*24*60*60)
     
      storage:
        class: sfPDOSessionStorage
        param:
          database:    doctrine
          db_table:    session
          db_id_col:   id
          db_data_col: content
          db_time_col: time
     
      # suite du fichier...
    Maintenant, voici le problème. Lorsque je vais sur le site, une session est efefctivement créée en BDD, dansla table session.

    Elle a la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    id = 0448d8e9cb5b686f2e9e6e454688f62a
    content = symfony/user/sfUser/lastRequest|i:1283283389;symfo...
    time = 1283283389
    Maintenant, voici ce que je ne comprends pas. Lorsque je me connecte sur le site (getUser()->setAuthenticated(true)), une nouvelle ligne de session est créée. Lorsque je me déconnecte, une nouvelle ligne est créée etc...

    J'ai vu que d'autres personnes avaient eu un problème similaire mais je n'ai pas trouvé de solution à mon problème.

    Pouvez-vous m'aider ?

    Merci d'avance.

  2. #2
    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
    Question intéressante...

    Je voulais justement tester la chose, j'en ai profité et j'en arrive à la même conclusion que toi.

    Alors j'ai creusé... et appris quelques trucs que je ne connaissais pas sous PHP.

    De base, PHP fournit un objet en charge de la gestion des sessions. Par contre, si on veut gérer sois même plus avant les sessions (le cas d'un sf<base>SessionStorage il faut indiquer à PHP quel fonctions utilisée pour gérer l'enregistrement et le reste des sessions, ceci est initié par la fonction php session_set_save_handler.

    Donc notre objet de base (classe abstraite) session_set_save_handler mère de tout mos SessionStorage renseigne bien notre PHP avec un tableau de fonctions qui fonctionnent vu que les sessions sont bien dans la table et évolues...

    On a donc deux problèmes, les sessions que l'on sait devoir nettoyer (vu que l'on change de session lors d'un login ou logout) et les sessions qui restent dans le cache.

    Le premier pourrait être lié à l'absence de l'utilisation de la fonction session_destroy() dans le sfBasicSecurityUser de symfony. Il est, peut-être, possible de l'implémenter sans modifier beaucoup de code, en effet, l'objet sfBasicSecurityUser est bavard et génère un événement "user.change_authentication" avec le type de changement. Peut-on envisager de faire un session_destroy() et un session_start() a ce moment là ??? a tester.

    Pour le nettoyage des sessions en cours, mais que l'utilisateur néglige et qui doivent disparaître automatiquement, le code est écris les paramètres par défaut de php sont d'une chance sur cent de générer un nettoyage, je n'ai pas eu de chance.

    Il n'y a pas de ticket sur ce problème sur le site de symfony. Il faut peut-être envisager d'en créer un.

  3. #3
    Membre éclairé
    Avatar de bricecol
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2007
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 364
    Points : 654
    Points
    654
    Par défaut
    Effectivement, j'ai lu également (mais ne suis pas entré dans les détails dans mon post initial), qu'il était "probable" que symfony prenne par défaut les paramètres PHP suivants (que l'on peut retrouver dans le .htaccess, ou surcharger avec ini_set) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    php_value session.gc_probability
    php_value session.gc_divisor
    php_value session.gc_maxlifetime
    Et efefctivement, on retouve ici le ratio que j'ai appelé "de nettoyage des sessions" qui est php_value session.gc_probability / php_value session.gc_divisor.

    Par défaut, je crois que c'est 1/100. Le paramètre maxlifetime, qui porte bien son nom n'est apparemment plus utilisé (/etc/php5/apache2/php.ini) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ; This is disabled in the Debian packages, due to the strict permissions
    ; on /var/lib/php5.  Instead of setting this here, see the cronjob at
    ; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below.
    ; php scripts using their own session.save_path should make sure garbage
    ; collection is enabled by setting session.gc_probability
    ;session.gc_probability = 0
    session.gc_divisor     = 100
    Le contenu de /etc/cron.d/php5 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #  This purges session files older than X, where X is defined in seconds
    #  as the largest value of session.gc_maxlifetime from all your php.ini
    #  files, or 24 minutes if not defined.  See /usr/lib/php5/maxlifetime
     
    # Look for and purge old sessions every 30 minutes
    09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -n 200 -r -0 rm
    Et encore à part de tout cela, il y a le fichier (script) /usr/lib/php5/maxlifetime :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    max=604800
     
    for ini in /etc/php5/*/php.ini; do
            cur=$(sed -n -e 's/^[[:space:]]*session.gc_maxlifetime[[:space:]]*=[[:space:]]*\([0-9]\+\).*$/\1/p' $ini 2>/dev/null || true);
            [ -z "$cur" ] && cur=0
            [ "$cur" -gt "$max" ] && max=$cur
    done
     
    echo $(($max/60))
     
    exit 0
    Il permet de modifier tous les maxlifetime des configurations php5 éparpillées ici et là

    Bref, tout çà pour dire que c'est le bazars là dedans !

    J'essaie de trouver comment utiliser le session_destroy, dans apps/myapp/lib/myUser.class.php, j'ajoute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public function listenToChangeAuthenticationEvent(sfEvent $event)
    {
      var_dump('change authentication');
      exit;
    }
    Résultat => rien , à voir pourquoi, je continue de chercher.

    C'est quand même bien étrange que peu de monde n'est soulevé ces questions.

  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
    En fait, je pense que cela fonctionne bien ainsi...

    Et avoir un surplus de session dans la table n'est pas gênant pour la majorité des application. En général, on utilise le stockage des sessions dans une table pour permettre de les partager entre plusieurs serveurs, c'est la première fois que j'entends l'idée de vouloir compter les user actifs. Et même si on arrive à virer dans la tables les sessions terminées, rien ne dit qu'une personne à la session active soit réellement sur le site, c'est un des gros problèmes de développement en web.


    Bon, pour nettoyer, j'aurais plutôt jouer avec les événements, dans lib du projet, la création d'un objet

    SupprSession.class.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class SupprSession
    {
       public function nettoyage(sfEvent $event)
       {
          session_destroy();
          session_start();
       }
    }
    et dans le projetconfiguration rajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $dispatcher->connect('user.change_authentication', array('SupprSession', 'nettoyage'));
    Ce qui permet de ne pas intervenir dans le code de symfony.

  5. #5
    Membre éclairé
    Avatar de bricecol
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2007
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 364
    Points : 654
    Points
    654
    Par défaut
    Et avoir un surplus de session dans la table n'est pas gênant pour la majorité des application.
    Je veux bien te croire. Mais dans mon cas, en es-tu sûr ? Je me connecte, je me déconnecte, connecte, déconnecte, etc... et avec un seul utilisateur j'arrive à créer des dizaines de lignes en BDD. Imagine avec des centaines, voir des milliers d'utilisateurs. Tu multiplie par 2 voir par 3, 4. Je crois qu'il y a quand même une limite et que le système doit pouvoir être un peu contrôlé. Enfin, c'est mon opinion, j'émets simplement des doutes là dessus.

    c'est la première fois que j'entends l'idée de vouloir compter les user actifs
    Je suis d'accord avec toi, je me suis mal exprimé. Effectivement cela n'a rien à faire ici. On peut faire çà simplement avec un marqueur "online" dans la table user par exemple. On n'oublie çà . De toute façon, ce n'est pas mon problème ici. C'était juste un très, très mauvais exemple.

    Je vais tester ta proposition, à moins que tu ne l'ai déjà testé ? Pour l'instant je vais dormir !

  6. #6
    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 de développement ce soir.

    Il reste deux possibilité pour diminuer le nombre de session dans développer, diminuer la durée de vie d'une session et changer les "chance" de faire le ménage, quoique, plus il y a d'user, plus la chance de faire le nettoyage devrait être diminuer, pour ne pas saturer la base avec des procédures de nettoyage.

    Donc, soit on a peu d'utilisateur, et les avoirs en base n'a pas d'importance, soit on a beaucoup d'utilisateur et le mieux est de diminuer le temps de session, mais diminuer aussi la chance de nettoyer.

    Reste que je pense qu'il est plus rapide de nettoyer la table que de vider des fichiers (mode de base). Et de plus, s'il y a beaucoup d'user, il faudra probablement plusieurs serveurs, donc partager les sessions, donc... les stocker en base de donnée.

    Par contre, je pense que sur un très gros site on aurait intérêt à stocker cette table dans une base séparée des données, il doit être plus rapide de la piler et de la recréer que de la compacter, bien sur, on va perdre les sessions en cours, ce qui n'est pas l'idéal, mais en visant un bon créneau horaire...

    Et il est aussi possible de stocker le cache dans une base, donc de le partager entre plusieurs serveurs. Même chose, je pense qu'il faut une base dédiée.

    Après, il reste les nouvelles bases de données de type NoSQL qui pour ces deux types de données pourraient être avantageusement utilisées. Du moins pour le cache, surement, pour les sessions, il y a le problème de la fin de validité de la session qui complique, un peu, l'intégration.

    Je pense qu'un sujet sur le forum de sensio pourrait être un bon départ pour comprendre le pourquoi du non effacement systématique des session.

  7. #7
    Membre éclairé
    Avatar de bricecol
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2007
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 364
    Points : 654
    Points
    654
    Par défaut
    Pour informations, j'ai créé la classe changeAuthListener dans apps/myapp/lib :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
     
    class changeAuthListener
    {
      public function clearSessions(sfEvent $event)
      {
        if (session_id())
        {
          session_destroy();
          session_start();
        }
      }
    }
    Et voici la ligne supplémentaire dans mon ProjectConfiguration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $this->getEventDispatcher()->connect('user.change_authentication', array(
          'changeAuthListener',
          'clearSessions'
        ));
    Cela ne résout pas le problème, mais aucune erreur.

    Mais comment être sûr que la fonction est bien appelée ? En effet, lorsque je rajoute un monstrueux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo 'changeAuth';
    exit;
    Cela ne change rien.

    Une précision encore. Dans mon cas, je souhaiterais garder les sessions assez longtemps (par exemple un mois, soit approximativement 2635200 secondes). Mais ce n'est pas pour autant que je souhaite dupliquer une ligne d'un utilisateur précis si celui si se connecte ou se déconnecte. Donc sommes-nous bien d'accord sur ce point ? "La durée des sessions est complètement dissociée du mécanisme qui identifie pour un utilisateur donné, la session qui lui correspond (selon son IP, son agent etc...)".

    Le problème est bien ici soit que :
    • Il est normal qu'une nouvelle session se crée lorsque l'utilisateur se connecte et alors ici le mécanisme de nettoyage des sessions mortes ne fonctionne pas.
    • Ou une nouvelle session ne devrait pas se créée lorsque l'utilisateur se connecte (car après tout n'est-ce pas simplement une mise à jour du contenu de la session ?) et alors le problème ici est que l'identification user <=> session ne fonctionne pas.


    Je pencherais fort sur le deuxième point.

    Je pense qu'un sujet sur le forum de sensio pourrait être un bon départ pour comprendre le pourquoi du non effacement systématique des session.
    Je vais voir çà.

    MISE A JOUR A 9H25

    J'ai fais un update de synfony, je suis sur la version 1.4.7-DEV.

    La fonction clearSessions de la classe changeAuthListener précédemment créée est maintenant appelée, j'ai vérifié. Cependant, la ré-initialisation de la session corrompt le mécanisme de session (on se retrouve soit avec une session complètement vide et/ou les fonctions login/logout ne se termine pas correctement, elles plantes tout simplement).

    MISE A JOUR A 9H55

    Bon apparemment le mécanisme fonctionne. Il a certes un comportement très étrange mais je viens de remarquer que le nombre de sessions se stabilise à un moment donné. Peut-être y-a-t-il certaines conditions internes au nettoyage de session que l'on ne connait pas ainsi que des timeouts au sein même du mécanisme et qui n'ont rien à voir avec le maxlifetime.

    Quoi qu'il en soit, au bout d'un moment, une des "vieilles" sessions voit son contenu être effacée, puis elle disparue quelques temps après et ect...

    En fin de compte, le mécanisme marchait peut être déjà avant ou c'est une petite MAJ qui vient de le régler. Je verrais quand même après des tests de charge, en simulant de nombreux utilisateurs...

  8. #8
    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
    Tiens nous au courant, c'est un sujet intéressant

  9. #9
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Aide insertion dans une base de donnee mysql5 avec php5
    Bonjour a tous difficile de comprendre la programmation objet avec php5 j'ai beaucoup essayer les codes kelk1 pourrait m'aider je veux avoir un exemple de definition de mes variables utilisant la methode post en php 5 pour ke g puisse inserer les donnees dans la BD. un exemple avec 3 champs nom,prenom,telephone avec num comme cle primaire dans ma base de donnee
    Merci a tous

  10. #10
    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
    A mon avis, cher nouveau, tu es dans le mauvais forum, et qui de plus, dans un sujet qui traite de choses qui n'ont rien a voir et avec un langage qui sent "bon" le SMS non revu et pas corrigé...

    Je te propose, pour une tel question d'aller créer un sujet dans le forum haddock, je pense que le forum sur PHP et les SGBD serait tout indiqué.

    Pense à faire un nouveau sujet et à soigner, un peu, ta présentation, cela incitera surement les quidams présents à te répondre.

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 26/02/2011, 12h30
  2. Stockage des fichier Dans base de donnée sql
    Par Meryjean dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 29/08/2010, 12h23
  3. [MySQL] Problème par rapport au tutoriel sur le stockage des images en base
    Par dark_vidor dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 25/09/2005, 10h37
  4. Comment gérer efficacement des listes en Base de données ?
    Par alexk dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 12/04/2005, 20h21
  5. Où trouver des concepteurs de Base de Données?
    Par TomCrouise dans le forum Décisions SGBD
    Réponses: 11
    Dernier message: 13/12/2004, 16h13

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