forked from floatschedule/yii2-phpredis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Session.php
150 lines (138 loc) · 4.88 KB
/
Session.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
namespace dcb9\redis;
use yii\base\InvalidConfigException;
use Yii;
/**
* Redis Session implements a session component using [redis](http://redis.io/) as the storage medium.
*
* Redis Session requires redis version 2.6.12 or higher to work properly.
*
* It needs to be configured with a redis [[Connection]] that is also configured as an application component.
* By default it will use the `redis` application component.
*
* To use redis Session as the session application component, configure the application as follows,
*
* ~~~
* [
* 'components' => [
* 'session' => [
* 'class' => 'dcb9\redis\Session',
* 'redis' => [
* 'hostname' => 'localhost',
* 'port' => 6379,
* 'database' => 0,
* ]
* ],
* ],
* ]
* ~~~
*
* Or if you have configured the redis [[Connection]] as an application component, the following is sufficient:
*
* ~~~
* [
* 'components' => [
* 'session' => [
* 'class' => 'dcb9\redis\Session',
* // 'redis' => 'redis' // id of the connection application component
* ],
* ],
* ]
* ~~~
*
* @property boolean $useCustomStorage Whether to use custom storage. This property is read-only.
*
* @author Bob chengbin <[email protected]>
*/
class Session extends \yii\web\Session
{
/**
* @var Connection|string|array the Redis [[Connection]] object or the application component ID of the Redis [[Connection]].
* This can also be an array that is used to create a redis [[Connection]] instance in case you do not want do configure
* redis connection as an application component.
* After the Session object is created, if you want to change this property, you should only assign it
* with a Redis [[Connection]] object.
*/
public $redis = 'redis';
/**
* @var string a string prefixed to every cache key so that it is unique. If not set,
* it will use a prefix generated from [[Application::id]]. You may set this property to be an empty string
* if you don't want to use key prefix. It is recommended that you explicitly set this property to some
* static value if the cached data needs to be shared among multiple applications.
*/
public $keyPrefix;
/**
* Initializes the redis Session component.
* This method will initialize the [[redis]] property to make sure it refers to a valid redis connection.
* @throws InvalidConfigException if [[redis]] is invalid.
*/
public function init()
{
if (is_string($this->redis)) {
$this->redis = Yii::$app->get($this->redis);
} elseif (is_array($this->redis)) {
if (!isset($this->redis['class'])) {
$this->redis['class'] = Connection::className();
}
$this->redis = Yii::createObject($this->redis);
}
if (!$this->redis instanceof Connection) {
throw new InvalidConfigException("Session::redis must be either a Redis connection instance or the application component ID of a Redis connection.");
}
if ($this->keyPrefix === null) {
$this->keyPrefix = substr(md5(Yii::$app->id), 0, 5);
}
$this->redis->open();
parent::init();
}
/**
* Returns a value indicating whether to use custom session storage.
* This method overrides the parent implementation and always returns true.
* @return boolean whether to use custom storage.
*/
public function getUseCustomStorage()
{
return true;
}
/**
* Session read handler.
* Do not call this method directly.
* @param string $id session ID
* @return string the session data
*/
public function readSession($id)
{
$data = $this->redis->get($this->calculateKey($id));
return $data === false || $data === null ? '' : $data;
}
/**
* Session write handler.
* Do not call this method directly.
* @param string $id session ID
* @param string $data session data
* @return boolean whether session write is successful
*/
public function writeSession($id, $data)
{
return (bool)$this->redis->setex($this->calculateKey($id), $this->getTimeout(), $data);
}
/**
* Session destroy handler.
* Do not call this method directly.
* @param string $id session ID
* @return boolean whether session is destroyed successfully
*/
public function destroySession($id)
{
return (bool)$this->redis->del($this->calculateKey($id));
}
/**
* Generates a unique key used for storing session data in cache.
* @param string $id session variable name
* @return string a safe cache key associated with the session variable name
*/
protected function calculateKey($id)
{
return $this->keyPrefix . md5(json_encode([__CLASS__, $id]));
}
}