会话控制
因为 HTTP
是无状态的协议,没有办法记录多个事务请求间的状态。即访问一个页面请求后再请求另一个页面时无法判断两次请求来自同一个用户。
会话原理
在 PHP 中实现会话的原理是为用户分配一个唯一的加密ID,并保存在用户客户端,并在整个会话时间周期内有效。
一般情况下使用 cookie 来进行保存,但也可以通过 url 传递。
用户通过携带会话 ID 到服务器获取内容。
COOKIE
cookie 是客户端存储数据的手段,并在请求服务器时自动携带 cookie 数据。
设置
PHP 中使用 setcookie() 函数对用户客户端设置 cookie 数据。
setcookie(string $name [, string $value = "" [, int $expires = 0 [, string $path = "" [, string $domain = "" [, bool $secure = FALSE [, bool $httponly = FALSE ]]]]]]): bool
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 数据。
document.cookie
后台使用超全局数组 $_COOKIE 读取。
print_r($_COOKIE);
使用
设置会话 cookie,当关闭浏览器时自动删除。
setcookie('name','admin');
设置七天内有效的 cookie
setcookie('name','admin',time()+60*60*24*7);
只允许 cookie 在 /app
访问路径中有效。
setcookie('web','baidu.com',0,'/app');
设置访问域名。
setcookie('name','admin',0,'/','baidu.com');
设置只允许 https 访问
setcookie('name','admin',0,'/','',true);
不允许 javascript 操作 cookie
setcookie('name','admin',0,'/','',false,true);
将 cookie
的到期时间设置为过去时间,就可以删除 cookie。
setcookie('name','',1);
SESSION
session 是服务器会话状态,可用于记录访问用户后台会话数据。
基本使用
开启会话
必须要开启 SESSION 才可以使用,有两种方法可以开启会话。
使用脚本开启会话,要保证在使用会话的所有脚本中执行。
session_start();
通过修改 php.ini 配置项
session.auto_start
,自动开启会话(不建议使用)
会话变量
使用超全局数组 $_SESSION
来使用会话变量。
设置变量
$_SESSION['name'] = 'admin';
删除变量
unset($_SESSION['name']);
删除所有变量
$_SESSION = [];
# 或使用函数删除
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,并更好的服务我们的网站业务。
<?php
class FileHandle implements SessionHandlerInterface
{
//写入目录
protected $path = 'session';
//过期时间
protected $maxlifetime = 1440;
/**
* 构建函数
*
* @param string $path 保存目录
* @param integer $maxlifetime 过期时间
*/
public function __construct(string $path = 'session', int $maxlifetime = 1440)
{
$this->path = $this->mkdir($path);
$this->maxlifetime = $maxlifetime;
}
/**
* 关闭
*
* @return void
*/
public function close()
{
return true;
}
/**
* 销毁
*
* @param [type] $session_id
* @return void
*/
public function destroy($session_id)
{
return (bool)@unlink($this->path . '/' . $session_id);
}
/**
* 垃圾回收
*
* @param [type] $maxlifetime
* @return void
*/
public function gc($maxlifetime)
{
foreach (glob($this->path . '/*') as $file) {
if (filemtime($file) + $this->maxlifetime < time()) {
@unlink($file);
}
}
return true;
}
protected function mkdir($path){
is_dir($path) or mkdir($path, 0755, true);
return realpath($this->path);
}
/**
* 开启
*
* @param [type] $save_path
* @param [type] $session_name
* @return void
*/
public function open($save_path, $session_name)
{
return true;
}
/**
* 读取会话数据
*
* @param [type] $session_id
* @return void
*/
public function read($session_id)
{
return @file_get_contents($this->path . '/' . $session_id);
}
/**
* 写入会话
*
* @param [type] $session_id
* @param [type] $session_data
* @return void
*/
public function write($session_id, $session_data)
{
return (bool)file_put_contents($this->path . '/' . $session_id, $session_data);
}
}
调用方法
<?php
include 'session.php';
//声明会话引擎
session_set_save_handler(new FileHandle,true);
session_start();
$_SESSION['web'] = 'baidu.com';
$_SESSION['name'] = 'admin';
print_r($_SESSION);