Store.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: yunwuxin <448901948@qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\session;
  12. use think\contract\SessionHandlerInterface;
  13. use think\helper\Arr;
  14. class Store
  15. {
  16. /**
  17. * Session数据
  18. * @var array
  19. */
  20. protected $data = [];
  21. /**
  22. * 是否初始化
  23. * @var bool
  24. */
  25. protected $init = null;
  26. /**
  27. * 记录Session name
  28. * @var string
  29. */
  30. protected $name = 'PHPSESSID';
  31. /**
  32. * 记录Session Id
  33. * @var string
  34. */
  35. protected $id;
  36. /**
  37. * @var SessionHandlerInterface
  38. */
  39. protected $handler;
  40. /** @var array */
  41. protected $serialize = [];
  42. public function __construct($name, SessionHandlerInterface $handler, array $serialize = null)
  43. {
  44. $this->name = $name;
  45. $this->handler = $handler;
  46. if (!empty($serialize)) {
  47. $this->serialize = $serialize;
  48. }
  49. $this->setId();
  50. }
  51. /**
  52. * 设置数据
  53. * @access public
  54. * @param array $data
  55. * @return void
  56. */
  57. public function setData(array $data): void
  58. {
  59. $this->data = $data;
  60. }
  61. /**
  62. * session初始化
  63. * @access public
  64. * @return void
  65. */
  66. public function init(): void
  67. {
  68. // 读取缓存数据
  69. $data = $this->handler->read($this->getId());
  70. if (!empty($data)) {
  71. $this->data = array_merge($this->data, $this->unserialize($data));
  72. }
  73. $this->init = true;
  74. }
  75. /**
  76. * 设置SessionName
  77. * @access public
  78. * @param string $name session_name
  79. * @return void
  80. */
  81. public function setName(string $name): void
  82. {
  83. $this->name = $name;
  84. }
  85. /**
  86. * 获取sessionName
  87. * @access public
  88. * @return string
  89. */
  90. public function getName(): string
  91. {
  92. return $this->name;
  93. }
  94. /**
  95. * session_id设置
  96. * @access public
  97. * @param string $id session_id
  98. * @return void
  99. */
  100. public function setId($id = null): void
  101. {
  102. $this->id = is_string($id) && strlen($id) === 32 ? $id : md5(microtime(true) . session_create_id());
  103. }
  104. /**
  105. * 获取session_id
  106. * @access public
  107. * @return string
  108. */
  109. public function getId(): string
  110. {
  111. return $this->id;
  112. }
  113. /**
  114. * 获取所有数据
  115. * @return array
  116. */
  117. public function all(): array
  118. {
  119. return $this->data;
  120. }
  121. /**
  122. * session设置
  123. * @access public
  124. * @param string $name session名称
  125. * @param mixed $value session值
  126. * @return void
  127. */
  128. public function set(string $name, $value): void
  129. {
  130. Arr::set($this->data, $name, $value);
  131. }
  132. /**
  133. * session获取
  134. * @access public
  135. * @param string $name session名称
  136. * @param mixed $default 默认值
  137. * @return mixed
  138. */
  139. public function get(string $name, $default = null)
  140. {
  141. return Arr::get($this->data, $name, $default);
  142. }
  143. /**
  144. * session获取并删除
  145. * @access public
  146. * @param string $name session名称
  147. * @return mixed
  148. */
  149. public function pull(string $name)
  150. {
  151. return Arr::pull($this->data, $name);
  152. }
  153. /**
  154. * 添加数据到一个session数组
  155. * @access public
  156. * @param string $key
  157. * @param mixed $value
  158. * @return void
  159. */
  160. public function push(string $key, $value): void
  161. {
  162. $array = $this->get($key, []);
  163. $array[] = $value;
  164. $this->set($key, $array);
  165. }
  166. /**
  167. * 判断session数据
  168. * @access public
  169. * @param string $name session名称
  170. * @return bool
  171. */
  172. public function has(string $name): bool
  173. {
  174. return Arr::has($this->data, $name);
  175. }
  176. /**
  177. * 删除session数据
  178. * @access public
  179. * @param string $name session名称
  180. * @return void
  181. */
  182. public function delete(string $name): void
  183. {
  184. Arr::forget($this->data, $name);
  185. }
  186. /**
  187. * 清空session数据
  188. * @access public
  189. * @return void
  190. */
  191. public function clear(): void
  192. {
  193. $this->data = [];
  194. }
  195. /**
  196. * 销毁session
  197. */
  198. public function destroy(): void
  199. {
  200. $this->clear();
  201. $this->regenerate(true);
  202. }
  203. /**
  204. * 重新生成session id
  205. * @param bool $destroy
  206. */
  207. public function regenerate(bool $destroy = false): void
  208. {
  209. if ($destroy) {
  210. $this->handler->delete($this->getId());
  211. }
  212. $this->setId();
  213. }
  214. /**
  215. * 保存session数据
  216. * @access public
  217. * @return void
  218. */
  219. public function save(): void
  220. {
  221. $this->clearFlashData();
  222. $sessionId = $this->getId();
  223. if (!empty($this->data)) {
  224. $data = $this->serialize($this->data);
  225. $this->handler->write($sessionId, $data);
  226. } else {
  227. $this->handler->delete($sessionId);
  228. }
  229. $this->init = false;
  230. }
  231. /**
  232. * session设置 下一次请求有效
  233. * @access public
  234. * @param string $name session名称
  235. * @param mixed $value session值
  236. * @return void
  237. */
  238. public function flash(string $name, $value): void
  239. {
  240. $this->set($name, $value);
  241. $this->push('__flash__.__next__', $name);
  242. $this->set('__flash__.__current__', Arr::except($this->get('__flash__.__current__', []), $name));
  243. }
  244. /**
  245. * 将本次闪存数据推迟到下次请求
  246. *
  247. * @return void
  248. */
  249. public function reflash(): void
  250. {
  251. $keys = $this->get('__flash__.__current__', []);
  252. $values = array_unique(array_merge($this->get('__flash__.__next__', []), $keys));
  253. $this->set('__flash__.__next__', $values);
  254. $this->set('__flash__.__current__', []);
  255. }
  256. /**
  257. * 清空当前请求的session数据
  258. * @access public
  259. * @return void
  260. */
  261. public function clearFlashData(): void
  262. {
  263. Arr::forget($this->data, $this->get('__flash__.__current__', []));
  264. if (!empty($next = $this->get('__flash__.__next__', []))) {
  265. $this->set('__flash__.__current__', $next);
  266. } else {
  267. $this->delete('__flash__.__current__');
  268. }
  269. $this->delete('__flash__.__next__');
  270. }
  271. /**
  272. * 序列化数据
  273. * @access protected
  274. * @param mixed $data
  275. * @return string
  276. */
  277. protected function serialize($data): string
  278. {
  279. $serialize = $this->serialize[0] ?? 'serialize';
  280. return $serialize($data);
  281. }
  282. /**
  283. * 反序列化数据
  284. * @access protected
  285. * @param string $data
  286. * @return array
  287. */
  288. protected function unserialize(string $data): array
  289. {
  290. $unserialize = $this->serialize[1] ?? 'unserialize';
  291. return (array) $unserialize($data);
  292. }
  293. }