>백엔드 개발 >PHP 튜토리얼 >데이터베이스에 세션을 저장하고 PHP에서 사용하는 방법

데이터베이스에 세션을 저장하고 PHP에서 사용하는 방법

不言
不言원래의
2018-08-07 10:24:125968검색

데이터베이스에 세션을 저장하고 PHP에서 사용하는 방법

이 글은 PHP에서 데이터베이스에 세션을 저장하고 사용하는 방법(코드 포함)을 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

예제 설명:

SESSION 데이터 변수를 서버에 저장하는 것이 더 안전한 접근 방식이지만 Xiaonei.com과 같은 웹사이트의 일일 방문 횟수가 1억 건이 넘고 사용자가 수천 명에 달한다고 상상해 보세요. 수만 명의 사용자가 있는 웹 사이트는 모든 사용자 SESSION 데이터를 서버에 저장하므로 막대한 서버 리소스를 소비하게 됩니다. 따라서 프로그래머가 대규모 웹사이트를 만들 때 SESSION을 서버측에 저장하는 것이 안전하지만 최선의 선택은 아닙니다. SESSION 데이터를 데이터베이스에 저장하면 서버에 대한 부담을 줄일 수 있고 데이터도 비교적 안전하다. 관련 주제 추천

:
php 세션

(그림, 텍스트, 비디오, 사례 포함)

디자인 프로세스

먼저 Mysql 데이터베이스에 SESSION을 저장할 테이블을 만듭니다.

테이블 이름은 t_session

테이블 구조는

설명: 데이터베이스에 세션을 저장하고 PHP에서 사용하는 방법

session_key: 세션 ID를 저장하는 데 사용됩니다

session_data
    code>
  • :예 직렬화 후 $_SESSION[]에 값을 저장하는 데 사용됩니다.

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

  • <span style="color:#3a3737;">session_time</span>

  • session_time

: 타임스탬프를 저장하는 데 사용됩니다. . 생성된 시간() + 세션 유효 기간. 여기서 session_time의 타입은 int이므로 데이터베이스 운영 시 크기 비교가 가능하다는 점 참고해주세요!

그럼 직렬화란 무엇일까요?

직렬화(Serialization)는 객체의 상태 정보를 저장하거나 전송할 수 있는 형태로 변환하는 과정입니다. 직렬화 중에 객체는 현재 상태를 임시 또는 영구 저장소에 씁니다. 나중에 저장소에서 개체의 상태를 읽거나 역직렬화하여 개체를 다시 만들 수 있습니다.

예를 들어

$_SESSION[“user”]=”张三”
$_SESSION[“pwd”]=”zhangsan”
시퀀스는 문자열이 됩니다
user|s:6:"张三";pwd|s:8:"zhangsan";

여기서 s는 유형을 문자열로 나타내고 숫자는 문자열의 길이를 나타내므로 이 문자열에 대해 연산을 수행할 수 있습니다.

다음 단계는 텍스트 부분입니다. session.save_handler 세션과 관련된 데이터를 저장하고 가져오는 핸들러의 이름을 정의합니다. 기본값은 files입니다. 파일(session.save_handler = files)로 설정되면 PHP의 내장 메커니즘이 사용됩니다. 저장 방법(예: 데이터베이스에 저장)을 사용자 정의하려면 session_set_save_handler()를 사용하여 설정을 사용자 정의하세요.

,

us 제가 여기서 말하는 것은 두 번째 유형입니다. 따라서 그림과 같이 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 ]]] ) #🎜 🎜 #수정하지 않는다면 세션 사용시에는 무시해도 되지만 수정할 때에는 직시해야 합니다. 이것은 매우 특별한 함수입니다. 일반 함수의 매개변수는 변수이지만 이 함수의 매개변수는 6개의 함수입니다(마지막 3개의 매개변수는 선택적 매개변수이므로 무시할 수 있습니다). 두려워하지 말고 하나씩 옵니다: # 🎜 🎜#첫 번째 매개변수: open(save_path,session_name), 여기에 있는 두 매개변수는 PHP에 의해 자동으로 전달됩니다. session.save_handler = files일 때 save_path는 session.save_path이고, session_name은 클라이언트를 식별하기 위해 서버에서 사용하는 세션 ID입니다. 그러나 사용자가 이를 사용자 정의하는 경우 이 두 매개변수는 사용되지 않고 데이터베이스에만 연결됩니다. 오픈 콜백 함수는 클래스의 생성자와 유사하며 세션이 열릴 때 호출됩니다. session_start()를 호출하여 자동 또는 수동으로 세션을 시작한 후 호출되는 첫 번째 콜백 함수입니다. 이 콜백 함수는 작업이 성공하면 TRUE를 반환하고, 그렇지 않으면 FALSE를 반환합니다.

두 번째 매개변수: close(), 이 함수는 매개변수가 필요하지 않으며 데이터베이스를 닫는 데 사용됩니다. 닫기 콜백 함수는 클래스의 소멸자와 유사합니다. 쓰기 콜백 함수가 호출된 후에 호출됩니다. session_write_close() 함수가 호출되면 닫기 콜백 함수도 호출됩니다. 이 콜백 함수는 작업이 성공하면 TRUE를 반환하고, 그렇지 않으면 FALSE를 반환합니다.

세 번째 매개변수: read($key), 여기서 매개변수는 php에서 자동으로 전달되는 세션 ID입니다. 세션 ID가 아닌 경우 이 매개변수는 빈 문자열을 반환합니다. 데이터베이스에 해당 데이터가 없으면 빈 문자열이 반환되어야 하며, 그렇지 않으면 오류가 보고됩니다! 세션에 데이터가 있는 경우 읽기 콜백 함수는 세션 데이터(이 경우 t_session 테이블에서 가져온 session_data)를 인코딩(직렬화)하는 문자열을 반환해야 합니다. session_start() 함수를 호출하여 자동 또는 수동으로 세션을 시작한 후 PHP는 내부적으로 읽기 콜백 함수를 호출하여 세션 데이터를 얻습니다. 읽기를 호출하기 전에 PHP는 공개 콜백 함수를 호출합니다. 읽기 콜백에서 반환된 직렬화된 문자열의 형식은 쓰기 콜백 함수가 데이터를 저장할 때의 형식과 정확히 동일해야 합니다. PHP는 반환된 문자열을 자동으로 역직렬화하고 $_SESSION 슈퍼 전역 변수를 채웁니다.

네 번째 매개변수: write($key,$data), 이 두 매개변수도 PHP에 의해 이 함수에 자동으로 전달됩니다. $key는 세션 ID에 해당합니다. $ data는 스크립트의 직렬화 프로세서가 처리하는 현재 세션 변수(예: $_SESSION["user"]="Zhang San"$_SESSION[ 위에서 언급한 "pwd"]="zhangsan"), 세션 데이터를 직렬화하는 프로세스는 session.serialize_handler 설정 값에 따라 PHP에 의해 완료됩니다. 직렬화된 데이터는 세션 ID와 연관되어 저장됩니다. 데이터를 얻기 위해 읽기 콜백 함수를 호출할 때 반환된 데이터는 쓰기 콜백 함수에 전달된 데이터와 완전히 일치해야 합니다. PHP는 스크립트 실행이 완료되거나 session_write_close() 함수가 호출된 후 이 콜백 함수를 호출합니다. 이 콜백 함수를 호출한 후 PHP는 내부적으로 닫기 콜백 함수를 호출합니다.

참고:PHP는 출력 스트림이 작성되고 닫힐 때까지 쓰기 콜백 함수를 호출하지 않으므로 쓰기 콜백 함수의 디버깅 정보는 브라우저 중간. 쓰기 콜백 함수에서 디버그 출력을 사용해야 하는 경우 디버그 출력을 파일에 쓰는 것이 좋습니다.

第五个参数:  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에서 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.