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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    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
    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 confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    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 chevronné
    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
    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 confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    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 chevronné
    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
    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 confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    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.

+ 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