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

问题描述:

I'm using PHP7 to start sessions using my favorite control method: URL paths. This used to work [the way I'm doing it] but doesn't work in PHP7. Let's start with a completely normal hello world example.

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

Run it first with TRUE and this baby works perfectly. Set it to FALSE and you get what you expect. Run it over and over and you get the same, expected result. I can even visit the session file and see that the variables were saved.

Now, I'm a fan of controlling my code using domain paths. E.G., example.com/action1/action2. Action1 is identified in my .htaccess file as a PHP type file and my doc_root has a symbolic link, action1 -> index.php. Please note, this works fine in every way but one... the moment you add those paths to the URI, the session stops reading the variables.

Can you help me understand why? Yes, the obvious solution to the question, "it hurts when I do this, what should I do?" is "don't do that." But like I said, I'm a fan. Frankly, this should work. The one and only cookie is correct. session_id() reports that I am looking at the same session ID and file. The very same session ID that is filled with data. Remove the /action1/action2 component and the $_SESSION variables show up again, just as we'd expect.

Does anyone know why this happens? What is it about adding the path that disables the session? Why would PHP even care so long as it has the expected session id? I even tried to file_get_contents() the session file so I could session_decode() the contents. Without the action path, I can read and process the file. With the action path (drum roll please...) I can't even read the file. It's as if some kind of ownership change has occured, but I have the file and directory permissions wide open. Any ideas?

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

EDIT: If you want to test this yourself. Save the first file to test.php, then update your .htaccess file as shown. Finally, ln -s test.php action1. Run domain.com/test.php to prove to yourself the sessions are working. Then run domain.com/action1 and watch the variables disappear.

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

 &lt;?php 
session_start(); 
if(TRUE){
 $ _SESSION ['test'] ='  Hello World!'; 
} 
print_r($ _ SESSION); 
echo“&lt; P&gt;”。session_id(); 
  code>  pre> 
 
 

首先使用TRUE运行它 这个宝贝很完美。 设置为FALSE,你得到你期望的。 一遍又一遍地运行它,你得到相同的预期结果。 我甚至可以访问会话文件并看到变量已保存。 p>

现在,我是使用域路径控制代码的粉丝。 E.G.,example.com / action1 / action2。 Action1在我的.htaccess文件中被标识为PHP类型文件,我的doc_root有一个符号链接,action1 - &gt; index.php文件。 请注意,这种方法在各方面都很好但只有一个......当你将这些路径添加到URI时,会话就会停止读取变量。 p>

你能帮助我理解为什么吗? 是的,这个问题的明显解决方案是“我这样做会很疼,我该怎么办?” 是“不要那样做”。 但就像我说的那样,我是粉丝。 坦率地说,这应该有效。 唯一的cookie是正确的。 session_id() code>报告我正在查看相同的会话ID和文件。 填充数据的完全相同的会话ID。 删除/ action1 / action2组件,$ _SESSION变量再次出现,正如我们所期望的那样。 p>

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

  .htaccess:
RewriteEngine On 
RewriteBase / 
AddHandler application / x-httpd-php70 .php 
&lt; Files action1&gt; 
 SetHandler application / x-  httpd-php 
&lt; / Files&gt; 
  code>  pre> 
 
 

编辑:如果你想自己测试一下。 将第一个文件保存到 test.php code>,然后更新.htaccess文件,如图所示。 最后, ln -s test.php action1 code>。 运行 domain.com/test.php code>以证明会话正在运行。 然后运行 domain.com/action1 code>并观察变量消失。 p> div>

As it turns out, @hakre was on the right path, but the change didn't solve the problem. The problem is that Plesk directly assigns *.php files to be processed through php_fpm. In the Virtual Host Apache configuration file we have...

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

This is how Plesk is specifically attaching one version of PHP over another by domain name. And anything that doesn't fall into this rule is interpreted by Apache's global rules, which for me are looking at a different install of PHP. (Why Plesk doesn't have a global override to point at their own PHP installs is a bit of a wonder, but I suspect this is a bug they've never encountered before.) So, logically, we'd need only add for each file we want to process without the .php suffix...

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

It is true that you need to do this, but for me it didn't work as advertised. My web page simply said "Access Denied" and my error files pointed me to FPM's security.limit_extensions paramter. In other words, despite specifically identifying a file I wanted to use without a suffix, FPM rejected it anyway. Here's where I got lazy. I reset the variable to nothing. In Plesk that's done by creating or modifying a php.ini file inside the domain's conf directory and adding (including the header if it's not already there)...

[php-fpm-pool-settings]
security.limit_extensions =

Restart Apache and Bob's your uncle.

According to a really rapid Google search, the ability to directly modify FPM parameters from inside Plesk is still up for debate.

Now, this comes with a price. From the perspective of the FPM socket, suddenly any file in you're web root "could" be executed as a PHP file, including images customers upload and you blindly put in your [ROOT]/images directory. You're partially saved by the fact that unless you've told Apache otherwise, just any old file won't be interpreted as a PHP file. However, you'd be better protected if all files you upload through your site are (a) thoroughly vetted to be sure they are what they claim to be and (b) are either saved outside the web root or in a DB so that nobody can "execute" them by referring to them directly.

Finally, there ought to be a way to override in a config file those files that I want to intentionally violate security.limit_extensions. Unfortunately, FPM and Apache don't appear to talk to each other, otherwise the use of the block would completely override security.limit_extensions. For all I know there's a way to do it. I'd be curious to know, but I have a working solution, so I'm back to work.

You are using two different PHP versions:

The application/x-httpd-php70 handler per default for all .php files.

And on the other hand, the application/x-httpd-php handler for file starting with action1.

When you add that path, apache uses a different PHP configuration which might block or use a different session store. I can't say in specific as I have never created such a setup, but it's likely you just have forgotten to use the same action handler for the files.

That is action handler configuration in Apache. See the docs https://httpd.apache.org/docs/2.4/handler.html so that you can better understand what is going on (and perhaps as well where that second PHP is from, you should be able to find that in the Apache configurtion).