AJAX如何影响PHP中的变量和函数


How does AJAX influence variables and functions in PHP?

根据定义,Ajax是对服务器的异步请求。但这对于PHP文件中的变量意味着什么呢?

假设我们在for循环中有一个Ajax请求。每次迭代的请求都是相同的,除了输入略有不同(在本例中为someField)。

for (var iOuter = 0; iOuter < 3; iOuter++) {
  (function(i) {
    myArrayVariable['someField'] = i;
    $.ajax({
        type: 'POST',
        url: 'someurl.php',
        data: myArrayVariable
      })
      .done(function() {
        console.log("Finished " + i);
      })
      .fail(function(jqXHR, textStatus, error) {
        console.error(error + ": " + textStatus);
      });
  })(iOuter);
}

在PHP中,我们可以这样写:

$val = $_POST['someField'];
$values = array();
for ($i = 0; $i < 10; $i++) {
  push($values, ($val+$i));
}

我的问题是:因为这是一个异步请求,这是否意味着变量的范围在不同的请求之间共享?换句话说,$values是否包含所有请求的所有值(当每个请求中的循环完成时),还是每个请求都是唯一的?

在扩展中,如何修改SESSION变量?我想这些应该是共享的吧?那么,如果我们将上面的代码片段替换为下面的代码,那么$values数组就会有所有的值吗?

$val = $_POST['someField'];
$_SESSION['values'] = array();
for ($i = 0; $i < 10; $i++) {
  push($_SESSION['values'], ($val+$i));
}

或者有可能,因为一些小的时间差,即使第一个初始化的请求已经向数组中写入了一个值,第二个请求将会话变量重新初始化为空数组?所以价值可能会丢失?

总结一下:变量是在多个ajax请求中共享到同一个PHP文件,还是每个请求都是唯一的?那么SESSION变量和它们的初始化呢?当你在PHP中使用变量/函数时,如果你知道你在ajax请求中使用该文件,你应该注意什么时候?或者,一般来说:对同一文件的异步请求是否会相互影响?

是在对同一PHP的多个ajax请求之间共享的变量文件,还是每个请求都是唯一的?

PHP变量在每次请求时都被重置,所以你不必担心一个请求会干扰另一个请求的值。

那么SESSION变量和它们的初始化呢?

$_SESSION数据不同。它位于PHP进程之外的磁盘或内存中的某个位置,就像数据库数据一样。因此,像数据库一样,它可以在请求之间存活,无论是异步的还是其他方式,并且将按照先到先服务的原则进行修改。

在您的示例中,您在每个请求上设置$_SESSION['values'] = array();,因此它将被重置为空数组。如果您刚刚向它推送了新值,那么来自先前请求的值将继续存在(至少在会话被销毁之前)。

关于会话的另一个要点:当会话处于活动状态时,PHP会锁定底层文件。因此,如果您的请求需要很长时间才能提供服务,并且同一会话的另一个请求进入,那么您将遇到麻烦。在这种情况下,最好的办法是在使用完会话文件后释放它,例如在脚本的早期。您总是可以在最后重新加载它以存储脚本的结果。

session_start();
... // do your session work early
session_write_close();
... // continue with your long script

对同一文件的异步请求是否会相互影响?

是的!如果处理需要很长时间处理文件,则另一个进程可能会出错。考虑这个脚本:

//allow script to run for a long time (or PHP might kill it)
set_time_limit(35);
$file = fopen("test.txt","w+"); //open file
flock($file,LOCK_EX); //set exclusive lock.
sleep(30); //sleep for 30 seconds
flock($file,LOCK_UN); //release lock
fclose($file);//close the file

如果另一个请求进来并试图在此进程休眠时打开此文件,您将遇到问题。

让我们运行一个测试,看看:

JS

    for (ajax_var=1; ajax_var < 4; ajax_var++) {
        $.ajax({
            url: 'variable.php',
            type: 'POST',
            data: { 'ajax_var': ajax_var },
            success: function(resp) {
                console.log(resp);
            }
        });
    }
PHP

    if(!isset($_SESSION)) { session_start(); }
    $ajax_var = $_POST['ajax_var'];
    $_SESSION['var'] = $ajax_var;
    $data = [];
    for ($php_var = 1; $php_var < 4; $php_var++) {
        array_push($data, "Ajax Variable = " . $ajax_var);
        array_push($data, "PHP Variable = " . $php_var);
        array_push($data, "Session Variable = " . $_SESSION['var']);
        array_push($data, "   ");
    }
    print_r($data)
<<p> 控制台/strong>
    Array
    (
        [0] => Ajax Variable = 1
        [1] => PHP Variable = 1
        [2] => Session Variable = 1
        [3] =>    
        [4] => Ajax Variable = 1
        [5] => PHP Variable = 2
        [6] => Session Variable = 1
        [7] =>    
        [8] => Ajax Variable = 1
        [9] => PHP Variable = 3
        [10] => Session Variable = 1
        [11] =>    
    )
    variable_test_run.html:20 
    Array
    (
        [0] => Ajax Variable = 2
        [1] => PHP Variable = 1
        [2] => Session Variable = 2
        [3] =>    
        [4] => Ajax Variable = 2
        [5] => PHP Variable = 2
        [6] => Session Variable = 2
        [7] =>    
        [8] => Ajax Variable = 2
        [9] => PHP Variable = 3
        [10] => Session Variable = 2
        [11] =>    
    )
    variable_test_run.html:20 
    Array
    (
        [0] => Ajax Variable = 3
        [1] => PHP Variable = 1
        [2] => Session Variable = 3
        [3] =>    
        [4] => Ajax Variable = 3
        [5] => PHP Variable = 2
        [6] => Session Variable = 3
        [7] =>    
        [8] => Ajax Variable = 3
        [9] => PHP Variable = 3
        [10] => Session Variable = 3
        [11] =>    
    )

看起来好像第一个php脚本在第二个php脚本启动之前就完成了。然而,我是在本地服务器上运行的,而实时服务器的响应速度可能比javascript代码稍慢。但是,两个脚本对齐并造成重叠的可能性几乎为零。我确信会话变量更有可能有重叠,但我从来没有真正理解为什么你需要在一个真实世界的例子中循环ajax调用。

每个请求都是唯一的。您可以使用会话,cookie,数据库来收集单独请求的数据。

会话将工作,因为每个ajax本质上与浏览器执行POST/GET并接收响应相同,除了它都发生在JS中。

php中的

除了包含一个变量来标识它是AJAX之外,还可以检测它是否是AJAX(xmlhttprequest)。(似乎没有一个是完全防傻瓜的)

更多信息在维基这里

关于ajax和普通请求的另一个软查询