当使用 /action1/action2 而不是 ?action1=&action2= 时,Session_start 无法读取会话

Session_start fails to read session when /action1/action2 rather than ?action1=&action2= is used

我正在使用 PHP7 使用我最喜欢的控制方法启动会话:URL 路径。这曾经工作 [我正在做的方式] 但在 PHP7 中不起作用。让我们从一个完全正常的 hello world 示例开始。

<?php
session_start();
if(TRUE){
    $_SESSION['test'] = 'Hello World!';
}
print_r($_SESSION);
echo "<P>".session_id();

运行 首先是 TRUE,这个宝贝效果很好。将它设置为 FALSE,您将得到您期望的结果。 运行 一遍又一遍,您会得到相同的预期结果。我什至可以访问会话文件并查看变量是否已保存。

现在,我热衷于使用域路径来控制我的代码。例如,com/action1/action2。 Action1 在我的 .htaccess 文件中被识别为 PHP 类型的文件,而我的 doc_root 有一个符号 link,action1 -> index.php。请注意,这在所有方面都可以正常工作,除了一个......当您将这些路径添加到 URI 时,会话将停止读取变量。

你能帮我理解为什么吗?是的,"it hurts when I do this, what should I do?" 这个问题的明显解决方案是 "don't do that." 但就像我说的,我是粉丝。坦率地说,这应该有效。唯一的 cookie 是正确的。 session_id() 报告我正在查看相同的会话 ID 和文件。充满数据的完全相同的会话 ID。删除 /action1/action2 组件,$_SESSION 变量再次出现,正如我们所期望的那样。

有谁知道为什么会这样?添加禁用会话的路径是什么?只要它具有预期的会话 ID,为什么 PHP 还要关心呢?我什至尝试 file_get_contents() 会话文件,这样我就可以 session_decode() 内容。没有操作路径,我可以读取和处理文件。使用动作路径(请打鼓......)我什至无法读取文件。就好像发生了某种所有权变更,但我的文件和目录权限是完全开放的。有什么想法吗?

.htaccess:
RewriteEngine On
RewriteBase /
AddHandler application/x-httpd-php70 .php
<Files action1>
  SetHandler application/x-httpd-php
</Files>

编辑:如果您想自己测试一下。将第一个文件保存到 test.php,然后更新您的 .htaccess 文件,如图所示。最后,ln -s test.php action1。 运行 domain.com/test.php 向自己证明这些会话有效。然后 运行 domain.com/action1 并观察变量消失。

您正在使用两个不同的 PHP 版本:

所有 .php 个文件的默认 application/x-httpd-php70 处理程序。

另一方面,application/x-httpd-php 处理程序以 action1 开头的文件。

添加该路径时,apache 使用不同的 PHP 配置,这可能会阻止或使用不同的会话存储。我不能具体说,因为我从来没有创建过这样的设置,但很可能你只是忘记了对文件使用相同的操作处理程序。

这是 Apache 中的操作处理程序配置。请参阅文档 https://httpd.apache.org/docs/2.4/handler.html 以便您可以更好地了解正在发生的事情(也许还有第二个 PHP 的来源,您应该能够在 Apache 配置中找到它)。

事实证明,@hakre 走在正确的道路上,但改变并没有解决问题。问题在于 Plesk 直接分配 *.php 文件通过 php_fpm 进行处理。在虚拟主机 Apache 配置文件中,我们有...

<Files ~ (\.php$)>
    SetHandler proxy:unix:///var/www/vhosts/system/wwphelps.com/php-fpm.sock|fcgi://127.0.0.1:9000
</Files>

这就是 Plesk 专门通过域名将 PHP 的一个版本附加到另一个版本的方式。任何不属于此规则的内容均由 Apache 的全局规则解释,对我而言,它正在查看 PHP 的不同安装。 (为什么 Plesk 没有全局覆盖来指向他们自己的 PHP 安装有点奇怪,但我怀疑这是他们以前从未遇到过的错误。)因此,从逻辑上讲,我们会只需要为我们要处理的每个文件添加没有 .php 后缀...

<Files action1>
    SetHandler proxy:unix:///var/www/vhosts/system/wwphelps.com/php-fpm.sock|fcgi://127.0.0.1:9000
</Files>

您确实需要这样做,但对我来说并没有像宣传的那样奏效。我的网页只是说 "Access Denied" 而我的错误文件将我指向 FPM 的 security.limit_extensions 参数。换句话说,尽管明确标识了一个我想使用的没有后缀的文件,但 FPM 还是拒绝了它。这就是我偷懒的地方。我将变量重置为空。在 Plesk 中,这是通过在域的 conf 目录中创建或修改 php.ini 文件并添加(包括 header 如果它不存在)...

来完成的
[php-fpm-pool-settings]
security.limit_extensions =

重新启动 Apache,Bob 就是你的叔叔了。

根据非常快速的 Google 搜索,从 Plesk 内部直接修改 FPM 参数的能力仍然存在争议。

现在,这是有代价的。从 FPM socket 的角度来看,突然间你的 web root "could" 中的任何文件都作为 PHP 文件执行,包括客户上传的图像和你盲目地放在你的 [ROOT]/images 目录中的图像。除非您以其他方式告诉 Apache,否则任何旧文件都不会被解释为 PHP 文件,这一事实让您部分得救。但是,如果您通过您的站点上传的所有文件都经过 (a) 彻底审查以确保它们与他们声称的一样,并且 (b) 保存在网络根目录之外或数据库中,那么您会得到更好的保护,这样就没有人可以 "execute" 直接引用它们。

最后,应该有一种方法可以在配置文件中覆盖那些我想故意违反的文件 security.limit_extensions。不幸的是,FPM 和 Apache 似乎并不互相交谈,否则块的使用将完全覆盖 security.limit_extensions。据我所知,有一种方法可以做到。我很想知道,但我有一个可行的解决方案,所以我回去工作了。