首页 后端开发 php教程 PHP中如何将session存入数据库并使用

PHP中如何将session存入数据库并使用

Aug 07, 2018 am 10:24 AM
php session

PHP中如何将session存入数据库并使用

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

实例说明:

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

相关专题推荐php session (包含图文、视频、案例)

设计过程

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

表名为t_session

表结构为

d3419c938fa7470eb60018041121b27.png

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

  • <span style="color:#3a3737;">session_data</span>:是用来存经序列化后的$_SESSION[]里的值;

  • <span style="color:#3a3737;">session_time</span>:是用来存时间戳的,这个时间戳指的是当前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用户登录界面

<?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(&#39;您不久前刚来过&#39;);window.location.href=&#39;main.php&#39;;</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(&#39;登录成功!&#39;);window.location.href=&#39;main.php&#39;;</script>";

}

}


?>
登录后复制

main.php主内容页

<?php


include("session_set_save_handler.php");


session_start();


if(isset($_SESSION["user"])){


echo "欢迎".$_SESSION["user"];

echo "<a href=&#39;index.php?login=0&#39;>注销</a>";


}else{


echo "您还没登录,请先登录!";

echo "<a href=&#39;index.php&#39;>登录</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=&#39;$key&#39; 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=&#39;$key&#39;";


$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(&#39;$key&#39;,&#39;$data&#39;,$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=&#39;$key&#39;,session_data=&#39;$data&#39;,session_time=$over_time where session_key=&#39;$key&#39;";


$result=mysqli_query($con,$sql);

}




return($result);


}

清楚相应的session数据

function destroy($key){




global $con;


$sql="delete from t_session where session_key=&#39;$key&#39;";


$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(&#39;open&#39;,&#39;close&#39;,&#39;read&#39;,&#39;write&#39;,&#39;destroy&#39;,&#39;overdue&#39;);


?>
登录后复制

相关文章推荐:

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

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

以上是PHP中如何将session存入数据库并使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1276
29
C# 教程
1256
24
PHP与Python:了解差异 PHP与Python:了解差异 Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP的持久相关性:它还活着吗? PHP的持久相关性:它还活着吗? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP和Python:解释了不同的范例 PHP和Python:解释了不同的范例 Apr 18, 2025 am 12:26 AM

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

PHP与其他语言:比较 PHP与其他语言:比较 Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP和Python:代码示例和比较 PHP和Python:代码示例和比较 Apr 15, 2025 am 12:07 AM

PHP和Python各有优劣,选择取决于项目需求和个人偏好。1.PHP适合快速开发和维护大型Web应用。2.Python在数据科学和机器学习领域占据主导地位。

See all articles