Maison > Article > développement back-end > Comment stocker une session dans une base de données et l'utiliser en PHP
Cet article vous présente comment stocker et utiliser des sessions dans la base de données en PHP (avec du code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. vous aide.
Exemple de description :
Il est plus sûr de stocker les variables de données SESSION côté serveur Mais imaginez un grand site Web comme Xiaonei.com avec plus de 100 millions de visites quotidiennes et des dizaines de millions d'utilisateurs si toutes les données de SESSION utilisateur sont stockées sur le serveur, cela consommera d'énormes ressources du serveur. Par conséquent, lorsque les programmeurs créent de grands sites Web , il est sûr de stocker SESSION côté serveur, mais ce n'est pas le meilleur choix. Si les données SESSION sont stockées dans la base de données, cela peut réduire la pression sur le serveur et les données sont relativement sûres.
Recommandations de sujets connexes : session php (y compris des photos, des vidéos, des cas)
Processus de conception
Créez d'abord une table pour stocker SESSION dans la base de données Mysql :
table La structure de table nommée t_session
est
Description : session_key : Oui
<code><span style="color:#3a3737;">session_data</span>
session_data : utilisé pour stocker le $_SESSION sérialisé La valeur dans
<span style="color:#3a3737;">session_time</span>
<span style="color:#3a3737;">session_time</span>
Alors, qu'est-ce que la sérialisation ?
La sérialisation est le processus de conversion des informations d'état d'un objet en une forme qui peut être stockée ou transmise. Lors de la sérialisation, un objet écrit son état actuel dans un stockage temporaire ou persistant. Plus tard, l'objet peut être recréé en lisant ou en désérialisant l'état de l'objet à partir du magasin.
$_SESSION[“user”]=”张三” $_SESSION[“pwd”]=”zhangsan”Par exemple,
user|s:6:"张三";pwd|s:8:"zhangsan";devient une chaîne après la séquence
où s représente le type sous forme de chaîne et le nombre représente la longueur de la chaîne , afin que vous puissiez Cette chaîne est manipulée.
L'étape suivante est le texte principalsession.save_handler Définir le nom du gestionnaire qui stocke et récupère les données associées à la séance. La valeur par défaut est fichiers. S'il est défini sur files (session.save_handler = files), le mécanisme intégré de PHP est utilisé. Si vous souhaitez personnaliser la méthode de stockage (comme le stockage dans une base de données), utilisez session_set_save_handler() pour personnaliser les paramètres . ,
Ce dont nous parlons ici, c'est du deuxième type.Nous devons donc modifier la valeur de session_set_save_handler dans le fichier php.ini en user
, comme Photo :bool session_set_save_handler ( callable open , appelable $close , appelable lire , appelable écrire , appelable détruire , appelable gc [, callable $create_sid [, callable validate_sid [, callable update_timestamp ]]] )
Si vous ne le modifiez pas, alors vous utilisez Vous pouvez l'ignorer pendant la séance, mais lorsque vous apportez des modifications, vous devez lui faire face. C'est une fonction très particulière, car les paramètres des fonctions générales sont des variables, mais les paramètres de cette fonction sont 6 fonctions (les trois derniers paramètres sont des paramètres facultatifs et peuvent être ignorés) N'ayez pas peur, venez un par un :
Le premier paramètre : open(save_path,session_name), les deux paramètres ici sont automatiquement passés par php. save_path est session.save_path lorsque session.save_handler = files, et session_name est l'ID de session utilisé par le serveur pour identifier le client. Cependant, si l'utilisateur le personnalise, ces deux paramètres ne sont pas utilisés et se connectent uniquement à la base de données. La fonction de rappel open est similaire au constructeur d'une classe et sera appelée à l'ouverture de la session. Il s'agit de la première fonction de rappel appelée après le démarrage d'une session automatiquement ou manuellement en appelant session_start() . Cette fonction de rappel renvoie VRAI si l'opération réussit, sinon elle renvoie FAUX.
Le deuxième paramètre : close(), cette fonction ne nécessite pas de paramètres et sert à fermer la base de données. La fonction de rappel close est similaire au destructeur d'une classe. Appelé après l’appel de la fonction de rappel d’écriture. Lorsque la fonction session_write_close() est appelée, la fonction de rappel close sera également appelée. Cette fonction de rappel renvoie VRAI si l'opération réussit, sinon elle renvoie FAUX.
Le troisième paramètre : read($key), le paramètre ici est l'ID de session, qui est automatiquement transmis par php. Le principe du passage est qu'il existe un ID de session If. non, alors ce paramètre renvoie une chaîne vide. Notez que s'il n'y a pas de données correspondantes dans la base de données, une chaîne vide doit être renvoyée, sinon une erreur sera signalée ! S'il y a des données dans la session, la fonction de rappel de lecture doit renvoyer une chaîne qui code (sérialise) les données de session (dans ce cas, les données de session extraites de la table t_session). Après avoir démarré une session automatiquement ou manuellement en appelant la fonction session_start(), PHP appelle en interne la fonction de rappel read pour obtenir les données de session. Avant d'appeler read, PHP appelle la fonction de rappel open. Le format de la chaîne sérialisée renvoyée par le rappel de lecture doit être exactement le même que celui utilisé lorsque la fonction de rappel d'écriture enregistre les données. PHP désérialisera automatiquement la chaîne renvoyée et remplira la super variable globale $_SESSION.
Le quatrième paramètre : write($key,$data), ces deux paramètres sont également passés automatiquement à cette fonction par PHP, $key correspond à l'ID de session, $data correspond à le courant (la fonction d'écriture étant généralement appelée après l'exécution du script), la variable de session traitée par le script est sérialisée par le processeur (par exemple $_SESSION["user"]="Zhang San" $_SESSION["pwd"] mentionné ci-dessus = "zhangsan"), le processus de sérialisation des données de session est complété par PHP selon la valeur du paramètre session.serialize_handler. Les données sérialisées seront enregistrées en association avec l'ID de session. Lors de l'appel de la fonction de rappel de lecture pour obtenir des données, les données renvoyées doivent être totalement cohérentes avec les données transmises à la fonction de rappel d'écriture. PHP appellera cette fonction de rappel une fois l'exécution du script terminée ou la fonction session_write_close() appelée. Notez qu'après avoir appelé cette fonction de rappel, PHP appellera la fonction de rappel close en interne.
REMARQUE :PHP n'appellera pas la fonction de rappel d'écriture tant que le flux de sortie n'est pas écrit et fermé, donc les informations de débogage dans la fonction de rappel d'écriture ne seront pas affichées dans le navigateur. Si vous devez utiliser la sortie de débogage dans la fonction de rappel d'écriture, il est recommandé d'écrire la sortie de débogage dans un fichier.
第五个参数: destroy($key),当调用 session_destroy() 函数, 或者调用 session_regenerate_id() 函数并且设置 destroy 参数为 TRUE 时, 会调用此回调函数。用来注销session对应的SESSION键值,此回调函数操作成功返回 TRUE,反之返回 FALSE。它就是人们常常在点击注销登录的时候用到的函数。后面会有这个小细节。
第六个参数: gc(expire_time),这个函数的参数在默认机制下就是session.gc_maxlifetime设置的session有效时间。但是,user机制下session的过期时间在就是表里session_time,所以这里不需要传递参数的。为了清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。 调用周期由 session.gc_probability 和 session.gc_pisor 参数控制。此回调函数操作成功返回 TRUE,反之返回 FALSE。
至此六个函数已经介绍完了,但是其中有许多需要说明的:
1、在open函数中本来是要传递save__path,目的是用来在这个路径下找到与session_name相对应的文件,然后通过read()函数来读取其中的数据,然后通过反序列化处理器将取到的字符串反序列化,在通过php自动填充各个$_session超全局变量。或者write函数来将序列化的数据存入这个路径下的文件。那么这里面的路径在非默认机制下难道就不需要吗,答案是肯定的*_*。当在非默认机制下,调试输出session_save_path,其结果为空值;而且如果未设置存储的路径,那被填充的$_session变量也只能在当前页面使用,而不能在别的页面使用,可以这样测试:在另一个页面利用session_start()函数打开会话,然后输出session_id和var_dump($_session),得到的是上一次浏览时服务器给客户端的session_id,但是$_session输出的是空数组(当然我这里只是大概的说一下我在验证时的过程)。其实我想说的就是我们在自定义会话存储机制的时候,是不需要自定义路径的,不然为什么还要存入数据库呢?
那么怎么在其他页面也能读取到$_session[]里面的值呢?
引入这个函数,即将六个 回调函数和session_set_save_handler放入一个文件里,然后在session_start()前用include()引入!
2、那他们的执行顺序是怎样呢?有点晕吧,来总结一下:首先session_start()函数打开session操作句柄,然后read函数读取数据,当脚本执行结束的时候执行write函数然后是close函数若有session_destroy()则执行完。
3、上面我提到过PHP 会在输出流写入完毕并且关闭之后才调用 write 回调函数,这个可把我玩坏啦,小编在上面可绕了不久呀,不然我也不会在write函数里调试那么久了!不过我也因此了解了register_shutdown_function这个函数,下面附上这个函数的特点吧:register_shutdown_function()是指在执行完所有PHP语句后再调用函数,不要理解成客户端关闭流浏览器页面时调用函数。
可以这样理解调用条件:
1、当页面被用户强制停止时
2、当程序代码运行超时时
3、当PHP代码执行完成时,代码执行存在异常和错误、警告
好了以上该说的都说完了,附上代码吧:
index.php用户登录界面
<?php include("session_set_save_handler.php");//引入自定义的会话存储机制 if(isset($_GET["login"])){//判断login是否有值,若有值则要进行注销, session_start();//只要需要 用到$_session变量的地方,就需要开启回调函数open session_destroy();//这里就是上文提到的 小细节了,当有session_destroy的时候,它是先于read回调函数执行的 }else{ session_start(); if(isset($_SESSION["user"])){//判断此值是否有定义,若有定义则说明 存入的session还未到期,则直接转到主内容 echo "<script>alert('您不久前刚来过');window.location.href='main.php';</script>"; } } ?> <html> <meta charset="utf-8"> <body> <form action="index_ok.php" method="post"> 账 户:<input type="text" name="user"><br> 密 码:<input type="text" name="pwd"> <input type="submit" name="sub"> </form> </body> </html>
index_ok.php表单提交处理文件
<?php include("session_set_save_handler.php"); session_start(); if($_POST["sub"]){//$_post["sub"]它若有值就是 提交查询 echo $_POST["sub"]; if($_POST["user"]!=""&&$_POST["pwd"]!=""){ $_SESSION["user"]=$_POST["user"]; $_SESSION["pwd"]=$_POST["pwd"];//这里自定义的会话管理机制将会调用回调函数write,将已由序列化处理器处理好的(由$_session[]变量形成)字符串写入数据库 echo "<script>alert('登录成功!');window.location.href='main.php';</script>"; } } ?>
main.php主内容页
<?php include("session_set_save_handler.php"); session_start(); if(isset($_SESSION["user"])){ echo "欢迎".$_SESSION["user"]; echo "<a href='index.php?login=0'>注销</a>"; }else{ echo "您还没登录,请先登录!"; echo "<a href='index.php'>登录</a>"; } ?>
session_set_save_handler.php自定义session存储机制函数文件
<?php //打开会话 function open(){ global $con;//使用全局变量 $con=mysqli_connect("localhost","root","123456","mysql")or die("数据库连接失败!"); mysqli_query($con,"set names utf8"); return(true); } //关闭数据库 function close(){ global $con; mysqli_close($con); return(true); } //读取session_data function read($key){ global $con; $time=time(); //不读取已过期的session $sql="select session_data from t_session where session_key='$key' and session_time>$time"; $result=mysqli_query($con,$sql)or die("查询失败!"); if (!$result) {//用来检查出现再数据库部分的错误,很有用 printf("Error: %s\n", mysqli_error($con));//%s表示的是字符串,这是c里面的 exit(); } $row=mysqli_fetch_array($result);//or die()会终止后面的程序! if($row!=false){ return($row["session_data"]); }else{ return "";//再次强调如果空值 ,则一定 要返回”“而不是false } } //存储session function write($key,$data){ global $con; $over_time=time()+60;//注意time()为时间戳,在mysql中的数据类型不可用用date,datetime,timestamp来存储 $sql="select session_data from t_session where session_key='$key'"; $re=mysqli_query($con,$sql); $result=mysqli_fetch_array($re); //若$result为false,即结果 为空,说明数据库中未存有相应的session_id,那么就插入,如果不为空,那即使还有未过期的session_id,这是应更新 if($result==false){ $sql="insert into t_session(session_key,session_data,session_time ) values('$key','$data',$over_time)";//字符串的时候要加单引号,数字的时候是不用加的 $result=mysqli_query($con,$sql); if (!$result) {//用来检查出现再数据库部分的错误,很有用 printf("Error: %s\n", mysqli_error($con));//%s表示的是字符串,这是c里面的 exit(); } }else{ $sql="update t_session set session_key='$key',session_data='$data',session_time=$over_time where session_key='$key'"; $result=mysqli_query($con,$sql); } return($result); } 清楚相应的session数据 function destroy($key){ global $con; $sql="delete from t_session where session_key='$key'"; $result=mysqli_query($con,$sql); return($result); } //执行垃圾回收 function overdue($expire_time){//这个参数是自动传进去的,就是session.gc_maxlifetime最大有效时间,例如1440s; global $con; $time=time(); $sql="delete from t_session where session_time<$time"; $result=mysqli_query($sql); return($result); } session_set_save_handler('open','close','read','write','destroy','overdue'); ?>
相关文章推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!