PHP SESSION 的工作原理

在客户端(如浏览器)登录网站时,被访问的 PHP 页面可以使用 session_start() 打开 SESSION,这样就会产生客户端的唯一标识 SESSION ID(此 ID 可通过函数 session_id() 获取/设置)。

SESSION ID 可以通过两种方式保留在客户端,使得请求不同的页面时,PHP 程序可以获知客户端的 SESSION ID;一种是将 SESSION ID 自动加入到 GET 的 URL 中(这个只能在unix系统下能实现,windows系统不能实现自动加入url中),或者 POST 的表单中,默认情况下,变量名为 PHPSESSID;另一种是通过 COOKIE,将 SESSION ID 保存在 COOKIE 中,默认情况下,这个 COOKIE 的名字为 PHPSESSID。不管哪一种方式,这个标识符是唯一的,php就凭着这个标识符来读写SESSION数据。

SESSION 的数据保存在服务器端,但不是保存在内存中,而是保存在文件或数据库中。默认情况下,php.ini 中设置的 SESSION 保存方式是files(session.save_handler = files)。这是可以更改的,是用数据库,redis,memcache都可以。

更改存储方式

  • 修改php.ini的设置(修改后重启)
session.save_handler = redis
  • ini_set
ini_set(“session.save_handler”,”redis”);
  • session_module_name
  session_module_name("files");  // ASCII files
session_module_name("mm"); // Shared memory
session_module_name("user"); // Custom session backend
实现数据库存储
  • 更改方式
session_module_name("user");
  • 建立数据库表

id就是唯一标识符,data就是数据,还可以自定义其他的内容例如过期日期等

CREATE TABLE 'session'(
'id' CHAR(30) NOT NULL,'data' CHAR(3000),
PARMIRY BY ('id')
);
  • 读写代码

实际读写代码,并用session_set_save_handler注册

session_set_save_handler (
callable $open ,
callable $close ,
callable $read ,
callable $write ,
callable $destroy ,
callable $gc
[, callable $create_sid ] );

如果用对象的方式,还需要注意处理

在脚本执行完毕之后,PHP 内部会清除对象, 所以有可能不调用 write 和 close 回调函数。 这样可能会引发非预期的行为,所以当使用对象作为会话保存管理器时, 需要通过注册 shutdown 回调函数来规避风险。 通常,你可以通过调用 register_shutdown_function() 函数 来注册 'session_write_close' 回调函数。

在 PHP 5.4.0 中,可以调用 session_register_shutdown() 函数来注册 shutdown 回调函数。 如果你使用session_set_save_handler() 的 OOP 原型, 那么仅需设置 “register shutdown” 为 TRUE 即可。

简单例子

<?php

$con =mysql_connection("127.0.0.1","user" , "pass");
mysql_select_db("session"); function open($save_path, $session_name)
{
return(true);
} function close()
{
return(true);
} function read($id)
{
if($result = mysql_query("SELECT * FROM session WHERE id='$id'"))
{
if($row = mysql_felth_row($result ))
{ return $row["data"]; }
}
else
{
return "";
}
} function write($id, $sess_data)
{
if($result = mysql_query("UPDATE session SET data='$sess_data' WHERE id='$id'"))
{
return true;
}
else
{
return false;
}
} function destroy($id)
{
if($result = mysql_query("DELETE * FROM session WHERE id='$id'"))
{
return true;
}
else
{
return false;
}
} /*********************************************
* WARNING - You will need to implement some *
* sort of garbage collection routine here. *
*********************************************/
function gc($maxlifetime)
{
return true;
} session_set_save_handler("open", "close", "read", "write", "destroy", "gc"); session_start();

 对象的方式

<?php
class FileSessionHandler
{
private $savePath; function open($savePath, $sessionName)
{
$this->savePath = $savePath;
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
} return true;
} function close()
{
return true;
} function read($id)
{
return (string)@file_get_contents("$this->savePath/sess_$id");
} function write($id, $data)
{
return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
} function destroy($id)
{
$file = "$this->savePath/sess_$id";
if (file_exists($file)) {
unlink($file);
} return true;
} function gc($maxlifetime)
{
foreach (glob("$this->savePath/sess_*") as $file) {
if (filemtime($file) + $maxlifetime < time() && file_exists($file)) {
unlink($file);
}
} return true;
}
} $handler = new FileSessionHandler();
session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
); // 下面这行代码可以防止使用对象作为会话保存管理器时可能引发的非预期行为
register_shutdown_function('session_write_close'); session_start();

新接口( PHP 5.4 开始)

<?php
class MySessionHandler implements SessionHandlerInterface
{
private $savePath; public function open($savePath, $sessionName)
{
$this->savePath = $savePath;
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
} return true;
} public function close()
{
return true;
} public function read($id)
{
return (string)@file_get_contents("$this->savePath/sess_$id");
} public function write($id, $data)
{
return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
} public function destroy($id)
{
$file = "$this->savePath/sess_$id";
if (file_exists($file)) {
unlink($file);
} return true;
} public function gc($maxlifetime)
{
foreach (glob("$this->savePath/sess_*") as $file) {
if (filemtime($file) + $maxlifetime < time() && file_exists($file)) {
unlink($file);
}
} return true;
}
} $handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();

PHP SESSION 保存到数据库的更多相关文章

  1. php将session保存到数据库的类实例(php版本需要大于5.4)

    这里实现了一个把session存储到数据库的类,包括数据表的创建.类的使用.php的配置. 可以更好地进行用户控制管理. 做项目的时候,有一个需求,是要实现禁止一个账号两处登录.同时要统计当前在线用户 ...

  2. ASP.NET将Session保存到数据库中

    因为ASP.NET中Session的存取机制与ASP相同,都是保存在进行中, 一旦进程崩溃,所有Session信息将会丢失,所以我采取了将Session信息保存到SQL Server中,尽管还有其它的 ...

  3. 小技巧-ASP.Net session保存在数据库服务器

    引用博客:http://www.cnblogs.com/lykbk/archive/2013/01/13/hf576856868.html web Form 网页是基于HTTP的,它们没有状态, 这意 ...

  4. Asp.Net将Session保存在数据库中

    1.由于项目dll文件变动比较频繁,而保存登陆的状态又保存在Session中,所以导致用户经常无故掉线.(dll变动的时候导致Session丢失) 2.有一种方法可以长期保存session,那就是se ...

  5. Java Hour 47 WeatherInfo 保存到数据库

    经历了上周简单的休整以后,我们继续Hibernate 之旅. 保存到数据库 private void saveWeatherInfo(Weatherinfo weatherInfo) { // Sav ...

  6. php将会话保存在数据库里

    php默认把会话保存在临时文件中,保存在数据库中可以提高安全性,在共享主机服务器上,所有web站点都使用同一个临时目录,这意味着数十个程序都在同一位置进行文件读取的操作,我们很容易就编写一个脚本从这个 ...

  7. 进程外Session保存和全局文件错误捕获

    Session深入学习,进程外的Session 当用户登入页面跳转时候,我们会将用户登录信息保存在服务端一个键值对的Session(Session池)中.那么Session池又是在哪里呢? 它最终默认 ...

  8. Java中将图片保存到数据库中

    在实际的开发中,我们可能需要将图片.影音等文件直接保存到数据库中,然后通过编程方式将数据读出进行使用.例如将读出的图片数据显示出来,将读出的电影文件播放出来. 二进制数据直接保存到文件和从文件中读出非 ...

  9. XAF:如何让用户在运行时个性化界面并将个性化信息保存到数据库中 win/web/entityframework/xpo

    本主题介绍如何启用管理模型差异(XAFML),并将设置存储在数据库中.   名词解释: 1.模型:XAF中把所有应用程序的结构都用模型来定义,比如列表,有哪些列,名称是什么,对应的字段名是什么,业务对 ...

随机推荐

  1. Redhat 6环境下安装Oracle 12c的方法

    Step 1: 要在Linux上安装Oracle,需要在安装Oracle之前安装好相应的软件包,在不同操作系统环境下,对软件包的要求各不相同.具体对应的软件包,见官网文档:https://docs.o ...

  2. 263. Ugly Number

    Write a program to check whether a given number is an ugly number. Ugly numbers are positive numbers ...

  3. next permutaion算法

    算法描述: Find largest index i such that array[i − 1] < array[i]. Find largest index j such that j ≥ ...

  4. Python 文件I/O

    文件I/O是Python中最重要的技术之一,在Python中对文件进行I/O操作是非常简单的. 1.打开文件 语法: open(name[, mode[, buffering]]) 1.1文件模式 1 ...

  5. oracle 几个时间函数探究

    近来经常用到时间函数,在此写一个笔记,记录自己的所得,希望也对您有所帮助. 1.对于一个时间如 sysdate:2015/1/30 14:16:03如何只得到年月日,同时它的数据类型不变化呢? 最容易 ...

  6. 部分手机不能连PC adb

    http://www.th7.cn/Program/java/201407/232139.shtml 1. 命令行中执行 android update adb [这一步的目的是产生下面第二步的路径和文 ...

  7. Ubuntu14.04 Objective-C hello world

    1. Install GNUstep sudo apt-get install gnustep gnustep-devel 2. Write hello world program, and save ...

  8. Asp.Net MVC如何返回401响应码

    需求:     在默认创建的Asp.Net MVC项目中(这里使用VS2013),需要手动返回一个401响应码给浏览器.我们的代码可能是下面这样子的.   public ActionResult Un ...

  9. ubuntu 下root用户无法访问声音设备的解决方案

    原因:root用户没有对pulsaudio的访问权限,而且pulsaudio默认是不能在root下自动启动解决办法: 一.修改自动启动:编辑 gedit /etc/default/pulseaudio ...

  10. EXCEL 跨表比较数据

    Public Sub Compare(fullname As String, sheet As String) Dim conn, sql, rows, i, cellContents ,rowInd ...