【问题标题】:How does AJAX influence variables and functions in PHP?AJAX 如何影响 PHP 中的变量和函数?
【发布时间】:2016-07-03 10:35:34
【问题描述】:

根据定义,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 变量呢?我认为这些应该共享?因此,如果我们将上面的 sn-p 替换为类似下面的内容,那么 $values 数组会包含所有值吗?

$val = $_POST['someField'];
$_SESSION['values'] = array();

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

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

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

【问题讨论】:

  • AJAX 分别对待每个周期。您可以在现代浏览器网络监控工具上查看您的 sn-p 所做的事情。一旦脚本返回响应,它就会死掉。它不能再被另一个(不同的)AJAX 调用使用。您可能正在寻找 long polling 这有点说明,不要死,嘿后端脚本!。这些是我的想法。
  • 使您的 javascript 请求异步并不会改变 PHP 在处理它们时的行为方式。每个请求都将被赋予其自己的变量范围(包括 globals),除非您通过使用 sessions 或写入 database 来跨多个请求共享数据。

标签: php ajax scope


【解决方案1】:

是多个对同一个 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

如果另一个请求进来并试图在这个进程休眠时打开这个文件,你就会遇到问题。

【讨论】:

  • 很好的答案。但是关于您对同一文件的异步请求的评论,我认为问题在于包含请求脚本的文件,而不是受该脚本影响的文件。
  • OP prob 的意思是你写的,但我想我会扩大一点以涵盖可能被忽视的情况。我也喜欢你关于 DB 和 Sessions 的说明。
【解决方案2】:

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

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)

控制台

    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 调用。

【讨论】:

    【解决方案3】:

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

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

    在 php 中,您还可以检测其 AJAX(xmlhttprequest) here 是否仅包含一个变量以将其标识为 ajax。 (似乎没有一个是完全万无一失的)

    更多信息on wiki here

    另一个关于 ajax 与普通请求的 sof 查询here

    还有更多here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      相关资源
      最近更新 更多