通过PHP

时间:2015-07-28 18:28:53

标签: php apache session cookies

php.net说:

  

PHP中的会话支持包含一种保留某些数据的方法   后续访问。

     

访问您网站的访问者被分配了一个唯一的ID,即所谓的ID   会话ID。这可以存储在用户端的cookie中,也可以存储在cookie中   在URL中传播。

我正在尝试查看第二个选项,即php通过查询字符串传递会话ID。我这样做只是出于教育目的。我知道不推荐这样做。

重现我的实验:

我在/var/www/html/script.php中存储了以下脚本:

<?php  
  session_start();
  if (isset($_SESSION["accesses"])) ++$_SESSION["accesses"];
  else $_SESSION["accesses"] = 1;
  echo "This page has been accessed ", $_SESSION["accesses"], " times";
?>

使用php.ini中的默认php设置,即:

session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0
一切正常。也就是说,当我在浏览器中访问localhost / script.php并刷新页面几次时,计数器就会按照它的设置运行。

当我在浏览器中禁用cookie时,当我多次刷新页面时,计数器不再有效(它始终保持为1)。然后我在网上看到,默认情况下,通过查询字符串维护php会话是关闭的。然后我按照以下方式修改了php.ini:

session.use_cookies = 0
session.use_only_cookies = 0
session.use_trans_sid = 1

重新加载apache2之后
service apache2 reload

脚本中的计数器无论如何都不起作用。我在php.ini中尝试了几个设置组合,但没有运气。

我使用PHP 5.5.9和Apache 2.4.7。

问题:

我的理解是当禁用cookie并且在php.ini中启用通过查询字符串传递会话ID时,在第一次GET之后,php应该看到查询字符串中没有会话ID。然后,php将初始化用户的会话ID,并发送一个响应,该响应将客户端重定向到查询字符串中具有会话ID的相同URL。所有这一切都在没有编写任何代码的情况下发生 - 它由php模块完成以维持会话。

这至少是我期待的事情。这实际上有多少呢?我是否对PHP自动做的事情有很多假设?但是,如果我这样做,那么这是什么“这可以存储在用户端的cookie中,也可以在URL中传播。”在php.net上关于? 如果禁用cookie时_SESSION不起作用,那么它不应该这样说吗?

修改

要在下面回答的其他评论:

神秘解决了。通过查询字符串维护会话的工作方式与下面的已加星标的答案相同。为了看到它的实际效果,我将/var/www/html/script.php中的脚本修改为:

<?php  
  session_start();
  if (isset($_SESSION["accesses"])) ++$_SESSION["accesses"];
  else $_SESSION["accesses"] = 1;
  echo "This page has been accessed ", $_SESSION["accesses"], " times";
  echo '<br><a href="script.php">revisit</a>';
?>

您可以看到,简单地刷新页面被PHP视为多个页面 尝试初始化新会话。只有当您单击“重新访问”链接时,会话ID才会实际嵌入(通过PHP自动)链接中,并且计数器开始工作(从那时起,它会通过再次关注链接或刷新来增加。)

关于php.ini中的设置的另一个词 (注意:我在Firefox 39.0中进行了以下所有实验。其他浏览器的行为可能有所不同。):

选项1: 如果您希望PHP使用cookie来维护会话(如果它们在客户端浏览器中启用)并使用查询字符串(如果禁用了cookie),请确保您的php.ini具有以下设置:

session.use_cookies = 1
session.use_only_cookies = 0
session.use_trans_sid = 1

默认情况下启用第一个(至少在我的PHP版本中,见上文)。其余两个从默认值修改。您需要修改两者

这是如何工作的非常有趣,因为当您执行第一个GET请求时,您不会在查询字符串中传递会话ID并且未设置cookie,因此PHP 不知道是否应该重写链接(参见下面的已加星标的答案)或设置一个cookie(可能会失败)。

它的作用是它同时尝试:你可以看到,在第一次访问时,下面示例中的“重新访问”链接被php重写为包含会话ID但是服务器尝试设置的第一个响应一个cookie。

仅在第二次请求之后,PHP 知道是否已成功种植cookie。如果是,则不再重写链接。如果没有,它会不断重写链接以包含查询字符串中的会话ID。

选项2: 如果您希望PHP使用cookie来维护会话(如果它们在客户端浏览器中启用)但是如果禁用cookie则不使用查询字符串,请坚持使用以下默认设置:

session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0

选项3: 如果您希望PHP专门使用查询字符串来维护会话(不推荐),即使启用了cookie,也可以使用:

session.use_cookies = 0
session.use_only_cookies = 0
session.use_trans_sid = 1

请注意,这些与默认的PHP设置完全相反。这是有充分理由的。

2 个答案:

答案 0 :(得分:2)

  

我是否对PHP自动做的事情做了太多假设?

是的,这部分不会发生:

  

然后php将...发送一个响应,将客户端重定向到查询字符串中具有会话ID的相同URL。

PHP对该选项的作用是在页面中重写链接,这样当您点击进入下一页时,将保留会话ID。没有任何东西可以阻止你离开没有会话ID的页面,这只是一个创建新会话的标志。

因此,当您通过刷新同一页面进行测试时,就像刷新登录表单而不是提交它一样 - 您告诉PHP每次都要开始一个新会话。

(注意:我从来没有真正使用过这个功能,所以我可能完全错了,并且对礼貌的更正持开放态度。)

答案 1 :(得分:1)

由于绝对不建议在查询字符串中使用会话ID,但在PHP 4.2.0+中可能会这样,因此大多数主机默认情况下会在您的apache配置中禁用它们。只需检查此行的apache / vhost / htaccess配置:

php_flag session.use_trans_sid off

更新 (感谢IMSoP):要检查session.use_trans_sid是否在某处被禁用,您只需在脚本中添加phpinfo();并检查设置& #39; s值。

如果您使用的是早于4.2的PHP版本,则必须使用--enable-trans-sid参数编译PHP,请参阅PHP手册:

  

除非您使用的是PHP 4.2.0或更高版本,否则需要启用它   构建PHP时手动。在Unix下,将--enable-trans-sid传递给   配置。   http://de2.php.net/manual/en/session.idpassing.php

如果您这样做,可以像现在一样启用session.use_trans_sid,PHP会关心ID。

否则,您必须手动保留ID,例如:

<?php echo 'mypage.php?'.htmlspecialchars(SID); ?>