各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案

Str Tom,为分享PHP技术和解决方案,贡献一份自己的力量!
收藏本站(不迷路),每天更新好文章!
当前位置:首页 > CMS教程 > PHP

PHP中如何将session存入数据库并使用(附代码)

管理员 2023-09-05
PHP
138

PHP中如何将session存入数据库并使用(附代码)

内容导读

收集整理的这篇技术教程文章主要介绍了PHP中如何将session存入数据库并使用(附代码),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10360字,纯文字阅读大概需要15分钟

内容图文

这篇文章给大家介绍的内容是关于PHP中如何将session存入数据库并使用(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

实例说明:

将SESSION数据变量存储于服务器是端是一种较安全的做法,但是设想一下,像校内网这样的日访问量过亿,拥有用户几千万的大型网站,如果将所有用户SESSION数据全部存储于服务器端,将消耗巨大的服务器资源。所以程序员在制作大型网站时将SESSION存储于服务器端虽然安全,但却不是最好的选择。如果将SESSION数据存储于数据库中,那么就可以减轻服务器的压力同时数据也是比较安全的。

设计过程

首先在Mysql数据库创建存储SESSION的表:

表名为t_session

表结构为

说明:session_key:是用来存会话ID的

session_data:是用来存经序列化后的$_SESSION[]里的值;

session_time:是用来存时间戳的,这个时间戳指的是当前session在创建时的 time()+session的有效期。需要注意的是这 里的session_time的类型是int,这样可以在操作数据库时,进行大小比较!

那么什么是序列化呢?

序列化 (Serialization)就是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

比如说

$_SESSION[“user”]=”张三”$_SESSION[“pwd”]=”zhangsan”

序列话后成为一个字符串

user|s:6:"张三";pwd|s:8:"zhangsan";

其中s表示类型为string,数字表示字符串长度,这样就可以对这个字符串操作了。

接下来就是正文部分了

session.save_handler 定义存储和获取与会话关联的数据的处理器的名字。默认为 files。如果设定为files(session.save_handler = files),则采用的是php内置机制,如果想自定义存储方式(比如存储到数据库中),则使用session_set_save_handler()进行自定义设置我们这里说的则是第二种。

所以我们得修改php.ini文件里session_set_save_handler的值,将其修改为user,如图:

bool session_set_save_handler ( callable open , callable $close , callable read , callable write , callable destroy , callable gc [, callable $create_sid [, callable validate_sid [, callable update_timestamp ]]] )

如果不修改,那你在使用session的时候可以不用理他,但当你修改 了,你不得不面对他。这是一个很特殊的函数,因为一般的函数的参数都是变量,但是该函数的参数为6个函数(后面的三个参数为可选参数,可忽略)不用怕,一个一个来:

第一个参数: open(save_path,session_name),这里面的两个参数是php自动传递的。save_path 在session.save_handler = files的情况下它就是session.save_path,session_name则是服务器用来识别客户端的会话ID,但是如果用户自定的话,这个两个参数都用不上,只在其中连接数据库,open 回调函数类似于类的构造函数,在会话打开的时候会被调用。 这是自动开始会话或者通过调用 session_start() 手动开始会话之后第一个被调用的回调函数。 此回调函数操作成功返回 TRUE,反之返回 FALSE。

第二个参数: close(),这个函数不需要参数,用来关闭数据库。close 回调函数类似于类的析构函数。 在 write 回调函数调用之后调用。 当调用 session_write_close() 函数之后,也会调用 close 回调函数。 此回调函数操作成功返回 TRUE,反之返回 FALSE。

第三个参数: read($key),这里面的参数是会话ID,php自动传递的,传递的前提是有会话ID,若无,则这个参数返回空字符串。注意,若数据库中无对应的数据一定要返回空字符串,否则报错!如果会话中有数据,read 回调函数必须返回将会话数据编码(序列化)后的字符串(在此处就是从表t_session里取出的session_data)。在自动开始会话或者通过调用 session_start()函数手动开始会话之后,PHP 内部调用 read 回调函数来获取会话数据。 在调用 read 之前,PHP 会调用 open 回调函数。read 回调返回的序列化之后的字符串格式必须与 write 回调函数保存数据 时的格式完全一致。 PHP 会自动反序列化返回的字符串并填充 $_SESSION 超级全局变量。

第四个参数: write($key,$data), 这两个参数也是php自动传递给这个函数的,$key对应会话ID,$data对应当前(因为write函数一般是在脚本执行结束后才被调用的)脚本被序列化处理器处理的session变量(如上文提到的$_SESSION[“user”]=”张三”$_SESSION[“pwd”]=”zhangsan”),序列化会话数据的过程由 PHP 根据 session.serialize_handler 设定值来完成。序列化后的数据将和会话 ID 关联在一起进行保存。 当调用 read 回调函数获取数据时,所返回的数据必须要和 传入 write 回调函数的数据完全保持一致。PHP 会在脚本执行完毕或调用 session_write_close() 函数之后调用此回调 函数。注意,在调用完此回调函数之后,PHP 内部会调用 close 回调函数。

NOTE:PHP 会在输出流写入完毕并且关闭之后 才调用 write 回调函数, 所以在 write 回调函数中的调试信息不会输出到浏览器中。 如果需要在 write 回调函数中使用调试输出, 建议将调试输出写入到文件。

第五个参数: 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用户登录界面

<?phpinclude("session_set_save_handler.php");//引入自定义的会话存储机制if(isset($_GET["login"])){//判断login是否有值,若有值则要进行注销,session_start();//只要需要 用到$_session变量的地方,就需要开启回调函数opensession_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表单提交处理文件

<?phpinclude("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主内容页

<?phpinclude("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_datafunction 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: %sn", mysqli_error($con));//%s表示的是字符串,这是c里面的exit();}$row=mysqli_fetch_array($result);//or die()会终止后面的程序!if($row!=false){return($row["session_data"]);}else{return "";//再次强调如果空值 ,则一定 要返回”“而不是false}}//存储sessionfunction 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: %sn", 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');?>

相关文章推荐:

php使用PHPMailer如何发送邮件(附代码)

PHP中常用的一些功能总结(归纳)

以上就是PHP中如何将session存入数据库并使用(附代码)的详细内容,更多请关注Gxl网其它相关文章!

内容总结

以上是为您收集整理的PHP中如何将session存入数据库并使用(附代码)全部内容,希望文章能够帮你解决PHP中如何将session存入数据库并使用(附代码)所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。

内容备注

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

扫码关注

qrcode

QQ交谈

回顶部