首頁 > 後端開發 > php教程 > PHP資料庫保存session會話

PHP資料庫保存session會話

不言
發布: 2023-03-23 06:36:01
原創
2944 人瀏覽過

本篇文章介紹的是關於PHP資料庫保存session會話,現在分享給大家,也可以給有需要的朋友一個參考,大家一起來看一看吧


前言:


在預設的情況下,PHP會把全部的會話資料保存在伺服器上的文字檔案裡面,這些檔案通常都是保存在伺服器上的暫存目錄裡邊。

那為什麼我們要把session會話保存在資料庫中呢?

  1. #主要原因:提高系統的安全性。在共享伺服器上,在沒有進行特別的設置,所有的網站網站都會使用同一個臨時目錄,這意味著數十個程式都在同一個位置對檔案進行讀寫操作。不僅速度下降了,而且別人也有可能竊取到我的網站的使用者資料。

  2. 把會話數據保存到資料庫還可以更方便的搜尋web站點會話的更多信息,我們可以查詢活動會話的數量(同時在線的用戶量),還可以對會話資料進行備份。

  3. 假如我的網站同時運行於多個伺服器,那麼某個使用者在一個會話過程中,可能會對不同的伺服器發送多個請求,但是會話資料如果保存在某一個伺服器上,那麼其他伺服器就不能使用到這些會話資料。假如我的某台伺服器只是資料庫的角色,那你把會話資料全保存在資料庫中,不是很方便麼?

更多的關於PHP session的理解可以參考該部落格 徹底理解PHP的SESSION機制 

1、建立會話表

#由於session 資料是保存在伺服器上面的,而在客戶端中保存的是一個索引(sessionID),這個索引對應於伺服器上的某一條session 資料。因此表格必須包含的兩個欄位是id、data,還有就是會話會有過期時間,所以這裡還有個欄位就是last_accessed,這裡我把該表建在test資料庫下:

CREATE TABLE sessions(
    id CHAR(32) NOT NULL,
    data TEXT,
    last_accessed TIMESTAMP NOT NULL,    PRIMARY KEY(id)
);
登入後複製

PHP資料庫保存session會話

PS:如果程式需要在會話中保存大量的數據,則data 欄位可能就需要定義為MEDIUMTEXT 或LONGTEXT 類型了。

2、定义会话函数:

这里我们主要有两个步骤:

  1. 定义与数据库交互的函数

  2. 使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(&#39;localhost&#39;, &#39;root&#39;, &#39;lsgogroup&#39;, &#39;test&#39;);     //数据库 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=&#39;%s&#39;", 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 &#39;&#39;;
    }
}//写入会话数据function write_session($sid, $data){
    global $sdbc;    $sql = sprintf("INSERT INTO sessions(id,data,last_accessed) VALUES(&#39;%s&#39;,&#39;%s&#39;,&#39;%s&#39;)", 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=&#39;%s&#39;", 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(&#39;open_session&#39;, &#39;close_session&#39;, &#39;read_session&#39;, &#39;write_session&#39;, &#39;destroy_session&#39;, &#39;clean_session&#39;);//启动会话,该函数必须在session_set_save_handler()函数后调用,不然我们所定义的函数就没法起作用了。session_start();//由于该文件被包含在需要使用会话的php文件里面,因此不会为其添加PHP结束标签
登入後複製

PS:

  1. 处理“读取”函数外,其他函数必须返回一个布尔值,“读取”函数必须返回一个字符串。

  2. .每次会话启动时,“打开”和“读取”函数将会立即被调用。当“读取”函数被调用的时候,可能会发生垃圾回收过程。

  3. 当脚本结束时,“写入”函数就会被调用,然后就是“关闭”函数,除非会话被销毁了,而这种情况下,“写入”函数不会被调用。但是,在“关闭”函数之后,“销毁”函数将会被调用。

  4. .session_set_save_handler()函数参数顺序不能更改,因为它们一一对应 open 、close、read、、、、

  5. 会话数据最后将会以数据序列化的方式保存在数据库中。

3、使用新会话处理程序

使用新会话处理程序只是调用session_set_save_handler()函数,使我们的自定义函数能够被自动调用而已。其他关于会话的操作都没有发生变化(以前怎么用现在怎么用,我们的函数会在后台自动被调用),包括在会话中存储数据,访问保存的会话数据以及销毁数据。

在这里,我们新建 sessions.php 文件,该脚本将在没有会话信息时创建一些会话数据,并显示所有的会话数据,在用户点击 ‘log out’(注销)时销毁会话数据。

代码:

<?php//引入sessions.inc.php文件,即上面的代码require(&#39;sessions.inc.php&#39;);?><!doctype html><html lang=&#39;en&#39;><head>
    <meta charset="utf-8">
    <title>DB session test</title></head><body><?php//创建会话数据if(empty($_SESSION)){    $_SESSION[&#39;blah&#39;] = "umlaut";    $_SESSION[&#39;this&#39;] = 12345;    $_SESSION[&#39;that&#39;] = &#39;blue&#39;;    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)."
登入後複製
登入後複製

"; }if(isset($_GET['logout'])){ //销毁会话数据 session_destroy(); echo "

session destroyed

"; }else{ echo "log out"; }echo "

session data :

".print_r($_SESSION,1)."
登入後複製

";echo ''; session_write_close(); //下面重点解析?>

解析 session_write_close():

顾名思义,该函数就是先写入会话数据,然后关闭session会话,按道理这两步在脚本执行完后会自动执行,为什么我们还要显式调用它呢?因为这里涉及到了数据库的连接!

由于我们知道,PHP会在脚本执行完后自动关闭数据库的所有连接,而同时会话函数会尝试向数据库写入数据并关闭连接。这样一来就会导致会话数据没法写入数据库,并且出现一大堆错误,例如write_session()、close_session()函数中都有用到数据库的连接。

为了避免以上说的问题,我们在脚本执行完之前调用 session_write_close()函数,他就会调用“写入”函数和“关闭”函数,而此时数据库连接还是存在的!

PS:在使用header()函数重定向浏览器之前也应该调用session_write_close()函数,假如有数据库的操作时!

4、测试使用

在浏览器中打开 sessions.php,刷新页面,然后再看看数据库有没有添加数据。在另一个浏览器打开 sessions.php ,看看数据库中有没有添加另一条数据。。。。。

本博客主要是参考自《深入理解PHP高级技巧、面向对象与核心技术》,希望能帮到大家。

相关推荐:

PHP开发Session原理以及使用详解



以上是PHP資料庫保存session會話的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板