이 글은 PHP 데이터베이스에 세션 세션을 저장하는 방법을 소개합니다. 이제 모든 사람과 공유하고, 도움이 필요한 친구들에게도 참고할 수 있습니다.
기본적으로 이 경우 PHP는 모든 세션 데이터를 서버의 텍스트 파일에 저장합니다. 이 파일은 일반적으로 서버의 임시 디렉터리에 저장됩니다.
그렇다면 왜 세션을 데이터베이스에 저장해야 할까요?
주된 이유는 시스템 보안을 향상시키기 위해서입니다. 공유 서버에서는 특별한 설정 없이 모든 웹사이트가 동일한 임시 디렉터리를 사용하게 됩니다. 이는 수십 개의 프로그램이 동일한 위치에서 파일을 읽고 쓰고 있음을 의미합니다. 속도가 느려졌을 뿐만 아니라 다른 사람이 내 사이트의 사용자 데이터를 도용하는 경우도 있었습니다.
세션 데이터를 데이터베이스에 저장하면 웹 사이트 세션에 대한 추가 정보를 더 쉽게 검색할 수 있으며, 활성 세션 수(동시에 온라인에 있는 사용자 수)를 쿼리하고 세션 데이터를 백업할 수 있습니다. .
내 사이트가 여러 서버에서 동시에 실행되는 경우 사용자는 세션 중에 여러 서버에 여러 요청을 보낼 수 있지만 세션 데이터가 특정 서버에 저장되어 있으면 다른 서버에서 이 세션 데이터를 확인할 수 없습니다. 사용된. 내 서버 중 하나가 데이터베이스 역할만 한다면 모든 세션 데이터를 데이터베이스에 저장하는 것이 매우 편리하지 않을까요?
PHP 세션에 대한 더 자세한 이해는 이 블로그를 참조하세요. PHP의 SESSION 메커니즘을 완전히 이해하세요.
세션 데이터가 서버에 저장되므로 클라이언트에 저장되는 내용은 무엇입니까? 서버의 특정 세션 데이터에 해당하는 인덱스(sessionID)입니다. 따라서 테이블에 포함되어야 하는 두 필드는 id와 data이고 세션에는 만료 시간이 있으므로 여기에 last_accessed인 또 다른 필드가 있습니다. 여기서는 테스트 데이터베이스 아래에 테이블을 만들었습니다.
CREATE TABLE sessions( id CHAR(32) NOT NULL, data TEXT, last_accessed TIMESTAMP NOT NULL, PRIMARY KEY(id) );
PS : 프로그램이 세션에서 많은 양의 데이터를 저장해야 하는 경우 데이터 필드를 MEDIUMTEXT 또는 LONGTEXT 유형으로 정의해야 할 수 있습니다.
这里我们主要有两个步骤:
定义与数据库交互的函数
使PHP能使用这些自定义函数
在第二步中,是通过调用函数 session_set_save_handler()来完成的,调用它需要6个参数,分别是 open(启动会话)、close(关闭会话)、read(读取会话)、write(写入会话)、destroy(销毁会话)、clean(垃圾回收)。
我们新建php文件 sessions.inc.php ,代码如下:
<?php$sdbc = null; //数据库连接句柄,在后面的函数里面让它成为全局变量//启动会话function open_session(){ global $sdbc; //使用全局的$sdbc $sdbc = mysqli_connect('localhost', 'root', 'lsgogroup', 'test'); //数据库 test if (!$sdbc) { return false; } return true; }//关闭会话function close_session(){ global $sdbc; return mysqli_close($sdbc); }//读取会话数据function read_session($sid){ global $sdbc; $sql = sprintf("SELECT data FROM sessions WHERE id='%s'", mysqli_real_escape_string($sdbc, $sid)); $res = mysqli_query($sdbc, $sql); if (mysqli_num_rows($res) == 1) { list($data) = mysqli_fetch_array($res, MYSQLI_NUM); return $data; } else { return ''; } }//写入会话数据function write_session($sid, $data){ global $sdbc; $sql = sprintf("INSERT INTO sessions(id,data,last_accessed) VALUES('%s','%s','%s')", mysqli_real_escape_string($sdbc, $sid), mysqli_real_escape_string($sdbc, $data), date("Y-m-d H:i:s", time())); $res = mysqli_query($sdbc, $sql); if (!$res) { return false; } return true; }//销毁会话数据function destroy_session($sid){ global $sdbc; $sql = sprintf("DELETE FROM sessions WHERE id='%s'", mysqli_real_escape_string($sdbc, $sid)); $res = mysqli_query($sdbc, $sql); $_SESSION = array(); if (!mysqli_affected_rows($sdbc) == 0) { return false; } return true; }//执行垃圾回收(删除旧的会话数据)function clean_session($expire){ global $sdbc; $sql = sprintf("DELETE FROM sessions WHERE DATE_ADD(last_accessed,INTERVAL %d SECOND)<NOW()", (int)$expire); $res = mysqli_query($sdbc, $sql); if (!$res) { return false; } return true; }//告诉PHP使用会话处理函数session_set_save_handler('open_session', 'close_session', 'read_session', 'write_session', 'destroy_session', 'clean_session');//启动会话,该函数必须在session_set_save_handler()函数后调用,不然我们所定义的函数就没法起作用了。session_start();//由于该文件被包含在需要使用会话的php文件里面,因此不会为其添加PHP结束标签
PS:
处理“读取”函数外,其他函数必须返回一个布尔值,“读取”函数必须返回一个字符串。
.每次会话启动时,“打开”和“读取”函数将会立即被调用。当“读取”函数被调用的时候,可能会发生垃圾回收过程。
当脚本结束时,“写入”函数就会被调用,然后就是“关闭”函数,除非会话被销毁了,而这种情况下,“写入”函数不会被调用。但是,在“关闭”函数之后,“销毁”函数将会被调用。
.session_set_save_handler()函数参数顺序不能更改,因为它们一一对应 open 、close、read、、、、
会话数据最后将会以数据序列化的方式保存在数据库中。
使用新会话处理程序只是调用session_set_save_handler()函数,使我们的自定义函数能够被自动调用而已。其他关于会话的操作都没有发生变化(以前怎么用现在怎么用,我们的函数会在后台自动被调用),包括在会话中存储数据,访问保存的会话数据以及销毁数据。
在这里,我们新建 sessions.php 文件,该脚本将在没有会话信息时创建一些会话数据,并显示所有的会话数据,在用户点击 ‘log out’(注销)时销毁会话数据。
代码:
<?php//引入sessions.inc.php文件,即上面的代码require('sessions.inc.php');?><!doctype html><html lang='en'><head> <meta charset="utf-8"> <title>DB session test</title></head><body><?php//创建会话数据if(empty($_SESSION)){ $_SESSION['blah'] = "umlaut"; $_SESSION['this'] = 12345; $_SESSION['that'] = 'blue'; echo "<p>Session data stored</p>"; }else{ echo "<p>Session data exists:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">".print_r($_SESSION,1)."
session destroyed
"; }else{ echo "log out"; }echo "session data :
".print_r($_SESSION,1)."