php知识点未掌握的知识PHP

PHP存储Session

2017-03-24  本文已影响446人  零一间

一 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 ] )

<?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);
?>


上一篇 下一篇

猜你喜欢

热点阅读