PHP存储Session

一 Redis

方法一:  配置文件php.ini,修改为下面内容,保存并重启服务

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

方法二:  直接在代码中加入以下内容:

<?php
ini_set("session.save_handler", "redis");
ini_set("session.save_path", "tcp://127.0.0.1:6379");
?>

如果redis配置文件redis.conf里设置了连接密码requirepass,save_path需要这样写tcp://127.0.0.1:6379?auth=连接密码

二 Memcache

方式一:  php.ini 文件,修改下面两个参数:

session.save_handler = memcache
session.save_path = "tcp://Mem服务器1:端口号,tcp://Mem服务器2:端口号..."

方式二: 在 php 文件中使用 ini_set 函数

<?php
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://Mem服务器1:端口号,tcp://Mem服务器2:端口号...");
?>

如果安装的PECL是memcached(使用libmemcache库的那个),则配置应为:

ini_set("session.save_handler", "memcached"); // 不是memcache
ini_set("session.save_path", "127.0.0.1:11211"); // 不要tcp:

三 回调函数方式

bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc , callable $create_sid )

  • open
    自动开始会话或者通过调用 session_start() 手动开始会话之后第一个被调用的回调函数。 成功返回 TRUE,反之返回 FALSE
  • close
    回调函数类似于类的析构函数。脚本执行完成 或 调用 session_write_close() session_destroy() 时被执行,即在所有session操作完后被执行。
  • read
    会话读取数据,read 回调函数必须返回将会话 数据编码(序列化)后的字符串。 如果会话中没有数据,read 回调函数返回空字符串。 在调用 read 之前,PHP 会调用 open 回调函数。read 回调返回的序列化之后的字符串格式必须与 write 回调函数保存数据时的格式完全一致。 PHP 会自动反序列化返回的字符串并填充 $_SESSION 超级全局变量。 虽然数据看起来和 serialize() 函数很相似, 但是需要提醒的是,它们是不同的。 请参考: session.serialize_handler
  • write
    会话保存数据。 此回调函数接收当前会话 ID 以及 $_SESSION 中数据序列化之后的字符串作为参数。 序列化会话数据的过程由 PHP 根据 session.serialize_handler 设定值来完成。PHP 会在脚本执行完毕或调用 session_write_close() 函数之后调用此回调函数。 注意,在调用完此回调函数之后,PHP 内部会调用 close 回调函数。
    PHP 会在输出流写入完毕并且关闭之后 才调用 write 回调函数, 所以在 write 回调函数中的调试信息不会输出到浏览器中。 如果需要在 write 回调函数中使用调试输出, 建议将调试输出写入到文件。
  • destroy
    当调用 session_destroy()函数, 或者调用session_regenerate_id()函数并且设置 destroy 参数为 TRUE 时, 会调用此回调函数。
  • gc
    清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。 调用周期由 session.gc_probability session.gc_divisor参数控制。 传入到此回调函数的 lifetime 参数由 session.gc_maxlifetime 设置。
  • create_sid
    当需要新的会话 ID 时被调用的回调函数。
<?php 

class FileSessionHandler { 

    private $savePath;
    //启动session
    function open($savePath, $sessionName) {
        $this->savePath = $savePath;
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath, 0777);
        }
        return true;
    } 

    //关闭session
    function close() {
        return true;
    } 

    //读取session
    function read($id) {
        return (string)@file_get_contents("$this->savePath/sess_$id");
    } 

    //写入session
    function write($id, $data) {
        return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
    } 

    //销毁session
    function destroy($id) {
        $file = "$this->savePath/sess_$id";
        if (file_exists($file)) {
            unlink($file);
        }
        return true;
    } 

    //销毁session
    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‘)
);
// 下面这行代码可以防止使用对象作为会话保存管理器时可能引发的非预期行为
// 脚本执行完毕之后,内部会清除对象,有可能不调用 write 和 close 回调函数。
register_shutdown_function(‘session_write_close‘);
session_start();
// 现在可以使用 $_SESSION 保存以及获取数据了

四 会话类处理类

使用sessionhandler添加加密PHP内部保存处理程序。

<?php 

/** decrypt AES 256
 * @param data $edata
 * @param string $password
 * @return decrypted data
 */ 

function decrypt($edata, $password) {
    $data = base64_decode($edata);
    $salt = substr($data, 0, 16);
    $ct = substr($data, 16);
    $rounds = 3;
    // depends on key length
    $data00 = $password.$salt;
    $hash = array();
    $hash[0] = hash(‘sha256‘, $data00, true);
    $result = $hash[0];
    for ($i = 1; $i < $rounds; $i++) {
        $hash[$i] = hash(‘sha256‘, $hash[$i - 1].$data00, true);
        $result .= $hash[$i];
    }
    $key = substr($result, 0, 32);
    $iv = substr($result, 32,16);
    return openssl_decrypt($ct, ‘AES-256-CBC‘, $key, true, $iv);
} 

/**
 * crypt AES 256
 * @param data $data
 * @param string $password
 * @return base64 encrypted data
 */
function encrypt($data, $password) {
    // Set a random salt
    $salt = openssl_random_pseudo_bytes(16);
    $salted = ‘‘; $dx = ‘‘;
    // Salt the key(32) and iv(16) = 48
    while (strlen($salted) < 48) {
        $dx = hash(‘sha256‘, $dx.$password.$salt, true);
        $salted .= $dx;
    }
    $key = substr($salted, 0, 32);
    $iv = substr($salted, 32,16);
    $encrypted_data = openssl_encrypt($data, ‘AES-256-CBC‘, $key, true, $iv);
    return base64_encode($salt . $encrypted_data);
} 

class EncryptedSessionHandler extends SessionHandler {
    private $key; 

    public function __construct($key) {
        $this->key = $key;
    } 

    public function read($id) {
        $data = parent::read($id);
        if (!$data) {
            return "";
        } else {
            return decrypt($data, $this->key);
        }
    } 

    public function write($id, $data) {
        $data = encrypt($data, $this->key);
        return parent::write($id, $data);
    }
} 

ini_set(‘session.save_handler‘, ‘files‘);
$key = ‘secret_string‘;
$handler = new EncryptedSessionHandler($key);
session_set_save_handler($handler, true);
session_start();

五 会话管理器接口

PHP > 5.4

//Database
CREATE TABLE `Session` (
    `Session_Id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
    `Session_Expires` datetime NOT NULL,
    `Session_Data` text COLLATE utf8_unicode_ci,
    PRIMARY KEY (`Session_Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SELECT * FROM mydatabase.Session;
<?php 

class SysSession implements SessionHandlerInterface {
    private $link;
    //开启session
    public function open($savePath, $sessionName) {
        $link = mysqli_connect("server","user","pwd","mydatabase");
        if($link){
            $this->link = $link;
            return true;
        }else{
            return false;
        }
    } 

    //关闭session
    public function close() {
        mysqli_close($this->link);
        return true;
    } 

    //读取session
    public function read($id) {
        $sql = "SELECT Session_Data FROM Session WHERE Session_Id = ‘".$id."‘ AND Session_Expires > ‘".date(‘Y-m-d H:i:s‘)."‘";
        $result = mysqli_query($this->link,$sql);
        if($row = mysqli_fetch_assoc($result)){
            return $row[‘Session_Data‘];
        }else{
            return "";
        }
    } 

    //写入session
    public function write($id, $data) {
        $DateTime = date(‘Y-m-d H:i:s‘);
        $NewDateTime = date(‘Y-m-d H:i:s‘,strtotime($DateTime.‘ + 1 hour‘));
        $sql = "REPLACE INTO Session SET Session_Id = ‘".$id."‘, Session_Expires = ‘".$NewDateTime."‘, Session_Data = ‘".$data."‘";
        $result = mysqli_query($this->link,$sql );
        if($result){
            return true;
        }else{
            return false;
        }
    } 

    //销毁session
    public function destroy($id) {
        $sql = "DELETE FROM Session WHERE Session_Id =‘".$id."‘";
        $result = mysqli_query($this->link,$sql);
        if($result){
            return true;
        }else{
            return false;
        }
    } 

    //回收session
    public function gc($maxlifetime) {
        $sql = "DELETE FROM Session WHERE ((UNIX_TIMESTAMP(Session_Expires) + ".$maxlifetime.") < ".$maxlifetime.")";
        $result = mysqli_query($this->link,$sql);
        if($result){
            return true;
        }else{
            return false;
        }
    } 

} 

$handler = new SysSession();
// 下面这行代码可以防止使用对象作为会话保存管理器时可能引发的非预期行为
session_set_save_handler($handler, true);
时间: 2024-08-09 22:01:30

PHP存储Session的相关文章

(转)Tomcat7+Redis存储Session

原创http://blog.csdn.net/caiwenfeng_for_23/article/details/45666831 PS:截止到2015-05-12前是不支持Tomcat8的,详情见官网:https://github.com/jcoleman/tomcat-redis-session-manager 前提:你已经部署了Redis,尚未学会的,可以移步这里:http://blog.csdn.net/caiwenfeng_for_23/article/details/45511007

基于php使用memcache存储session的详解(转)

web服务器的php session都给memcached ,这样你不管分发器把 ip连接分给哪个web服务器都不会有问题了,配置方法很简单,就在php的配置文件内增加一条语句就可以了,不过前提你需要装好memcache模块 1.设置session用memcache来存储方法I: 在 php.ini 中全局设置session.save_handler = memcachesession.save_path = "tcp://127.0.0.1:11211"方法II: 某个目录下的 .h

nginx 负载均衡、用数据库存储Session,来实现多站点共享Session[转]

多站点共享Session常见的作法有: 1.使用.net自动的状态服务(Asp.net State Service); 2.使用.net的Session数据库: 3.使用Memcached. 4.使用Cookie方式实现多个站点间的共享(这种方式只限于几个站点都在同一域名的情况下): 这里我们就 演练一下 以数据库的形来存储Session,来实现多站点共享Session. 首先我们 建好一下站点,如下图: Default.aspx 其中 有二个Button  ,SetSession 主要是用于给

Express中使用mongodb存储session

express默认有队session的支持,但是是存储在内存中的. 我们可以使用mongodb来存储会话. 但是express的各个版本中对该功能的写法是不同的. Express 2.x: app.use(express.session({ secret: settings.cookieSecret, store: new MongoStore({ db: settings.db })})); Express 3.x: var express = require('express');var m

Redis存储Session

net Core 使用Redis存储Session 前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(middleware). 对于Session来说褒贬不一,很多人直接说不要用,也有很多人在用,这个也没有绝对的这义,个人认为只要不影什么且又可以方便实现的东西是可以用的,现在不对可不可用做表态,我们只关心实现. 类库引用 这个相对于之前的.net是方便了不少,需要在project.json中的depend

[转]php使用 memcache 来存储 session

转自:http://koda.iteye.com/blog/466667 Memcache和PHP memcach扩展安装请见http://koda.iteye.com/blog/665761 设置session用memcache来存储 方法I: 在 php.ini 中全局设置 Php.ini代码 session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211" 方法II: 某个目录下的 .htacc

php+redis实现多台服务器内网存储session并读取

大型网站由于大并发的问题会导致系统出现诡异的崩溃性问题这着实让人很是蛋疼,首先考虑的就是负载均衡服务器来处理这个,当然数据库的性能也是非常非常重要的,今天就说下在负载均衡情况下对于session这个问题如何处理,说实话不处理session其实也是可以的,但是在实际的情况中会出现一些让用户体验非常蛋疼的问题,比如购物下单的时候负载均衡调配服务器来回切换的过程中session丢失了,这个时候就尴尬了,用户就会郁闷我擦这什么鬼,于是乎各种担心就会出现,这破网站是不是有什么安全问题等等.下面就来说说这个

Asp.net Core 使用Redis存储Session

前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(middleware). 对于Session来说褒贬不一,很多人直接说不要用,也有很多人在用,这个也没有绝对的这义,个人认为只要不影什么且又可以方便实现的东西是可以用的,现在不对可不可用做表态,我们只关心实现. 类库引用 这个相对于之前的.net是方便了不少,需要在project.json中的dependencies节点中添加如下内容: "StackExc

PHP使用Memcache来存储session 其他【转载】

PHP使用Memcache来存储session 分类:PHP 时间:2015年3月30日 很多时候一个完整的系统可能运行在多个服务器上,如果这多个服务器之间需要共享session的话,那么PHP默认的files保存session的方式就无能为力了.这时我们可以考虑使用Memcache来接管session的保存与读取工作. 方法I: 在 php.ini 中全局设置php.ini代码 12 session.save_handler = memcachesession.save_path = "tcp

为什么不能用memcached存储Session?

Memcached创建者Dormando非常早就写过两篇文章[1][2].告诫开发者不要用memcached存储Session. 他在第一篇文章中给出的理由大致是说,假设用memcached存储Session,那么当memcached集群发生问题(比方内存溢出)或者维护(比方升级.添加或降低server)时,用户会无法登录.或者被踢掉线.而在第二篇文章中.他则指出.memcached的回收机制可能会导致用户无缘无故地掉线. Titas Norkūnas是DevOps咨询服务提供商Bear Mou