我猜这是一些我从未遇到过的已知问题。我有一个多维数组通过 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'})
根据 print_r($_POST['vids'])
,PHP 收到以下内容:
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
到底是怎么回事?
最佳答案
考虑您在问题中显示的 foreach 循环以及您的答案中的循环:
// First
foreach($_POST['vids'] as $i => &$arr) {
//...
}
// Second
foreach($_POST['vids'] as $arr) echo $arr['vid_id']."\n";
第一个循环在 $arr
和 $_POST['vids']
的每个元素之间创建一个引用,但是对最后一个元素的引用永远不会被取消设置,所以$arr
实际上仍然引用数组的最后一个元素
这听起来可能有点不直观,但它的意思是,当您更改 $arr
的值时,$_POST['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";
关于javascript - PHP foreach 与通过 AJAX 发送的多维数组的怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50912968/