PHP-Datenbanksitzungssitzung speichern

不言
Freigeben: 2023-03-23 06:36:01
Original
2906 Leute haben es durchsucht

Dieser Artikel stellt das Speichern von Sitzungen in einer PHP-Datenbank vor und kann auch als Referenz für Freunde in Not dienen.


Vorwort:


Standardmäßig speichert PHP alle Sitzungsdaten in Textdateien auf dem Server. Diese Dateien werden normalerweise im temporären Verzeichnis gespeichert.

Warum müssen wir dann die Sitzung in der Datenbank speichern?

  1. Der Hauptgrund: die Sicherheit des Systems zu verbessern. Auf einem gemeinsam genutzten Server verwenden alle Websites ohne besondere Einstellungen dasselbe temporäre Verzeichnis, was bedeutet, dass Dutzende Programme Dateien am selben Ort lesen und schreiben. Es wurde nicht nur die Geschwindigkeit verringert, sondern es war auch möglich, dass jemand anderes die Benutzerdaten meiner Website stehlen konnte.

  2. Das Speichern von Sitzungsdaten in der Datenbank kann auch die Suche nach weiteren Informationen zu Website-Sitzungen erleichtern. Wir können die Anzahl der aktiven Sitzungen (die Anzahl der Benutzer, die gleichzeitig online sind) abfragen Zeit) und auch Sitzungsdaten werden gesichert.

  3. Wenn meine Website gleichzeitig auf mehreren Servern läuft, kann ein Benutzer während einer Sitzung mehrere Anfragen an verschiedene Server senden, wenn die Sitzungsdaten jedoch auf einem bestimmten Server gespeichert werden Andere Server können diese Sitzungsdaten nicht nutzen. Wenn einer meiner Server nur die Rolle einer Datenbank übernimmt, wäre es für Sie dann nicht sehr praktisch, alle Sitzungsdaten in der Datenbank zu speichern?

Weitere Informationen zu PHP-Sitzungen finden Sie in diesem Blog. Erfahren Sie mehr über den SESSION-Mechanismus von PHP

1. Erstellen Sie eine Sitzungstabelle

Da die Sitzungsdaten auf dem Server und ein Index (Sitzungs-ID) auf dem Client gespeichert werden, entspricht dieser Index einem bestimmten Teil der Sitzungsdaten auf dem Server. Daher müssen die beiden Felder „id“ und „data“ in der Tabelle enthalten sein, und die Sitzung hat eine Ablaufzeit. Daher gibt es hier ein weiteres Feld mit dem Namen „last_accessed“. Hier habe ich die Tabelle unter der Testdatenbank erstellt:

CREATE TABLE sessions(
    id CHAR(32) NOT NULL,
    data TEXT,
    last_accessed TIMESTAMP NOT NULL,    PRIMARY KEY(id)
);
Nach dem Login kopieren

PHP-Datenbanksitzungssitzung speichern

PS: Wenn das Programm eine große Datenmenge in der Sitzung speichern muss, muss das Datenfeld möglicherweise als MEDIUMTEXT- oder LONGTEXT-Typ definiert werden.

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结束标签
Nach dem Login kopieren

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)."
Nach dem Login kopieren
Nach dem Login kopieren

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

session destroyed

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

session data :

".print_r($_SESSION,1)."
Nach dem Login kopieren

";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原理以及使用详解



Das obige ist der detaillierte Inhalt vonPHP-Datenbanksitzungssitzung speichern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!