我有一个包含IP地址及其各自子网信息的数组。在第一次,我必须将子网信息添加到我的数据库中,但我试图这样做,没有任何重复,使用此代码
#Note that this is pseudo-code
foreach ($subnets as $subnet)
{
$query = 'INSERT INTO subnets (field1, field2)
VALUES ($subnet['subnet'], $subnet['netmask']);'
$database->executeQuery($query);
$query = 'SELECT id FROM subnets
WHERE subnet = $subnet['subnet']
AND mask = $subnet['netmask'];'
$subnet_id = $database->getRow($query);
foreach ($subnets as $key => $subnet_check)
{
if (($subnet['subnet'] == $subnet_check['subnet']) AND ($subnet['netmask'] == $subnet_check['netmask']))
{
$ip_to_add = array_merge($ip_to_add,array(array("subnet_id" => $subnet_id[0], "ip" => $subnet['ip'], "name" => $subnet['name'])));
unset($subnets[$key]);
}
}
}
第一个foreach将添加每个子网并检索每个子网。 第二个foreach将扫描每个子网并尝试查找重复(包括其自身)。如果是这样,它应该将ip addresse信息添加到一个数组中,然后取消设置此元素,因为我们不想在另一个循环中重新插入子网。
然而,这似乎并没有正确设置它,因为最终,每个子网和IP地址都被插入(插入所有子网会带来很多重复)。
有人可以向我解释为什么unset无法正常工作?是因为我进入了一个2级的foreach?
谢谢。
答案 0 :(得分:1)
PHP中的foreach()语句秘密地制作数组的副本并迭代该副本。这没有任何性能影响因为它使用Copy-on-Write语义,所以如果你在foreach循环中写入数组,那么数组只能真正复制到内存中。你在这做什么所以你的两个循环实际上迭代了2个不同的$ subnets数组副本。当你从一个数组中取消设置时,这对另一个数组没有任何影响。
解决此问题的最简单方法是指示PHP不要复制。在两个循环中进行此更改:
foreach(array() as &$row) {}
或
foreach(array() as $key => &$row) {}
那就是说,我认为你的算法可以改进。 所以你正在做的事情是:
我的问题是,你想让$ ip_to_add最终看起来像什么?现在看来,如果有重复项,你只需要在表中插入一个但是$ ip_to_add会有重复的行吗?似乎$ ip_to_add将与原始$ subnets数组具有相同数量的项目?这就是你需要的吗?
如果没有,我会做的是: