读取/设置当前缓存的到期时间
      int session_cache_expire ([ string $new_cache_expire ] )
      请求开始的时候,缓存到期时间会被重置为 180分钟,并且保存在 session.cache_expire 配置项中。 因此,针对每个请求,需要在 session_start() 函数调用之前 调用 session_cache_expire() 来设置缓存到期时间。如果给定 new_cache_expire ,就使用 new_cache_expire 的值设置当前缓存到期时间,以分钟为单位,默认值是 180 (分钟)。 

读取/设置缓存限制器
      string session_cache_limiter ([ string $cache_limiter ] )
      缓存限制器定义了向客户端发送的 HTTP 响应头中的缓存控制策略。 客户端或者代理服务器通过检测这个响应头信息来 确定对于页面内容的缓存规则。 设置缓存限制器为nocache 会禁止客户端或者代理服务器缓存内容, public 表示允许客户端或代理服务器缓存内容, private 表示允许客户端缓存, 但是不允许代理服务器缓存内容。在 private 模式下, 包括 Mozilla 在内的一些浏览器可能无法正确处理 Expire 响应头, 通过使用private_no_expire 模式可以解决这个问题:在这种模式下, 不会向客户端发送 Expire 响应头。 

获取/设置当前会话 ID
      string session_id ([ string $id ] )
      如果指定了 id 参数的值, 则使用指定值作为会话 ID。 必须在调用 session_start() 函数之前调用 session_id() 函数。 不同的会话管理器对于会话 ID 中可以使用的字符有不同的限制。 例如文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 , (逗号)和 - (减号) 。

读取/设置会话名称
      string session_name ([ string $name ] )
      session_name() 函数返回当前会话名称。 如果指定 name 参数, session_name() 函数会更新会话名称, 并返回 原来的 会话名称。请求开始的时候,会话名称会被重置并且存储到 session.name 配置项。 因此,要想设置会话名称,那么对于每个请求,都需要在 调用session_start() 或者 session_register() 函数 之前调用 session_name() 函数。 会话名称至少需要一个字母,不能全部都使用数字, 否则,每次都会生成一个新的会话 ID。 

读取/设置当前会话的保存路径
      string session_save_path ([ string $path ] )
      指定会话数据保存的路径。 必须在调用 session_start() 函数之前调用 session_save_path() 函数。 在某些操作系统上,建议使用可以高效处理 大量小尺寸文件的文件系统上的路径来保存会话数据。 例如,在 Linux 平台上,对于会话数据保存的工作而言,reiserfs 文件系统会比 ext2fs 文件系统能够提供更好的性能。 

启动新会话或者重用现有会话
      bool session_start ( void )
      session_start() 会创建新会话或者重用现有会话。 如果通过 GET 或者 POST 方式,或者使用 cookie 提交了会话 ID, 则会重用现有会话。

销毁一个会话中的全部数据
      bool session_destroy ( void )

但是不会重置当前会话所关联的全局变量, 也不会重置会话 cookie。


      1、session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的COOKIE键值,这个值可以从php.ini找到。 如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端.相当于执行了下面COOKIE 操作,注意的是,这一步执行了setcookie()操作,COOKIE是在header头中发送的,这之前是不能有输出的。PHP有另外一个函数session_regenerate_id(), 如果使用这个函数,这之前也是不能有输出的。

setcookie(session_name(), session_id(), session.cookie_lifetime,//默认0
                       session.cookie_path,//默认'/'当前程序跟目录下都有效
                       session.cookie_domain,//默认为空
                       )
      如果存在那么session_id =$_COOKIE[session_name()];然后去session.save_path指定的文件夹里去找名字为'SESS_'.session_id()的文件.读取文件的内容反序列化,然后放到$_SESSION中.

      2、比如新添加一个值$_SESSION['test'] ='blah'; 那么这个$_SESSION只会维护在内存中,当脚本执行结束的时候,把$_SESSION的值写入到session_id指定的文件夹中,然后关闭相关资源. 

      3、SESSION发出去的COOKIE一般属于即时COOKIE,保存在内存中,当浏览器关闭后,才会过期,假如需要人为强制过期,比如 退出登录,而不是关闭浏览器,那么就需要在代码里销毁SESSION,方法有很多:
      1]. setcookie(session_name(),session_id(),time() -8000000,..);//退出登录前执行
      2]. usset($_SESSION);//这会删除所有的$_SESSION数据,刷新后,有COOKIE传过来,但是没有数据。
      3]. session_destroy();//这个作用更彻底,删除$_SESSION 删除session文件,和session_id。
      当不关闭浏览器的情况下,再次刷新,2和3都会有COOKIE传过来,但是找不到数据。


<?php
// 初始化会话
session_name('Session_test');
session_id('safdsadfasdfsadfasdf');
session_start();

$_SERVER['user'] = 'admin';
echo $_SERVER['user']."<br>";

echo $_COOKIE[session_name()];

重置会话中的所有变量 -- 使用unset可以重置某个会话变量
// $_SESSION = array();
// // 同时删除会话 cookie
// if (ini_get("session.use_cookies"))
// {
// $params = session_get_cookie_params();
// setcookie(session_name(), '', time() - 42000,
// $params["path"], $params["domain"],
// $params["secure"], $params["httponly"]);
// }
// // 最后,销毁会话
// session_destroy();
?>

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
</head>

<body>
</body>
</html>

PHP Session管理_php


session 死锁

我们在使用session时,需要先执行​​session_start()​​函数。​​session_start()​​函数的作用如下:

判断 http 请求是否包含名为 PHPSESSID 的 cookie,如果没有则创建该 cookie 并写入到 http 响应的头文件。 
通过 PHPSESSID 查找对应的 session 文件,以读写方式打开的文件,然后读取里面的数据到内存。

然后我们一般会通过 $_SESSION 这个超全局变量,读取或者设置 session 的值,我们操作的时候,session 的值都是保存在内存中的,默认在页面执行完毕之后,才会写入到对应的文件中。

upload.php

<?php
session_start();
$_SESSION['name']='koastal';
sleep(10); //sleep 10s 模拟文件上传耗时
  • index.php
<?php
session_start();
var_dump($_SESSION);
  • 通过上面的分析可以知道,session 在页面执行完毕之后,才会写入到文件中,并释放文件锁。session 的功能,我们一般都是在页面中的一部分用到的,当我们处理完 session 之后,可以使用

​session_commit()​

  • 或者

​session_write_close()​

  • 函数,提前将 session 的值写入到文件中,并释放文件锁。

死锁示例优化后程序

upload.php

<?php
session_start();
$_SESSION['name']='koastal';
session_commit();
sleep(10); //sleep 10s 模拟文件上传耗时
  • 我们操作完 session 之后,先将 session 数据写入到文件,然后再执行上传过程,就不会影响到其他页面使用该 session 文件了。

执行完session_commit之后

<?php
session_start();
$_SESSION['name'] = "koastal";
session_commit();
echo $_SESSION['name'];
  • session_commit 的另一个名字是 session_write_close,也就是将 session 信息写入并关闭文件的意思。session_commit 之后,虽然 session 文件已经关闭,但是页面还在执行,只要没有执行 session_unset 内存中就还保存着 session 的值,所以我们还可以获取和输出 session 的值。其实,这个时候我们还可以给 session 赋值,但是这个赋值只是赋值到内存中,因为文件已经关闭,所以其他页面时访问不到 session_commit(); 之后设置的session的值。

通过上面的分析,我们知道 session 的值会保存在内存和文件两个地方。 
session_start() 会将对应文件打开,并将 session 数据读入到内存。 
session_commit() 会将内存中的 session 数据写入到文件中,并关闭文件。 
不显示调用 session_commit() 的话,会在页面执行完毕之后,自动调用。

所以,我们需要删除内存中的 session 信息,并且删除 session 文件。

session_unset();    //删除内存中的session信息
session_destory(); //删除session文件
  • 如果我们只是用

​session_unset();​

  • 也能达到注销用户的效果,但是这样处理实际上是把 session 的数据设置为空,并且写入session 文件中了,本质上并没有删除 session 文件。

上面的两部操作,销毁了服务器上的 session 值,此外,我们还需要清理保存在客户端中的 cookie,完成真正意义上的注销操作。

注销登录完整代码

logout.php

<?php
session_unset(); //删除内存中的session信息
session_destory(); //删除session文件
setcookie('PHPSESSID', null, time()-10);//将cookie值设置为过期