この記事では、PHP データベースへのセッションの保存について紹介します。また、困っている友達の参考にもなります。
。デフォルトでは、PHP はすべてのセッション データをサーバー上のテキスト ファイルに保存します。これらのファイルは通常、サーバー上の一時ディレクトリに保存されます。
それでは、なぜセッションをデータベースに保存する必要があるのでしょうか?
主な理由は、システムのセキュリティを向上させるためです。共有サーバーでは、特別な設定を行わない限り、すべての Web サイトが同じ一時ディレクトリを使用します。これは、多数のプログラムが同じ場所でファイルの読み取りと書き込みを行うことを意味します。速度が低下しただけでなく、他の誰かが私のサイトのユーザーデータを盗む可能性もありました。
セッション データをデータベースに保存すると、Web サイトのセッションに関する詳細情報を簡単に検索でき、アクティブなセッションの数 (同時にオンラインになっているユーザーの数) をクエリしたり、セッション データをバックアップしたりすることができます。 。
私のサイトが複数のサーバーで同時に実行されている場合、ユーザーはセッション中に複数のリクエストを異なるサーバーに送信できますが、セッションデータが特定のサーバーに保存されている場合、他のサーバーはこのセッションデータを送信できません使用済み。サーバーの 1 つがデータベースの役割だけを果たしている場合、すべてのセッション データをデータベースに保存できれば非常に便利だと思いませんか?
PHPセッションについて詳しくは、このブログを参照してください。PHPのSESSIONメカニズムを徹底的に理解します
セッションデータはサーバーに保存されるため、クライアントに保存されるものはサーバー上の特定のセッション データに対応するインデックス (セッション ID) です。したがって、テーブルに含める必要がある 2 つのフィールドは id と data であり、セッションには有効期限があるため、ここに last_accessed という別のフィールドがあります。ここでは、テスト データベースの下にテーブルを構築します。注: プログラムがセッション内に大量のデータを保存する必要がある場合、データ フィールドを 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:<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 '