Cookie.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2021 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types = 1);
  12. namespace think;
  13. use DateTimeInterface;
  14. /**
  15. * Cookie管理类
  16. * @package think
  17. */
  18. class Cookie
  19. {
  20. /**
  21. * 配置参数
  22. * @var array
  23. */
  24. protected $config = [
  25. // cookie 保存时间
  26. 'expire' => 0,
  27. // cookie 保存路径
  28. 'path' => '/',
  29. // cookie 有效域名
  30. 'domain' => '',
  31. // cookie 启用安全传输
  32. 'secure' => false,
  33. // httponly设置
  34. 'httponly' => false,
  35. // samesite 设置,支持 'strict' 'lax'
  36. 'samesite' => '',
  37. ];
  38. /**
  39. * Cookie写入数据
  40. * @var array
  41. */
  42. protected $cookie = [];
  43. /**
  44. * 当前Request对象
  45. * @var Request
  46. */
  47. protected $request;
  48. /**
  49. * 构造方法
  50. * @access public
  51. */
  52. public function __construct(Request $request, array $config = [])
  53. {
  54. $this->request = $request;
  55. $this->config = array_merge($this->config, array_change_key_case($config));
  56. }
  57. public static function __make(Request $request, Config $config)
  58. {
  59. return new static($request, $config->get('cookie'));
  60. }
  61. /**
  62. * 获取cookie
  63. * @access public
  64. * @param mixed $name 数据名称
  65. * @param string $default 默认值
  66. * @return mixed
  67. */
  68. public function get(string $name = '', $default = null)
  69. {
  70. return $this->request->cookie($name, $default);
  71. }
  72. /**
  73. * 是否存在Cookie参数
  74. * @access public
  75. * @param string $name 变量名
  76. * @return bool
  77. */
  78. public function has(string $name): bool
  79. {
  80. return $this->request->has($name, 'cookie');
  81. }
  82. /**
  83. * Cookie 设置
  84. *
  85. * @access public
  86. * @param string $name cookie名称
  87. * @param string $value cookie值
  88. * @param mixed $option 可选参数
  89. * @return void
  90. */
  91. public function set(string $name, string $value, $option = null): void
  92. {
  93. // 参数设置(会覆盖黙认设置)
  94. if (!is_null($option)) {
  95. if (is_numeric($option) || $option instanceof DateTimeInterface) {
  96. $option = ['expire' => $option];
  97. }
  98. $config = array_merge($this->config, array_change_key_case($option));
  99. } else {
  100. $config = $this->config;
  101. }
  102. if ($config['expire'] instanceof DateTimeInterface) {
  103. $expire = $config['expire']->getTimestamp();
  104. } else {
  105. $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0;
  106. }
  107. $this->setCookie($name, $value, $expire, $config);
  108. }
  109. /**
  110. * Cookie 保存
  111. *
  112. * @access public
  113. * @param string $name cookie名称
  114. * @param string $value cookie值
  115. * @param int $expire 有效期
  116. * @param array $option 可选参数
  117. * @return void
  118. */
  119. protected function setCookie(string $name, string $value, int $expire, array $option = []): void
  120. {
  121. $this->cookie[$name] = [$value, $expire, $option];
  122. }
  123. /**
  124. * 永久保存Cookie数据
  125. * @access public
  126. * @param string $name cookie名称
  127. * @param string $value cookie值
  128. * @param mixed $option 可选参数 可能会是 null|integer|string
  129. * @return void
  130. */
  131. public function forever(string $name, string $value = '', $option = null): void
  132. {
  133. if (is_null($option) || is_numeric($option)) {
  134. $option = [];
  135. }
  136. $option['expire'] = 315360000;
  137. $this->set($name, $value, $option);
  138. }
  139. /**
  140. * Cookie删除
  141. * @access public
  142. * @param string $name cookie名称
  143. * @param array $options cookie参数
  144. * @return void
  145. */
  146. public function delete(string $name, array $options = []): void
  147. {
  148. $config = array_merge($this->config, array_change_key_case($options));
  149. $this->setCookie($name, '', time() - 3600, $config);
  150. }
  151. /**
  152. * 获取cookie保存数据
  153. * @access public
  154. * @return array
  155. */
  156. public function getCookie(): array
  157. {
  158. return $this->cookie;
  159. }
  160. /**
  161. * 保存Cookie
  162. * @access public
  163. * @return void
  164. */
  165. public function save(): void
  166. {
  167. foreach ($this->cookie as $name => $val) {
  168. [$value, $expire, $option] = $val;
  169. $this->saveCookie(
  170. $name,
  171. $value,
  172. $expire,
  173. $option['path'],
  174. $option['domain'],
  175. $option['secure'] ? true : false,
  176. $option['httponly'] ? true : false,
  177. $option['samesite']
  178. );
  179. }
  180. }
  181. /**
  182. * 保存Cookie
  183. * @access public
  184. * @param string $name cookie名称
  185. * @param string $value cookie值
  186. * @param int $expire cookie过期时间
  187. * @param string $path 有效的服务器路径
  188. * @param string $domain 有效域名/子域名
  189. * @param bool $secure 是否仅仅通过HTTPS
  190. * @param bool $httponly 仅可通过HTTP访问
  191. * @param string $samesite 防止CSRF攻击和用户追踪
  192. * @return void
  193. */
  194. protected function saveCookie(string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly, string $samesite): void
  195. {
  196. if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
  197. setcookie($name, $value, [
  198. 'expires' => $expire,
  199. 'path' => $path,
  200. 'domain' => $domain,
  201. 'secure' => $secure,
  202. 'httponly' => $httponly,
  203. 'samesite' => $samesite,
  204. ]);
  205. } else {
  206. setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
  207. }
  208. }
  209. }