Disparition de variables de session PHP après une redirection ?
Aujourd'hui, je viens d'apprendre quelque chose que j'ai trouvé vraiment intéressant, et surtout piégeur !
Je développe actuellement un site web tout simple avec stockage de la connexion des utilisateurs en
variable de session. Seulement, j'ai remarqué des phénomènes limites paranormaux : de temps en temps, après une redirection avec la fonction PHP
header(), on se retrouvait déconnecté sans raison. Et impossible de reproduire le bug à coup sur, et surtout : ça n'arrivait jamais en local.
La raison est assez simple, mais tordue (merci aux commentaires dans les fonctions PHP du site php.net !) :
Si le script A ouvre une session (pour voir si l'internaute est connecté), puis redirige avec header() vers le script B, et que le script B ouvre lui aussi rouvre la session pour voir si l'utilisateur est connecté, il peut y avoir un problème.En effet, normalement la session PHP est refermée à la fin du script. Donc quand A redirige vers B, on fait
die() (ou
exit) dans A et A termine son exécution.
Mais le serveur peut être tellement rapide que le script B est déjà appelé par le navigateur client avant même que A ait fini son exécution, et donc le serveur exécute le script B qui demande d'ouvrir la session. Il y'a donc un
conflit et B (en tout cas c'est ce que j'ai constaté avec mes tests approximatifs) voit bien le tableau de session, mais celui-ci est vide. Et donc boum -> l'internaute est déconnecté.
La parade ?
Utiliser
session_write_close().
Soit après en avoir finit avec la session, c'est plus sur, soit juste avant l'appel à la fonction header(). Comme ça on est certain d'avoir fini de travailler sur la session et le script B peut l'ouvrir sans problème.
PS : je
pense que ça n'arrivait jamais en local car mon PC n'a pas du tout la même puissance que le serveur, bien que les temps de réponses soient bien plus infimes, mais ça n'est que mon interprétation.
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :