会话控制

因为 HTTP 是无状态的协议,没有办法记录多个事务请求间的状态。即访问一个页面请求后再请求另一个页面时无法判断两次请求来自同一个用户。

会话原理

在 PHP 中实现会话的原理是为用户分配一个唯一的加密ID,并保存在用户客户端,并在整个会话时间周期内有效。

一般情况下使用 cookie 来进行保存,但也可以通过 url 传递。

用户通过携带会话 ID 到服务器获取内容。

COOKIE

cookie 是客户端存储数据的手段,并在请求服务器时自动携带 cookie 数据。

设置

PHP 中使用 setcookie() 函数对用户客户端设置 cookie 数据。

  1. setcookie(string $name [, string $value = "" [, int $expires = 0 [, string $path = "" [, string $domain = "" [, bool $secure = FALSE [, bool $httponly = FALSE ]]]]]]): bool
  1. setcookie('name','admin',time()+60*60*24);

参数说明如下:

参数 说明
name cookie 的名称。
value cookie 的值。该值存储在客户端计算机上;不要存储敏感信息。
expires cookie 过期的时间。这是一个Unix时间戳,可以使用 time() 函数加上希望它到期之前的秒数来设置它。
path 服务器上可以使用 cookie 的路径。如果设置为 “/“,则 cookie 将在整个范围内可用。
domain cookie 可用的域。(例如”www.baidu.com”)将使 cookie 可用于该子域及其所有其他子域(即w2.www.baidu.com)。要使 cookie 可用于整个域(包括其所有子域),只需将值设置为域名(在本例中为”baidu.com”)
secure 表示 cookie 应仅通过客户端的安全 HTTPS 连接传输。
httponly 当为 TRUE 时,cookie 只能通过 HTTP 协议访问时。这意味着脚本语言(例如 JavaScript)无法访问 cookie。

读取

因为 cookie 保存在客户端并在请求时提交到后台服务器,所以可以在前台与后台访问到 cookie。

前台使用 document.cookie 获取 cookie 数据。

  1. document.cookie

后台使用超全局数组 $_COOKIE 读取。

  1. print_r($_COOKIE);

使用

设置会话 cookie,当关闭浏览器时自动删除。

  1. setcookie('name','admin');

设置七天内有效的 cookie

  1. setcookie('name','admin',time()+60*60*24*7);

只允许 cookie 在 /app 访问路径中有效。

  1. setcookie('web','baidu.com',0,'/app');

设置访问域名。

  1. setcookie('name','admin',0,'/','baidu.com');

设置只允许 https 访问

  1. setcookie('name','admin',0,'/','',true);

不允许 javascript 操作 cookie

  1. setcookie('name','admin',0,'/','',false,true);

cookie 的到期时间设置为过去时间,就可以删除 cookie。

  1. setcookie('name','',1);

SESSION

session 是服务器会话状态,可用于记录访问用户后台会话数据。

基本使用

开启会话

必须要开启 SESSION 才可以使用,有两种方法可以开启会话。

  1. 使用脚本开启会话,要保证在使用会话的所有脚本中执行。

    1. session_start();
  2. 通过修改 php.ini 配置项 session.auto_start ,自动开启会话(不建议使用)

会话变量

使用超全局数组 $_SESSION 来使用会话变量。

设置变量

  1. $_SESSION['name'] = 'admin';

删除变量

  1. unset($_SESSION['name']);

删除所有变量

  1. $_SESSION = [];
  2. # 或使用函数删除
  3. session_destroy();

常用函数

session_save_path

设置服务器会话数据储存目录,必须在 session_start 前使用。

session_id

通过 session_id 函数来获取/设置当前会话 ID。

session_name

获取或设置会话 COOKIE 名称,如果设置会话名称则需要在 session_id 前调用。

垃圾回收

session.gc_probability

session 清除无效 session 的基率。

session.gc_divisor

启动垃圾回收程序的概率。概率计算公式为: session.gc_probability/session.gc_divisor ,如果网站访问量大建议将概率降低如 1/1000~5000。

session.gc_maxlifetime

session 文件过期时间,超过这个时间没有使用的 session 将视为垃圾,将在下次垃圾回收时删除。

自定义驱动

自定义 SESSION 处理驱动可以让我们更灵活的管理 SESSION,并更好的服务我们的网站业务。

  1. <?php
  2. class FileHandle implements SessionHandlerInterface
  3. {
  4. //写入目录
  5. protected $path = 'session';
  6. //过期时间
  7. protected $maxlifetime = 1440;
  8. /**
  9. * 构建函数
  10. *
  11. * @param string $path 保存目录
  12. * @param integer $maxlifetime 过期时间
  13. */
  14. public function __construct(string $path = 'session', int $maxlifetime = 1440)
  15. {
  16. $this->path = $this->mkdir($path);
  17. $this->maxlifetime = $maxlifetime;
  18. }
  19. /**
  20. * 关闭
  21. *
  22. * @return void
  23. */
  24. public function close()
  25. {
  26. return true;
  27. }
  28. /**
  29. * 销毁
  30. *
  31. * @param [type] $session_id
  32. * @return void
  33. */
  34. public function destroy($session_id)
  35. {
  36. return (bool)@unlink($this->path . '/' . $session_id);
  37. }
  38. /**
  39. * 垃圾回收
  40. *
  41. * @param [type] $maxlifetime
  42. * @return void
  43. */
  44. public function gc($maxlifetime)
  45. {
  46. foreach (glob($this->path . '/*') as $file) {
  47. if (filemtime($file) + $this->maxlifetime < time()) {
  48. @unlink($file);
  49. }
  50. }
  51. return true;
  52. }
  53. protected function mkdir($path){
  54. is_dir($path) or mkdir($path, 0755, true);
  55. return realpath($this->path);
  56. }
  57. /**
  58. * 开启
  59. *
  60. * @param [type] $save_path
  61. * @param [type] $session_name
  62. * @return void
  63. */
  64. public function open($save_path, $session_name)
  65. {
  66. return true;
  67. }
  68. /**
  69. * 读取会话数据
  70. *
  71. * @param [type] $session_id
  72. * @return void
  73. */
  74. public function read($session_id)
  75. {
  76. return @file_get_contents($this->path . '/' . $session_id);
  77. }
  78. /**
  79. * 写入会话
  80. *
  81. * @param [type] $session_id
  82. * @param [type] $session_data
  83. * @return void
  84. */
  85. public function write($session_id, $session_data)
  86. {
  87. return (bool)file_put_contents($this->path . '/' . $session_id, $session_data);
  88. }
  89. }

调用方法

  1. <?php
  2. include 'session.php';
  3. //声明会话引擎
  4. session_set_save_handler(new FileHandle,true);
  5. session_start();
  6. $_SESSION['web'] = 'baidu.com';
  7. $_SESSION['name'] = 'admin';
  8. print_r($_SESSION);