Maison développement back-end tutoriel php PHP Session原理分析及使用

PHP Session原理分析及使用

Dec 05, 2016 am 09:53 AM
php

之前在一个叫魔法实验室的博客中看过一篇《php session原理彻底分析》的文章,作者从session的使用角度很好阐述了在代码运行过程中,每个环节的变化以及相关参数的设置及作用。本来想把原文转帖过来,但是原博客被关闭了。不知是这次大范围的重新备案,还是其他什么原因所致。通过百度快照找到一些原文资料,没找到的将按之前的理解重新整理,以使大家对session能有更多了解。

楔子:Session大白话 

Session,英文翻译为“会话”,两个人聊天,从第一句问好,到最后一句再见,这就构成了一个会话。PHP里的session主要是指客户端浏览器与服务端数据交换的对话,从浏览器打开到关闭,一个最简单的会话周期。计算机语言一般怎么实现会话呢?举个通俗的例子:
服务端好比一个理发店,客户端好比每一个去理发的客人,很多理发店都有这种促销手段,连续消费10次的客人,可以免费一次,大概有三种方式来实现:
1、理发师傅记性太好,你来过几次,他看一眼就知道——这叫协议本身支持会话;
2、每个客人发一个会员卡,你每次消费,都要带着这个卡片,消费一次记录一笔,当然还要加盖印章——这叫通过cookie实现会话,缺点是安全性不高,我完全可以伪造会员卡或者公章;
3、理发店准备一个大帐本,客人每人对应一个会员号或者自己的个人资料,甚至密码,每个客人来消费,报一下自己的会员号,再把消费次数记录到大帐本里——这就是session实现会话,客人脑子里的会员号就是保存在客户端的SESSIONID,大帐本就是保存在服务端的session数据,这样相比第二种方法,安全性要高很多,除非你说你把自己的会员号和密码都搞丢了,这叫做伪造客户端的SESSIONID。
 
因为http协议是无状态的,所以php要实现会话只能通过后面两种方式,前一种cookie,缺点已经说了,安全性不高,所以重要的会话会选择使用session。session会话必须依靠一个标识,也可以理解成一个暗号,就是SESSIONID。这是个经过加密的串,保存在客户端,通常在cookie里,客户端与服务端的每次交流都是通过这个SESSIONID,客户端先自报家门,服务器才能找到你在服务端保存的会话数据,继续通话。

php.ini常用session设置 

[服务端]
session.save_handler = files
默认为file,定义session在服务端的保存方式,file意为把sesion保存到一个临时文件里,如果我们想自定义别的方式保存(比如用数据库),则需要把该项设置为user;
 
session.save_path = "/tmp/"
定义服务端存储session的临时文件的位置。
 
session.auto_start = 0
如置1,则不用在每个文件里写session_start(); session自动start。
 
session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
这三个配置组合构建服务端session的垃圾回收机制session.gc_probability与session.gc_divisor构成执行session清理的概率,理论上的解释为服务端定期有一定的概率调用gc函数来对session进行清理,清理的概率为:gc_probability/gc_divisor 比如:1/100  表示每一个新会话初始化时,有1%的概率会启动垃圾回收程序,清理的标准为session.gc_maxlifetime定义的时间。
 
[客户端]
session.use_cookies = 1
sessionid在客户端采用的存储方式,置1代表使用cookie记录客户端的sessionid,同时,$_COOKIE变量里才会有$_COOKIE[‘PHPSESSIONID’]这个元素存在;
 
session.use_only_cookies = 1
也是定义sessionid在客户端采用的存储方式,置1代表仅仅使用 cookie 来存放会话 ID。一般来说,现在客户端都会支持cookie,所以建议设置成1,这样可以防止有关通过 URL 传递会话 ID 的攻击。
 
session.use_trans_sid = 0
相对应于上面那个设置,这里如果置1,则代表允许sessionid通过url参数传递,同理,建议设置成0;
 
session.referer_check =  
这个设置在session.use_trans_sid = 1的时候才会生效,目的是检查HTTP头中的"Referer"以判断包含于URL中的会话id是否有效,HTTP_REFERER必须包含这个参数指定的字符串,否则URL中的会话id将被视为无效。所以一般默认为空,即不检查。  
 
session.name = PHPSESSID
定义sessionid的名称,即变量名,通过浏览器http工具可以查看PHPSESSID的值;
 
session.hash_function = 0
选择session_name的加密方式,0代表md5加密,1代表sha1加密,默认是0,但是据说用sha1方式加密,安全性更高;
 
session.hash_bits_per_character = 4
指定在session_name字符串中的每个字符内保存多少位二进制数,这些二进制数是hash函数的运算结果。
4   bits:   0-9,   a-f  
5   bits:   0-9,   a-v  
6   bits:   0-9,   a-z,   A-Z,   "-",   "," 
 
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset="
指定重写哪些HTML标签来包含sid(session_id)(仅在"session.use_trans_sid"打开的情况下有效),URL重写器将添加一个隐藏的"",它包含了本应当额外追加到URL上的信息。  
 
session.cookie_lifetime = 0
保存sessionid的cookie文件的生命周期,如置0,代表会话结束,则sessionid就自动消失,常见的强行关闭浏览器,就会丢失上一次的sessionid;
 
session.cookie_path = /
保存sessionid的cookie文件在客户端的位置;
 
session.cookie_domain = /
保存sessionid的cookie的域名设置,这跟cookie允许的域名的访问权限设置有关,一般来说想让自己网站所有的目录都能访问到客户端的cookie,就应该设置成“/”如需要详细了解,可以看下setcookie()函数的domain参数相关设置和使用方法;
 
session.bug_compat_42 = 1
session.bug_compat_warn = 1
这两个可以说几乎是快要被废弃的设置,是为了老版本的php服务的,主要是针对session_register函数,因为php5的register_global默认是关闭状态,所以在php5里根本用不到session_register这个函数;并且php6就要废除这个设置,直接定义为关闭,所以没必要研究这两个了;


session_start()做了些什么? 

假设php.ini中session的几个关键参数配置为:
session.save_handler = files
session.use_cookies = 1
session.name = PHPSESSID
session.save_path = "/tmp/"

 

下面通过代码样例阐述,在一个会话过程中session_start的作用。

程序1:
session_start();
$_SESSION['uname'] = 'monkey';
$_SESSION['ukey'] = 20119999;
?>


程序1执行后,session_start()会做两件事:


1、在客户端生成一个存放PHPSESSID的cookie文件,这个文件的存放位置和存放方式跟程序的执行方式有关,不同的浏览器也不尽相同,这一步会产生一个序列化后的字符串——PHPSESSID;查看浏览器中的cookie信息,可以安装相关插件。firefox中httpfox,web developer等都是很好的工具。


2、在服务端生成一个存放session数据的临时文件,存放的位置由session.save_path参数指定,名称类似于“sess_85891d6a81ab13965d349bde29b2306c”,“sess_”代表这是个session文件,“85891d6a81ab13965d349bde29b2306c”即此次会话的PHPSESSID,跟客户端的PHPSESSID值是一样的。
用编辑器打开“sess_85891d6a81ab13965d349bde29b2306c”文件,会看到一串“uname|s:6:"monkey";ukey|i:20119999;”这样的内容。这个文件里存放的就是$_SESSION变量的具体内容,每个变量用“;"分号隔开。


格式为:变量名 | 变量类型 : [长度] : 值; 例如: uname|s:6:"monkey"; 表示SESSION变量uname的类型为字符串,值长度为6,值为monkey.

那么问题来了,上面说的两件事,是在程序执行到session_start(),就完成的吗?这两件事,谁先谁后呢?
让试验来证明,稍微改动一下程序:

程序2:
session_start();
$_SESSION['uname'] = 'monkey';
$_SESSION['ukey'] = 20119999;

sleep(30);
?>  

先把客户端和服务端的session数据通通删除,然后执行程序2,趁着程序里的sleep30秒的工夫,去查看客户端和服务端的session情况,发现:在程序执行过程中,客户端并没有建立保存PHPSESSID的cookie文件,服务端却已经有了保存session内容的临时文件,但是文件里没有内容,等30秒时间过了之后,客户端的cookie文件才会生成,服务端的session文件里才有了内容。


由此推断大致流程应该为:在程序执行到session_start()的时候,服务端首先生成PHPSESSID,并生成相对应的session文件,但是在程序进行$_SESSION赋值的时候,并没有把相应的值写入到session文件里,姑且臆断为保存在内存里吧,到了程序执行完毕后,才会在客户端生成保存PHPSESSID的cookie文件,并把$_SESSION变量里的值写入服务端的session文件里,至于最后两个步骤谁先谁后,暂时还没有想到好办法来证明。
 

为了更进一步论证,删除客户端和服务端的session相关内容执行程序3,观察第一次和第二次的结果:
程序3:
session_start();
$_SESSION['uname'] = 'monkey';
$session_id = session_id();
$sess_file = "/tmp/sess_".$session_id;
$content = file_get_contents($sess_file);

echo '***'.$_COOKIE['PHPSESSID'] .'***';
echo '
' . $_SESSION['uname'] . '
'; 
echo '***'.$content.'***'; 
?>  
 

上面说的是第一次sessin_start()的执行方式,也就是一套程序里,第一个session_start()出现的时候所做的事情,下面来看之后的session_start(): 

假设的php.ini配置:session.cookie_lifetime = 0        

程序4:
session_start();
echo $_SESSION['uname'];
echo $_SESSION['ukey'];
?>  

现在,客户端已经有了保存PHPSESSID的cookie文件,服务端也有了保存session内容的sess_文件,执行程序4,会打印出正常的内容。这时,如果强行关闭浏览器,再执行程序4,结果会怎样呢?

 

首先,session.cookie_lifetime设置成0,表示客户端保存PHPSESSID的cookie文件的生存周期为0,浏览器如果处于开启状态,PHPSESSID的值会保存在内存中,一旦强行关闭,保存PHPSESSID的cookie文件会同时销毁,但是服务端并没有执行session_destroy(),所以,服务端的session数据文件还在,但是当浏览器再次打开执行程序4,发现什么都没有输出,由此推理:


session_start()首先会去获取客户端cookie里的PHPSESSID,然后与“sess_”组成文件名,去服务端查找这个文件,然后取出文件里的内容,把内容放到$_SESSION全局变量里以供使用。浏览器强行关闭,再打开,之前的PHPSESSID丢失,这时遇到session_start()就相当于上面说的第一次执行,会生成一个新的PHPSESSID,这个PHPSESSID匹配不到之前那个服务端的sess_文件,所以取不到内容。当然,服务端也有能跟这个PHPSESSID匹配的文件,不过,那个文件还是空的。


所以,有的系统为了实现同一用户只能在一台机器甚至一个浏览器登录的机制,如果没有修改session.cookie_lifetime的设置,就会出现强行关闭浏览器之后,在服务端session生存期截止前该,用户登录不进去的情况,比较好的办法是把session.cookie_lifetime设置成一个比较大的值,反正一个cookie文件存在时间久一些也没什么影响。


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

7 fonctions PHP que je regrette de ne pas connaître auparavant 7 fonctions PHP que je regrette de ne pas connaître auparavant Nov 13, 2024 am 09:42 AM

Si vous êtes un développeur PHP expérimenté, vous aurez peut-être le sentiment d'y être déjà allé et de l'avoir déjà fait. Vous avez développé un nombre important d'applications, débogué des millions de lignes de code et peaufiné de nombreux scripts pour réaliser des opérations.

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Apr 05, 2025 am 12:04 AM

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Comment analysez-vous et traitez-vous HTML / XML dans PHP? Comment analysez-vous et traitez-vous HTML / XML dans PHP? Feb 07, 2025 am 11:57 AM

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

Programme PHP pour compter les voyelles dans une chaîne Programme PHP pour compter les voyelles dans une chaîne Feb 07, 2025 pm 12:12 PM

Une chaîne est une séquence de caractères, y compris des lettres, des nombres et des symboles. Ce tutoriel apprendra à calculer le nombre de voyelles dans une chaîne donnée en PHP en utilisant différentes méthodes. Les voyelles en anglais sont a, e, i, o, u, et elles peuvent être en majuscules ou en minuscules. Qu'est-ce qu'une voyelle? Les voyelles sont des caractères alphabétiques qui représentent une prononciation spécifique. Il y a cinq voyelles en anglais, y compris les majuscules et les minuscules: a, e, i, o, u Exemple 1 Entrée: String = "TutorialSpoint" Sortie: 6 expliquer Les voyelles dans la chaîne "TutorialSpoint" sont u, o, i, a, o, i. Il y a 6 yuans au total

Expliquez la liaison statique tardive en PHP (statique: :). Expliquez la liaison statique tardive en PHP (statique: :). Apr 03, 2025 am 12:04 AM

Liaison statique (statique: :) ​​implémente la liaison statique tardive (LSB) dans PHP, permettant à des classes d'appel d'être référencées dans des contextes statiques plutôt que de définir des classes. 1) Le processus d'analyse est effectué au moment de l'exécution, 2) Recherchez la classe d'appel dans la relation de succession, 3) il peut apporter des frais généraux de performance.

Quelles sont les méthodes PHP Magic (__construct, __ destruct, __ call, __get, __set, etc.) et fournir des cas d'utilisation? Quelles sont les méthodes PHP Magic (__construct, __ destruct, __ call, __get, __set, etc.) et fournir des cas d'utilisation? Apr 03, 2025 am 12:03 AM

Quelles sont les méthodes magiques de PHP? Les méthodes magiques de PHP incluent: 1. \ _ \ _ Construct, utilisé pour initialiser les objets; 2. \ _ \ _ Destruct, utilisé pour nettoyer les ressources; 3. \ _ \ _ Appel, gérer les appels de méthode inexistants; 4. \ _ \ _ GET, Implémentez l'accès à l'attribut dynamique; 5. \ _ \ _ SET, Implémentez les paramètres d'attribut dynamique. Ces méthodes sont automatiquement appelées dans certaines situations, améliorant la flexibilité et l'efficacité du code.

See all articles