1
0
mirror of https://github.com/newnius/YAO-portal.git synced 2025-06-06 07:11:54 +00:00
YAO-portal/util4p/ReSession.class.php

209 lines
5.1 KiB
PHP
Executable File

<?php
require_once('util.php');
require_once('CRObject.class.php');
require_once('RedisDAO.class.php');
require_once('Random.class.php');
class Session
{
private static $time_out = 0; // 0-never expire
private static $bind_ip = false; // bind session with ip, when client ip changes, previous session will be unavailable
private static $sid = '';
private static $guid_key = '_session_id';
private static $cache = array();
/* configuration && initialization */
public static function configure(CRObject $config)
{
self::$time_out = $config->get('time_out', self::$time_out);
self::$bind_ip = $config->getBool('bind_ip', self::$bind_ip);
self::$guid_key = $config->get('guid_key', self::$guid_key);
/* assign id from new sessions */
if (!isset($_COOKIE[self::$guid_key])) {
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
do { // generate an unique session id
self::$sid = Random::randomString(64);
} while ($redis->exists('session:' . self::$sid) === 1);
$redis->disconnect();
setcookie(self::$guid_key, self::$sid);
} else {
self::$sid = $_COOKIE[self::$guid_key];
}
return true;
}
/* Ask browser to remember session id even if browser restarts */
public static function persist($duration)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$redis_key = 'session:' . self::$sid;
$redis->expire($redis_key, $duration);
$redis->disconnect();
setcookie(self::$guid_key, self::$sid, time() + $duration);
return true;
}
/* attach session to $group to avoid wild sessions */
public static function attach($group)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$redis_key = 'session:' . self::$sid;
$key = 'session-group:' . $group;
$redis->sadd($key, array($redis_key));
$redis->disconnect();
return true;
}
/* detach session from $group */
public static function detach($group)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$key = 'session-group:' . $group;
$redis_key = 'session:' . self::$sid;
$redis->srem($key, $redis_key);
$redis->disconnect();
return true;
}
/**/
public static function put($key, $value)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$redis_key = 'session:' . self::$sid;
$redis->hset($redis_key, $key, $value);
$redis->hset($redis_key, '_ip', cr_get_client_ip(false));
self::$cache[$key] = $value;//update cache
self::get('_ip');//renew expiration
$redis->disconnect();
return true;
}
/**/
public static function get($key, $default = null)
{
if (isset(self::$cache[$key])) {
return self::$cache[$key];
}
$redis = RedisDAO::instance();
if ($redis === null) {
return $default;
}
$redis_key = 'session:' . self::$sid;
$list = $redis->hgetall($redis_key);
if (self::$bind_ip) {
if (!(isset($list['_ip']) && $list['_ip'] === cr_get_client_ip(false))) {
return $default;
}
}
self::$cache = $list;
if ($redis->ttl($redis_key) < self::$time_out) {
$redis->expire($redis_key, self::$time_out);
}
$redis->disconnect();
if (isset($list[$key])) {
return $list[$key];
}
return $default;
}
/* expire current session */
public static function expire()
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$redis_key = 'session:' . self::$sid;
$redis->del(array($redis_key));
$redis->disconnect();
setcookie(self::$guid_key, self::$sid, time() - 3600);
return true;
}
/**/
public static function expireByGroup($group, $index = null)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$group_key = "session-group:$group";
$keys = $redis->smembers($group_key);
foreach ($keys as $i => $key) {
if ($index === null || $i === $index) {
$redis->srem($group_key, $key);
$redis->del($key);
}
}
$redis->disconnect();
return true;
}
/* Low Performance, Not recommended */
public static function listGroup(CRObject $rule)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$prefix = 'session-group:';
$keys = $redis->keys($prefix . '*');
$offset = $rule->getInt('offset', 0);
$limit = $rule->getInt('limit', -1);
$groups = array();
$len = strlen($prefix);
foreach ($keys as $index => $key) {
if ($index < $offset) {
continue;
}
if ($limit !== -1 && $offset + $limit <= $index) {
break;
}
$groups[] = array('index' => $index, 'group' => substr($key, $len));
}
$redis->disconnect();
return $groups;
}
/* Low Performance, Not recommended */
public static function listSession(CRObject $rule)
{
$redis = RedisDAO::instance();
if ($redis === null) {
return false;
}
$group = $rule->get('group', '');
$redis_key = "session-group:$group";
$keys = $redis->smembers($redis_key);
$sessions = array();
foreach ($keys as $index => $key) {
$session = $redis->hgetall($key);
if (count($session) === 0) {
$redis->srem($redis_key, $key);
continue;
}
$session['_index'] = $index;
$session['_current'] = $key === 'session:' . self::$sid;
$sessions[] = $session;
}
return $sessions;
}
}