1

Does session variables work when using background process?

I have two php scripts - 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
*/

and the background.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);

The background process creates the myFile.txt however the session variable doesn't work. I did some other tests and it doesn't work in any case. Anyone knows why?

Is it a limitation of using a background process?

I edited the code, my problem now is that I can't pass any variable as arguments. $argv is always empty.

I finally solved it, register_argc_argv must be enabled on php.ini!

4

3 回答 3

1

php 通常从 cookie 或 http 请求字段中获取会话 ID。当您直接通过命令行执行时,它们都不可用。因此,请考虑通过命令行参数或环境变量传递 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);被调用时将陷入死锁。

但是......如果第二个脚本不需要修改会话,甚至不要打扰。只需将它需要的值传递给它并忘记会话。

于 2012-04-26T04:05:09.480 回答
1

您可以传递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停止执行。

于 2012-04-26T04:05:23.520 回答
0

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);
于 2012-04-26T04:03:24.393 回答