zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    转:C#操作摄像头
    C# Memcached缓存
    WCF:调用方未由服务器进行身份验证
    SQL Server 存储过程进行分页查询
    SQL Server T-SQL高级查询
    C#设计模式总结(转)
    C#中构造函数和析构函数区别
    C#: static关键字的作用(转)
    C#结构体和类的区别(转)
    .NET多线程编程(转)
  • 原文地址:https://www.cnblogs.com/lpblogs/p/7462507.html
Copyright © 2011-2022 走看看