使用后台进程时,会话变量是否有效?
我有两个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
*/
和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);
后台进程会创建myFile.txt,但会话变量不起作用。我做了一些其他测试,但在任何情况下都不起作用。谁知道为什么?
使用后台进程是否有限制?
我编辑了代码,我现在的问题是我不能将任何变量作为参数传递。 $ argv总是空的。
我终于解决了它,必须在php.ini上启用register_argc_argv!
答案 0 :(得分:2)
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);
时,另一个脚本将挂起死锁。
但是......如果第二个脚本不需要修改会话,甚至不用打扰。只需传递它需要的值并忘记会话。
答案 1 :(得分:2)
您可以将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
停止执行。
答案 2 :(得分:1)
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 here。
- 更新 -
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);