CacheSession.php 4.46 KB
<?php
/**
 * Created by PhpStorm.
 * User: Zip
 * Date: 14/12/25
 * Time: 下午4:47
 */

namespace Hood\Core\Session;

use Hood\Core\Support\Str;
use Hood\Core\Root;
use Hood\Cache\Memcached as mcCache;

class CacheSession extends Root implements SessionHandlerInterface
{
    /**
     * session 前缀
     * @var string
     */
    private $sessionPrefix = 'session:';

    /**
     * Session数据就自动删除时间 (默认24小时)
     * @var int 
     */
    private $gcMaxLifeTime = 86400; //1800;

    private $sessionOptions = array(
        'use_cookies',
        'auto_start',
        'serialize_handler',
        'cookie_lifetime',
        'cookie_path',
        'cookie_domain',
        'use_cookies',
        'cache_expire',
        'gc_maxlifetime'
    );

    private $mcCache;

    private $cacheNode = 'memcached';

    private $childNode = 'session';

    /**
     * 初始化
     */
    public function __construct($sessionName = null, $domain = null)
    {
        session_set_save_handler(
            array(&$this, "open"),
            array(&$this, "close"),
            array(&$this, "read"),
            array(&$this, "write"),
            array(&$this, "destroy"),
            array(&$this, "gc")
        );
        if (version_compare(phpversion(), '5.4.0', '>=')) {
            register_shutdown_function('session_write_close');
        }
        if ($sessionName != null && is_string($sessionName) && strlen($sessionName) > 1) {
            ini_set("session.name", $sessionName);
        }
        ini_set("session.use_cookies", 1);
        ini_set('use_only_cookies', 0);
        if ($domain == null) {
            ini_set("session.cookie_domain", $this->currentDomain());
        } else {
            ini_set("session.cookie_domain", '.' . $domain);
        }
        ini_set('session.cookie_path', '/');
        ini_set('session.gc_maxlifetime', $this->gcMaxLifeTime);
    }

    public function currentDomain()
    {
        if (!isset($_SERVER['HTTP_HOST'])) {
            return '';
        }
        if (ip2long($_SERVER['HTTP_HOST']) == false) {
            return '.' . preg_replace("/^(.*\.)?([^.]*\..*)$/", "$2", $_SERVER['HTTP_HOST']);
        }
        return $_SERVER['HTTP_HOST'];
    }

    /**
     * 设置session缓存节点
     * @param string $node
     * @param string $childNode
     * @return $this
     */
    public function setCacheNode($node = 'memcached', $childNode = 'session')
    {
        $this->cacheNode = $node;
        $this->childNode = $childNode;
        return $this;
    }

    /**
     * @return mcCache
     */
    private function cache()
    {
        if (empty($this->mcCache)) {
            $this->mcCache = new mcCache();
            $this->mcCache->setSection($this->cacheNode)->setNode($this->childNode)->setPrefix('qinsession');
        }
        return $this->mcCache;
    }

    /**
     * 设置session参数
     * @param array $options
     * @return $this
     */
    public function setSessionOptions(array $options)
    {
        foreach ($options as $key => $val) {
            if (isset($this->sessionOptions[$key])) {
                ini_set('session.' . $key, $val);
            }
        }
        return $this;
    }

    /**
     * 打开Session
     * @param string $savePath
     * @param string $sessionID
     * @return bool
     */
    public function open($savePath, $sessionID)
    {
        return true;
    }

    /**
     * 关闭Session
     * @return bool
     */
    public function close()
    {
        return true;
    }

    /**
     * 读取缓存
     * @param string $sessionID
     * @return mixed|string
     */
    public function read($sessionID)
    {
        return $this->cache()->get($this->sessionPrefix . $sessionID);
    }

    /**
     * 写入Session
     * @param string $sessionID
     * @param string $sessionData
     * @return bool
     */
    public function write($sessionID, $sessionData)
    {
        $return = $this->cache()->set($this->sessionPrefix . $sessionID, $sessionData, $this->gcMaxLifeTime);
        return $return;
    }

    /**
     * 注销Session
     * @param int $sessionID
     * @return bool
     */
    public function destroy($sessionID)
    {
        return $this->cache()->delete($this->sessionPrefix . $sessionID);
    }

    public function gc($maxlifetime)
    {
        return true;
    }

    public function __destruct()
    {
        session_write_close();
    }

    public function generateSessionId()
    {
        return sha1(uniqid('', true) . Str::random(25) . microtime(true));
    }
}