记一次故障排查
偶然发现$_SESSION失效了
排查
第一步
检查浏览器中的cookie是否被禁用了,禁用的话得打开,我这里检查发现没有被禁用
为什么要检查浏览器的cookie呢,因为session是依赖cookie保存session_id的
第二步
检查session的相关配置是否开启
我这里是通过phpinfo查看的
具体查看
session.save_path有误,如权限不够,或是目录不存在
这个保存路径一定要存在且有权限
我这里通过第二步发现保存路径没有权限
通过chmod -R 777 保存路径 赋权解决了
补充
Session机制说明
在默认情况下,当访客访问网站时,php程序通过预先写好的session_start();命令在服务器端为该访客创建一个session文件,用于存储该访客的变量。并将创建好的session文件的id发送给客户端,客户端浏览器收到该session_id时,将该session_id存储在浏览器本地cookie中。
当访客离开该网页进入其他网页时,浏览器从本地cookie中取出session_id再发送给服务端,服务端php执行到session_strart()时将不再创建新的session给该访客,而是根据该session_id获得该访客的session变量继续使用,在各个跨网页间进行变量传递,已达到跨网页传递数据和用户信息不丢失的目的。
但是,当访客的客户端浏览器如果禁用了cookie,客户端将无法保存session值,当用户离开该网页进入其他网页时,服务端无法获得session_id和继续使用该session文件,就会把访客当做新用户,再次创建一个session文件给其使用。这样以来session就无法做到跨网页传递数据的目的了。
表现出来的现象就是session失效无法跨网页传递数据。
session id可以使用客户端的Cookie或者Http1.1协议的Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,并非只能使用cookie。
关于客户端禁用cookie的问题
如果客户端禁用了cookie,就意味着服务器端的session失效,那么我们就需要采取其他的传参的方式给服务器端把SESSION_ID传过去,常见的传输方式就是GET、POST
这个时候在服务器通过如下方式即可获得session的值
set.php
<?php
session_start();
$_SESSION['uid'] = '2023';
$sid = session_id();
echo "<a href='./bb.php?sid={$sid}'>获取session</a>";
get.php
<?php
$sid = $_GET['sid'];
session_id($sid);
session_start();
//注意这里的session_start()一定要放在session_id()之后才行
//另外要在php.ini中关闭session自启动 session.auto_start = 0
var_dump($_SESSION);
关于开启use_trans_sid 的说明
; trans sid support is disabled by default.
; Use of trans sid may risk your users' security.
; Use this option with caution.
; - User may send URL contains active session ID
; to other person via. email/irc/etc.
; - URL that contains active session ID may be stored
; in publicly accessible computer.
; - User may access your site with the same session ID
; always using URL stored in browser's history or bookmarks.
; http://php.net/session.use-trans-sid
session.use_trans_sid = 0
大概是什么意思呢?
翻译:
默认情况下禁用trans-sid支持。
使用trans-sid可能会危及用户的安全。
请谨慎使用此选项。用户可以通过将包含活动会话ID的URL发送给其他人。电子邮件/irc等。包含活动会话ID的URL可能存储在可公开访问的计算机中。用户可以始终使用存储在浏览器历史记录或书签中的URL使用相同的会话ID访问您的网站。
就是说:当这个开启后,在url里会追加SESSION_ID
localhost:8080/test/b.php?PHPSESSID=1b7uihm875fuik4o4bnodqrm92
这个时候在b.php里直接接收SESSION的值即可