2017-04-25 77 views
6

我在这里面临一个奇怪的问题。 我使用javascript ajax(我用jquery)。现在情况是这样的;PHP脚本自动被多次调用

一个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的变化:我:s到H1:I1:S1

所以,按我的理解PHP脚本正在调用两次。对于您的信息,相同的代码在12小时之前可能正在工作。我之前遇到过这个问题,并以某种方式解决了它(试验和错误,所以我不知道如何或可能会自动......确实我没有线索)。

你能给我一个洞察力,我做错了吗? 请提及您是否需要更多信息。

而有趣的是,它只是在问这个问题之后就能按预期工作,甚至没有改变一行代码。但我想知道原因。

+0

因为while循环。 – vijay

+0

不清楚,请解释 –

+0

你的AJAX是什么样的? – 2017-05-02 02:20:13

回答

3

我想我知道是什么原因,PHP将会话变量写入文件,但它只在脚本执行结束时才会执行,所以在长结尾之前您不能看到另一个脚本中会话的更改。

您可以通过在每次更改会话数据后添加session_write_close(); session_start();来解决此问题。

session_write_close会将更改写入HD,因此另一个脚本可以读取它。 session_start将从HD加载会话,但要确保您的另一个脚本不会更改会话,这些更改将被您的长脚本覆盖。

还有一件事情,如果你使用单独的域: 在实际的AJAX调用发生之前,浏览器发送OPTIONS请求到相同的URL来检查CORS头。所以,在你的脚本开始检查HTTP METHOD,如果它HEADOPTIONS使die();

+0

不,我有同样的域名,但我要添加你所说的。 –

+0

检查编辑的答案,我认为这个问题。 – h0x91B

+0

它没有帮助我,这些都不是我的问题 –

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调用在session_start()之前;

+0

不,实际上有在启动while循环之前的一个session_start –

+0

好的,这不在你的代码粘贴中 – delboy1978uk

3

而不是使用会话,请尝试使用一个临时文件,以保持计数和动态ID

的Javascript

var time = Date.now(); 
$.get('/firstURL?time='+time); 
setInterval(function(){ 
    $.get('/secondURL?time='+time, function(response){ 
     console.log(response); 
    } 
}, 1000); 

PHP 1 URL

<?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; 

?> 
+0

它不会被调用两次,它有时会被一次又一次地调用 –

+0

@KOUSIKMANDAL因为你说它被调用多次你的AJAX或代码有问题,你还没有告诉我们 – 2017-05-02 02:35:44

+0

好吧,如果是的话,它应该总是被调用多次,但有时它可以正常工作。我要添加代码。 –

0

如果使用GET方法调用ajax - 必须设置“cache:false”选项。

是的,你必须保护你的PHP脚本免受其他请求。使用唯一密钥(GET参数)或会话。

php锁定单个呼叫的会话数据,只有当这个呼叫结束时才释放它。当脚本仍在工作时使用session_write_close() - 不好的做法。也许你想在循环之后但在使用来自其他请求的数据之前将其保存到会话中。

灵活和透明的溶液:

1)script1.php - 从AJAX调用用于启动长期的工作。

2)script2.php(长时间工作在这里) - 直接从script1.php作为背景直接运行而不需要等待,或者添加新的cron作业(插入表格)并从cron运行script2.php(每秒钟检查作业时间)。

3)script3.php - 检查作业状态(ajax)。

对于script2.php和script3.php之间的“通信”,可以使用数据库或flock(),clearstatcache()和flush()等特殊文件。

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如果它不存在汇报它已经完成读取。