278 lines
6.9 KiB
PHP
278 lines
6.9 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: dingran
|
|
* Date: 2019/2/18
|
|
* Time: 下午6:48
|
|
*/
|
|
|
|
namespace app\common\helpers;
|
|
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Redis;
|
|
|
|
define('TIMESTAMP', time());
|
|
|
|
class YunSession implements \SessionHandlerInterface
|
|
{
|
|
public static $uniacid;
|
|
|
|
public static $openid;
|
|
|
|
public static $expire;
|
|
|
|
public static function start($uniacid, $openid, $expire = 7200)
|
|
{
|
|
self::$uniacid = $uniacid;
|
|
self::$openid = $openid;
|
|
self::$expire = $expire;
|
|
|
|
$cache_setting = $GLOBALS['_W']['config']['setting'];
|
|
if (extension_loaded('memcache') && !empty($cache_setting['memcache']['server']) && !empty($cache_setting['memcache']['session'])) {
|
|
self::setHandler('memcache');
|
|
} elseif (self::getRedisStatus()) {
|
|
self::setHandler('redis');
|
|
} else {
|
|
self::setHandler('mysql');
|
|
}
|
|
register_shutdown_function('session_write_close');
|
|
session_start();
|
|
}
|
|
|
|
public static function setHandler($type = 'mysql')
|
|
{
|
|
$classname = "app\common\helpers\YunSession{$type}";
|
|
if (class_exists($classname)) {
|
|
$sess = new $classname;
|
|
}
|
|
if (version_compare(PHP_VERSION, '5.5') >= 0) {
|
|
session_set_save_handler($sess, true);
|
|
} else {
|
|
session_set_save_handler(
|
|
array(&$sess, 'open'),
|
|
array(&$sess, 'close'),
|
|
array(&$sess, 'read'),
|
|
array(&$sess, 'write'),
|
|
array(&$sess, 'destroy'),
|
|
array(&$sess, 'gc')
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public function open($save_path, $session_name)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function close()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
public function read($sessionid)
|
|
{
|
|
return '';
|
|
}
|
|
|
|
|
|
public function write($sessionid, $data)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
public function destroy($sessionid)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
public function gc($expire)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public static function getRedisStatus()
|
|
{
|
|
try {
|
|
return Redis::ping() == 'PONG';
|
|
} catch (\Exception $exception) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
class YunSessionMemcache extends YunSession
|
|
{
|
|
protected $session_name;
|
|
|
|
protected function key($sessionid)
|
|
{
|
|
return $this->session_name . ':' . $sessionid;
|
|
}
|
|
|
|
public function open($save_path, $session_name)
|
|
{
|
|
$this->session_name = $session_name;
|
|
|
|
return true;
|
|
}
|
|
|
|
public function read($sessionid)
|
|
{
|
|
$row = Redis::hgetall($this->key($sessionid));
|
|
if ($row['expiretime'] < TIMESTAMP) {
|
|
return '';
|
|
}
|
|
if (is_array($row) && !empty($row['data'])) {
|
|
return $row['data'];
|
|
}
|
|
return '';
|
|
}
|
|
|
|
public function write($sessionid, $data)
|
|
{
|
|
if (empty($data) || (!empty($data) && empty($this->chk_member_id_session($data)))) {
|
|
$read_data = $this->read($sessionid);
|
|
|
|
if (!empty($member_data = $this->chk_member_id_session($read_data))) {
|
|
$data .= $member_data;
|
|
}
|
|
}
|
|
|
|
$row = array();
|
|
$row['data'] = $data;
|
|
$row['expiretime'] = TIMESTAMP + YunSession::$expire;
|
|
$result = Redis::hmset($this->key($sessionid), $row);
|
|
Redis::expire($this->key($sessionid), YunSession::$expire);
|
|
return $result;
|
|
}
|
|
|
|
public function destroy($sessionid)
|
|
{
|
|
return Redis::del($this->key($sessionid));
|
|
}
|
|
|
|
public function chk_member_id_session($read_data)
|
|
{
|
|
$member_data = '';
|
|
|
|
if (!empty($read_data)) {
|
|
preg_match_all('/yunzshop_([\w]+[^|]*|)/', $read_data, $name_matches);
|
|
preg_match_all('/(a:[\w]+[^}]*})/', $read_data, $value_matches);
|
|
|
|
if (!empty($name_matches)) {
|
|
foreach ($name_matches[0] as $key => $val) {
|
|
if ($val == 'yunzshop_member_id') {
|
|
$member_data = $val . '|' . $value_matches[0][$key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $member_data;
|
|
}
|
|
}
|
|
|
|
class YunSessionRedis extends YunSessionMemcache
|
|
{
|
|
public function __construct()
|
|
{
|
|
}
|
|
|
|
public function open($save_path, $session_name)
|
|
{
|
|
$this->session_name = $session_name;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class YunSessionMysql extends YunSession
|
|
{
|
|
public function open($save_path, $session_name)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function read($sessionid)
|
|
{
|
|
$sql = 'SELECT * FROM ' . DB::getTablePrefix() . 'core_sessions WHERE `sid`=:sessid AND `expiretime`>:time';
|
|
$params = array();
|
|
$params[':sessid'] = $sessionid;
|
|
$params[':time'] = TIMESTAMP;
|
|
$row = DB::selectOne($sql, $params);
|
|
|
|
|
|
if (is_array($row) && !empty($row['data'])) {
|
|
return $row['data'];
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
|
|
public function write($sessionid, $data)
|
|
{
|
|
if (empty($data) || (!empty($data) && empty($this->chk_member_id_session($data)))) {
|
|
$read_data = $this->read($sessionid);
|
|
|
|
if (!empty($member_data = $this->chk_member_id_session($read_data))) {
|
|
$data .= $member_data;
|
|
}
|
|
}
|
|
|
|
$row = array();
|
|
$row['sid'] = $sessionid;
|
|
$row['uniacid'] = YunSession::$uniacid;
|
|
$row['openid'] = YunSession::$openid;
|
|
$row['data'] = $data;
|
|
$row['expiretime'] = TIMESTAMP + YunSession::$expire;
|
|
|
|
$sql = 'REPLACE INTO ' . DB::getTablePrefix() . "core_sessions (`sid`, `uniacid`, `openid`, `data`, `expiretime`)
|
|
VALUES ('{$row['sid']}', {$row['uniacid']}, '{$row['openid']}', '{$row['data']}', {$row['expiretime']})";
|
|
|
|
return DB::insert($sql) >= 1;
|
|
}
|
|
|
|
|
|
public function destroy($sessionid)
|
|
{
|
|
$row = array();
|
|
$row[':sid'] = $sessionid;
|
|
|
|
$sql = 'DELETE FROM ' . DB::getTablePrefix() . 'core_sessions WHERE `sid` = :sid';
|
|
return DB::delete($sql, $row) == 1;
|
|
}
|
|
|
|
|
|
public function gc($expire)
|
|
{
|
|
$sql = 'DELETE FROM ' . DB::getTablePrefix() . 'core_sessions WHERE `expiretime`<:expire';
|
|
|
|
return DB::delete($sql, [':expire' => TIMESTAMP]) == 1;
|
|
}
|
|
|
|
private function chk_member_id_session($read_data)
|
|
{
|
|
$member_data = '';
|
|
|
|
if (!empty($read_data)) {
|
|
preg_match_all('/yunzshop_([\w]+[^|]*|)/', $read_data, $name_matches);
|
|
preg_match_all('/(a:[\w]+[^}]*})/', $read_data, $value_matches);
|
|
|
|
if (!empty($name_matches)) {
|
|
foreach ($name_matches[0] as $key => $val) {
|
|
if ($val == 'yunzshop_member_id') {
|
|
$member_data = $val . '|' . $value_matches[0][$key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $member_data;
|
|
}
|
|
} |