会话变量不适用于 php 中的后台进程


Session variables doesn't work with background process in php

会话变量在使用后台进程时是否有效?

我有两个php脚本 - index.php:

session_start();
$_SESSION['test'] = 'test';
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/xampp/php/php-cgi.exe -f C:/xampp/htdocs/sand_box/background.php".session_id(), 0, false);
/*
continue the program
*/

和背景.php:

session_id($argv[1]);
session_start();
sleep(5);
$test = $argvs[1];
$myFile = "myFile.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, $test);
fclose($fh);

后台进程创建 myFile.txt但会话变量不起作用。我做了一些其他测试,但无论如何都不起作用。有人知道为什么吗?

使用后台进程是否有限制?

编辑了代码,我现在的问题是我无法将任何变量作为参数传递。 $argv始终为空。

我终于解决了,register_argc_argv必须在php.ini上启用!

您可以将session_id传递给后台脚本:

$oExec = $WshShell->Run("C:/xampp/php/php-cgi.exe -f C:/xampp/htdocs/sand_box/background.php " . session_id(), 0, false);

在后台脚本中,您写为第一行:

session_id($argv[1]);
session_start();

编辑:如@chris所述,由于锁定,您需要注意后台脚本将等待index.php停止执行。

php 通常从 cookie 或 http 请求字段中获取会话 ID。当您直接通过命令行执行时,两者都不可用。因此,请考虑通过命令行 arg 或环境变量传递 session_id(),然后在生成的脚本中通过以下方式指定它

session_start($the_session_id);

接下来,您需要确保PHP的其他实例使用相同的配置。它可以对session_save_path使用不同的设置。通过 phpinfo() 进行检查并根据需要进行调整。

最后,php 在会话文件上使用独占锁定模型。因此,一次只能打开一个进程的特定会话 ID 的会话文件。PHP 通常会在完成脚本执行后释放其在会话文件上的锁,但您可以通过 session_write_close() 更快地执行此操作。如果在生成另一个脚本之前不调用 session_write_close(),则调用session_start($the_session_id);时另一个脚本将处于死锁状态。

但。。。如果第二个脚本不需要修改会话,甚至不要打扰。只需向它传递所需的值,然后忘记会话。

COM 调用的 PHP 进程将不知道用户已建立的会话。相反,您应该尝试将会话值作为参数传递给background.php脚本:

$oExec = $WshShell->Run(sprintf("C:/xampp/php/php-cgi.exe -f C:/xampp/htdocs/sand_box/background.php %s", $_SESSION['test']) , 0, false);

那么在您的background.php中,您应该能够通过$argv访问该值:

// You should see the session value as the 2nd value in the array
var_dump($argv);
$myFile = 'myFile.txt';
....

以上只是一个理论,因为我以前没有通过COM运行它,但应该有效。

更多关于 argv 的信息 这里.

--更新--

session_start();
$WshShell = new COM("WScript.Shell");
// Notice the space between background.php and session_id()
$oExec = $WshShell->Run("C:/xampp/php/php-cgi.exe -f C:/xampp/htdocs/sand_box/background.php " . session_id(), 0, false);