代码之家  ›  专栏  ›  技术社区  ›  Mitya

通过ajax发送多维数组的php技术

  •  5
  • Mitya  · 技术社区  · 6 年前

    我猜这是我从未遇到过的已知问题。我有一个多维数组通过ajax发送到php,如下所示:

    let pd = {
        vids: $.map(yt_vids_preview.find('tr:has(td :checked)'), function(el) {
            let vid = $(el).data('vid');
            return {
                vid_id: vid.contentDetails.videoId
        }; })
    };
    $.ajax({data: pd, url: 'foo.php', type: 'post'})
    

    以下是php收到的消息,根据 print_r($_POST['vids']) :

    Array
    (
        [0] => Array
            (
                [vid_id] => kCkrVN7IVbo
            )
    
        [1] => Array
            (
                [vid_id] => dNVxfnb8fjo
            )
    
        [2] => Array
            (
                [vid_id] => rJEEYTzYiAE
            )
    )
    

    一切都好。三个不同的视频。

    现在来说说你的古怪。

    foreach($_POST['vids'] as $arr) echo $arr['vid_id']."\n";
    

    出于某种原因,这将输出:

    kCkrVN7IVbo
    dNVxfnb8fjo
    dNVxfnb8fjo
    

    其中一件物品被复制了,另一件很贵,但却被完全省略了。我省略了所有其他代码,没有重写 $arr 或者类似的事情。

    如果我用基本的 for() 循环,甚至迭代回调函数,如 array_walk() :

    array_walk($_POST['vids'], function($arr) { echo $arr['vid_id']."\n"; });
    

    给予:

    kCkrVN7IVbo
    dNVxfnb8fjo
    rJEEYTzYiAE
    

    到底怎么回事?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Aramil Rey    6 年前

    考虑到你在问题中显示的foreach循环,以及你的答案中显示的循环:

    // First
    foreach($_POST['vids'] as $i => &$arr) {
        //...
    }
    
    // Second
    foreach($_POST['vids'] as $arr) echo $arr['vid_id']."\n";
    

    第一个循环在 $arr 每一个元素 $_POST['vids'] ,但对最后一个元素的引用从未取消设置,因此 阿尔 实际上仍在引用数组的最后一个元素

    这听起来可能有些不直观,但它的意思是 $后['vids'] 更改的值时更改 阿尔 ,所以在上一次迭代中 $_post['vids'] ,你正在做 $arr = $arr 哪个值是在循环的前一次迭代中得到的。

    从图形上看,类似的事情正在发生。(这不是有效的php)

    $arr = [1, 2, 3, 4, 5 <=> $value] 
    // This represents the last item on arr being a reference of $value (<=> is not being used as an actual operator, its representing the reference)
    
    foreach($arr as $value) {
        echo $arr;
    }
    // OUTPUT:
    [1, 2, 3, 4, 1 <=> $value] // $value equals the first element of the array
    [1, 2, 3, 4, 2 <=> $value] // $value equals the 2nd element of the array
    [1, 2, 3, 4, 3 <=> $value] // $value equals the 3rd element
    [1, 2, 3, 4, 4 <=> $value] // $value equals the 4th element
    [1, 2, 3, 4, 4 <=> $value] // $value equals itself (4th element)
    

    要解决这个问题,只需要在第二个循环之前使用 unset($arr)

    unset($arr);
    foreach($_POST['vids'] as $arr) echo $arr['vid_id']."\n";
    
        2
  •  1
  •   Mitya    6 年前

    不确定这是否对其他人有帮助,但它证明了 $arr 在一个 foreach() 在同一个函数的更早版本中,loop是罪魁祸首。

    关键的是,这一个是通过引用分配的,即。

    foreach($_POST['vids'] as $i => &$arr) {
        //...
    }
    

    由于某些原因,我没有完全理解,这导致了我后来使用 阿尔 在另一个地方 前额() 指派。我知道它是从先前的引用分配泄漏的,但是为什么要复制一个并忽略另一个视频id?奇怪的结果…

    foreach($_POST['vids'] as $arr) echo $arr['vid_id']."\n";