在不启动 PHP 会话的情况下检查?

Posted

技术标签:

【中文标题】在不启动 PHP 会话的情况下检查?【英文标题】:Checking for PHP session without starting one? 【发布时间】:2010-12-19 08:09:21 【问题描述】:

是否可以在不启动会话的情况下检查会话?

我问的原因是,我正在开发的应用程序有一个集成的管理界面。因此,当管理员登录时,他们浏览与用户相同的页面以进行编辑。字段和选项根据用户权限显示。

这会导致两个问题。

一个是因为正在启动会话,所以我无法启用浏览器缓存功能,因为发送的标头始终是:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0       

我正在使用 smarty 输出模板,但无法实现:

$smarty->cache_modified_check = true;

发送一个未修改的 304,因为会话已经开始。使用上面的 smarty 参数对我来说是浏览器缓存的完美解决方案。

两个是因为每个使用该网站的人都在开始一个会话,会话目录中充满了不需要的会话。

如果用户未登录,我可以只销毁会话,但是每次加载页面时,用户都会创建和删除会话。这是不好的做法吗?

因此,如果我可以检查是否存在活动会话而不启动一个活动会话,那么我的所有问题都会得到解决。有任何想法吗?浏览器在请求页面时不发送会话cookie吗?

理想情况是这样的:

if (session_exists) 
 session_start();
 $users->priv = $_SESSION['priv'];

else 
 $users->priv = guest;

------------- 回应托尼·米勒 ---------------

使用 session_id() 时,您必须已经启动了一个会话,它才能返回一个 id。

session_start();
echo session_id($_SESSION);

或者您可以在调用会话开始之前为会话设置一个 id

session_id("adfasdf");
session_start();
echo session_id($_SESSION);

//prints "adfasdf"

这些都没有帮助我。除非我遗漏了什么。

【问题讨论】:

不要打电话给session_id("adfasdf"),而是打电话给session_id()。如果不存在会话,它将返回""。所以在打电话给session_start()之前做一个if(session_id()) 到目前为止,没有一个答案能正确解决这个问题:1)session_idsession_start 之前什么都不返回,2)phpSESSID cookie 不是一个可靠的参数,因为客户端可以提交任何他想要。 【参考方案1】:

你会想要session_id(),如果没有定义会话,它会返回空字符串。

文档指出,如果没有启动会话,则返回空字符串(不是“无”)。

正如 2014 年 cmets 所指出的(我在 2009 年写了这个答案),如果有一个存储了会话 ID 的 cookie 可以被session_start() 拾取,那么会话就有可能开始。

从 PHP 5.4.0 开始,我们现在有了 session_status(),但这在 2009 年还不存在。

【讨论】:

您能详细说明一下吗?看起来 session_id 有两种用途。 1. session_id($_SESSION) 返回会话的id,必须在session_start()之后调用。 2. 在 session_start() 之前调用 session_id("asdf") 将会话的 id 设置为 "asdf"。我不确定其中任何一个如何帮助我。如果我在调用 session_start() 之前给它一个新的 id,我将如何知道当前的浏览器会话?谢谢 实际上, session_id() 返回当前会话 id - 如果没有,它将是空字符串 ('')。我不认为 session_is($_SESSION) 是一个有效的用途。 session_is($_SESSION) 无效。它将尝试将会话 ID 设置为 $_SESSION 中的任何内容 - 很可能它将是一个值为 'Array' 的字符串。这是一个巨大的安全威胁。 在 session_start() 之前调用 session_id() 不会返回任何内容,即使潜在会话可用(即,即使 PHPSESSID 设置为某个值)。 为什么这个答案有 12 个赞?它在问题的意义上不起作用......对不起,但我是-1。写更多,描述更多,并说明为什么这会起作用,我将取消我的反对票。【参考方案2】:

您可以检查是否设置了 PHPSESSID cookie(PHPSESSID 名称可能有其他名称,具体取决于您的服务器设置,请检查 ini.session.name)。

但如果您担心的只是污染会话目录,您可以调整 session.gc_probability、session.gc_divisor 和 session.gc_maxlifetime 以使它们更快消失。

【讨论】:

这似乎是票。在调用 session_start() 之前检查是否设置了 $_REQUEST['PHPSESSID'] 可以让您知道会话是否“可用”。 好答案。如果您(OP)发现$_COOKIE[session_name()] 有一个值,您还应该在调用session_start() 之前验证是否存在名称与该值匹配的会话文件。您永远不想做的是允许用户以用户给您的名称创建新会话。 是的,这个很棒。我对“最佳”答案投了反对票,因为这当然不是最好的;)。这个是。来自我的 +1。【参考方案3】:

这里有一个函数可以满足您的要求,即在启动之前检查会话是否存在:

function sessionExists() 
    return (isset($_COOKIE[session_name()]));

如果您想在创建它的同一请求中对其进行测试,则可以改为:

function sessionExists() 
    return (isset($_SESSION) || isset($_COOKIE[session_name()]));

【讨论】:

以上是关于在不启动 PHP 会话的情况下检查?的主要内容,如果未能解决你的问题,请参考以下文章

PHP-如何在不重新启动 rds 的情况下将 aws.push git 到弹性 beantalk?

如何在不重新加入会话的情况下检查屏幕会话的进度?

没有 cookie 的 PHP 会话

有没有办法在不关闭当前会话的情况下“刷新”终端/iTerm?

Xcode - 如何在不更改 UIScreen 大小的情况下添加 xib 启动屏幕

如何在不轮询内核的情况下监控 C 程序中的 NIC 状态(启动/关闭)?