我在这里遇到一个奇怪的问题。 我正在使用javascript ajax(我使用jquery)。现在的情况是;
一个ajax调用正在调用一个php脚本,它基本上是一个长时间运行的进程,它设置了一些会话变量。
稍后在某些时间间隔(比方说,每2秒),我正在运行另一个ajax调用来检查会话变量,以了解进程(第一个PHP脚本执行)何时完成。
第一个php脚本从数据库中获取数据并将其拧入文件中。在每个提取中,我计算循环数并将其存储到会话变量中以保留某种跟踪记录。等;
$i=0;
$_SESSION['time']=date('m-d-Y H:i:s');
while(...)
{
ini_set('session.use_only_cookies', false);
ini_set('session.use_cookies', false);
ini_set('session.use_trans_sid', false);
ini_set('session.cache_limiter', null);
session_start();
$_SESSION['tracksatus']="loop number : ".$i." time is :"$_SESSION['time'];
session_write_close();
$i++;
......
......
}
我通过setInterval
ajax调用的另一个php脚本就是这样;
echo $_SESSION['trackstatus']
设定的间隔ajax让我回归;
loop number 1 time is m-d-Y H:i:s
loop number 5 time is m-d-Y H:i:s
loop number 8 time is m-d-Y H:i:s
......
然后再打几次电话;
loop number 1 time is m-d-Y H1:i1:s1
.....
注意H:i:s更改为H1:i1:s1
根据我的理解,php脚本正在调用两次。并且对于您的信息,相同的代码在12小时之前就可以正常工作。我之前遇到过这个问题,并以某种方式解决了它(试验和错误,所以我不知道怎么样或者可能是自动的....好吧,实际上我没有线索)。
你能告诉我一些我做错了什么吗? 如果您需要更多信息,请提及。
有趣的是,在没有更改单行代码的情况下提出这个问题后,它正在按预期工作。但我想知道原因。
答案 0 :(得分:3)
我认为我知道是什么原因,PHP将会话变量写入文件,但它只在脚本执行结束时才这样做,所以在长篇文章结束之前你不能看到另一个脚本中会话的变化。 / p>
您可以在每次更改会话数据后添加session_write_close(); session_start();
来修复此问题。
session_write_close
会将更改写入HD,因此另一个脚本可以读取它。
session_start
将从HD加载会话,但请确保您的其他脚本不会对会话进行任何更改,这些更改将被您的长脚本覆盖。
如果您使用单独的域,还有一件事:
在实际的AJAX调用发生之前,您的浏览器会将OPTIONS
请求发送到同一URL以检查CORS标头。因此,在您的脚本开始时,请检查HTTP METHOD
以及HEAD
或OPTIONS
是否die();
答案 1 :(得分:3)
尝试使用临时文件来保持计数动态ID
,而不是使用会话<强>的Javascript 强>
var time = Date.now();
$.get('/firstURL?time='+time);
setInterval(function(){
$.get('/secondURL?time='+time, function(response){
console.log(response);
}
}, 1000);
PHP第一个网址
<?php
$id = $_GET['time'];
$count = 0;
while(...) {
// Do your stuff
$count++;
file_put_contents("/tmp/{$id}", $count);
}
?>
PHP第二个网址
<?php
$id = $_GET['time'];
$count = 0;
try {
$count = file_get_contents("/tmp/{$id}");
} catch(Exception $e) {}
echo $count;
?>
答案 2 :(得分:3)
正如其他人所说,PHP在执行完成之前不会写会话。你最好创建一个你调用的php函数写入一个带有进度的文件,然后你的第二个ajax调用只读取文件。
function updateCreateProgress($jobStartTime, $progress){
file_put_contents('/tmp/'.$jobStartTime.'.txt', $progress);
}
function completeProgress($jobStartTime){
unlink('/tmp/'.$jobStartTime.'.txt')
}
现在你的第二个脚本可以检查'/tmp/'.$jobStartTime.'.txt'
是否有使用file_get_contents
的内容,如果它没有报告它已经完成,那么就会检查它。
答案 3 :(得分:1)
尝试调整为:
$i=0;
ini_set('session.use_only_cookies', false);
ini_set('session.use_cookies', false);
ini_set('session.use_trans_sid', false);
ini_set('session.cache_limiter', null);
session_start();
$_SESSION['time']=date('m-d-Y H:i:s');
while(...)
{
$_SESSION['tracksatus']="loop number : ".$i." time is :"$_SESSION['time'];
session_write_close();
session_start();
$i++;
......
......
}
在调用session_start();
之前,您开始讨论$ _SESSION答案 4 :(得分:0)
如果使用GET方法调用ajax - 则必须设置“cache:false”选项。
是的,您必须保护您的php脚本免受其他请求的影响。使用唯一键(GET参数)或会话。
单个调用的php锁定会话数据,仅在此调用结束时释放它。当脚本仍在工作时使用session_write_close() - 不好的做法。也许你想要在循环之后但在使用其他请求中的这些数据之前保存更多会话。
灵活清晰的解决方案:
1)script1.php - 从ajax调用start start job。
2)script2.php(这里的长工作) - 直接从script1.php运行作为背景,无需等待,或者添加新的cron作业(插入表)并从cron运行script2.php(每秒或其他时间检查作业) )。
3)script3.php - 检查工作状态(ajax)。
对于script2.php和script3.php之间的“通信”,可以使用数据库或flock(),clearstatcache()和flush()的特殊文件。