2009-08-06 5 views
33

Quelle est la différence réelle entre session.gc_maxlifetime et session_cache_expire()? Supposons que je souhaite que la session des utilisateurs soit invalide après 15 minutes de non-activité (et non 15 après sa première ouverture). Lequel de ceux-ci va m'aider là-bas?Délais de session en PHP: bonnes pratiques

Je sais aussi que je peux faire session_set_cookie_params() qui peut mettre le cookie de l'utilisateur à expiration dans un certain laps de temps. Cependant, le cookie expirant et la session réelle expirant du côté du serveur ne sont pas les mêmes; cela supprime-t-il également la session lorsque le cookie a expiré?

Une autre solution que j'ai bien est simple de $_SESSION['last_time'] = time() à chaque demande, et en comparant la session à l'heure actuelle, la suppression de la session sur cette base. J'espérais qu'il y avait un mécanisme plus "intégré" pour gérer cela.

Merci.

+0

Comme je suis tombé moi-même sur cette question après quelques recherches, on peut avoir une réponse très complète sur ce problème sur [cette question stackoverflow] (http://stackoverflow.com/a/1270960/474526), ​​en particulier pourquoi ni la mise à jour 'session.gc_maxlifetime' ni 'session.cookie_lifetime' ne sont des approches fiables. –

Répondre

39

Chaque fois que session_start est appelé l'horodatage des fichiers de session (s'il existe) est mis à jour, qui est utilisé pour calculer si session.gc_maxlifetime a été dépassé. Plus important encore, vous ne pouvez pas compter sur l'expiration d'une session après le dépassement de la durée de session.gc_maxlifetime.

PHP exécute garbage collection sur les sessions expirées après le chargement de la session en cours et en utilisant session.gc_probability et session.gc_divisor il calcule la probabilité que la récupération de place s'exécute. Par défaut c'est une probabilité de 1%.

Si vous avez un faible nombre de visiteurs, il existe une probabilité qu'un utilisateur inactif puisse accéder à une session qui aurait dû expirer et être supprimée. Si cela est important, vous devez stocker un horodatage dans la session et calculer la manière dont un utilisateur a été inactif.

Cet exemple remplace session_start et applique un délai d'attente:

function my_session_start($timeout = 1440) { 
    ini_set('session.gc_maxlifetime', $timeout); 
    session_start(); 

    if (isset($_SESSION['timeout_idle']) && $_SESSION['timeout_idle'] < time()) { 
     session_destroy(); 
     session_start(); 
     session_regenerate_id(); 
     $_SESSION = array(); 
    } 

    $_SESSION['timeout_idle'] = time() + $timeout; 
} 
5

session.gc_maxlifetime est basé sur la dernière fois qu'un fichier de session a été modifié. Ainsi, chaque fois qu'un fichier de session est modifié ou qu'un session_start() est appelé dans une page séparée, le compte à rebours de gc_maxlifetime recommence et l'utilisateur reste connecté. C'est la valeur que vous recherchez. Vous pouvez modifier ce en utilisant ini_set() dans vos fichiers php, ou modifier php.ini si vous avez accès

session_cache_expire() contrôle uniquement le HTTP « expires » en-tête. Cet en-tête contrôle combien de temps le contenu de la page téléchargée reste dans le cache du navigateur de l'utilisateur.

49

J'ai passé un peu de temps à la recherche d'une bonne réponse à la façon dont les paramètres du serveur php.ini font sessions expirent. J'ai trouvé beaucoup d'informations, mais il a fallu un certain temps pour comprendre pourquoi les paramètres fonctionnent comme ils le font. Si vous êtes comme moi, cela peut vous être utile:

Les sessions sont stockées en tant que cookies (fichiers sur le PC du client) ou côté serveur en tant que fichiers sur le serveur. Les deux méthodes ont des avantages et des inconvénients.

Pour les sessions stockées sur le serveur, trois variables sont utilisées.

session.gc_probability session.gc_divisor session.gc_maxlifetime

(session.gc_probability/session.gc_divisor) produit la probabilité que la routine de collecte des ordures sera exécuté. Lorsque le garbage collector s'exécute, il vérifie les fichiers de session qui n'ont pas été consultés au moins pour session.gc_maxlifetime et les supprime.

Tout cela est expliqué assez bien dans les messages du forum (celui-ci en particulier!) - Mais les questions suivantes ne se présentent:

1.) Comment est que la probabilité appliquée? Quand le serveur lance-t-il les dés? R: Le serveur jette les dés chaque fois que session_start() est appelée pendant toute session active sur le serveur

Donc, cela signifie que vous devriez voir le éboueur courir à peu près une fois pour chaque tranche de 100 fois que session_start() est appelée si vous avez la valeur par défaut = 1 et session.gc_probability session.gc_divisor = 100

2.) Qu'est-ce qui se passe sur les serveurs à bas volume? A: Lorsque session_start() est appelée, FIRST actualise la session et vous donne accès aux valeurs de la session . Cela met à jour l'heure sur votre fichier de session sur le serveur . Il lance ensuite les dés et s'il gagne (1 chance sur 100), il appelle le garbage collector. Le garbage collector vérifie ensuite tous les fichiers d'identification de session et voit s'il y a des qui peuvent être supprimés. Donc, cela signifie que si vous êtes la seule personne sur le serveur, votre session ne deviendra jamais inactive et il semblera que la modification des paramètres n'a pas d'effet . Supposons que vous définissiez session.gc_maxlifetime à 10 et session.gc_probability à 100. Cela signifie qu'il y a 100% de chances que le garbage collector s'exécute et que efface tous les fichiers de session qui n'ont pas été accédés au cours des 10 dernières secondes .

Si vous êtes le seul sur le serveur, votre session ne sera pas supprimée. Vous avez besoin de au moins 1 autre session active en cours pour que la vôtre devienne inactive.

Donc, fondamentalement, sur un serveur à faible volume ou à un moment de faible volume - il pourrait être beaucoup plus longtemps que session.gc_maxlifetime avant le garbage collector fonctionne réellement et les sessions sont effectivement supprimées. Et sans savoir comment cela fonctionne, il peut apparaître complètement aléatoire pour vous.

3.) Pourquoi utilisent-ils la probabilité?

A: Performances. Sur un serveur de volume supérieur, vous ne voulez pas que le ramasse-miettes soit exécuté à chaque requête de session_start(). Il va ralentir le serveur inutilement. Donc, selon le volume de votre serveur, vous pouvez augmenter ou diminuer la probabilité que le garbage collector fonctionne. J'espère que cela lie les choses ensemble pour vous. Si vous êtes comme moi et que vous avez essayé la session .gc_maxlifetime et il ne semble pas fonctionner (parce que vous l'avez essayé sur un serveur de développement afin de ne pas déranger personne), alors cet article espère vous a sauvé un peu de grattage de la tête.

Bonne chance!

+3

Une réponse très informative! Devrait être dans les documents officiels de PHP. Merci! –

+0

Réponse très claire ... mais je voudrais juste souligner que même si vous utilisez les sessions basées sur des fichiers par défaut de PHP, un cookie est toujours envoyé au navigateur de l'utilisateur. Ceci est un cookie de session (traditionnellement ceux-ci expirent quand ils ferment l'onglet/fenêtre) et contient simplement leur identifiant de session. Les problèmes de session peuvent donc ne pas être limités aux paramètres du serveur. Si le navigateur de l'utilisateur se «souvient» de ce cookie au-delà de la fermeture d'un onglet/d'une fenêtre, il risque de perdre des sessions qu'il s'attendrait sinon à conserver. De même, le fait de jouer avec les paramètres de ce cookie peut avoir un impact sur leur capacité à maintenir une session en vie. – simonhamp

+0

de http://www.appnovation.com/blog/session-garbage-collection-php ... dans la distribution Debian/Ubuntu, par défaut, PHP désactive son mécanisme de récupération de place. Au lieu de cela, il exécute un travail cron toutes les demi-heures (voir le script /etc/cron.d/php5) pour purger les fichiers de session dans le répertoire/var/lib/php5 /. – renergy

1

Pour vérifier les valeurs actuelles, ce code sera utile:

$gc_maxlifetime = ini_get('session.gc_maxlifetime'); 
$gc_probability = ini_get('session.gc_probability'); 
$gc_divisor  = ini_get('session.gc_divisor'); 
Questions connexes