0

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 は、すべてのサブネットを追加し、それぞれの ID を取得します。2 番目の foreach は、すべてのサブネットをスキャンし、重複 (それ自体を含む) を見つけようとします。存在する場合は、IP アドレス情報を配列に追加してから、別のループにサブネットを再挿入したくないため、この要素の設定を解除する必要があります。

ただし、最終的にすべてのサブネットと IP アドレスが挿入されるため、これは正しく設定解除されていないようです (すべてのサブネットを挿入すると、多くの重複が発生します)。

設定解除が正しく機能しない理由を誰かに説明してもらえますか? 私が2レベルのforeachに夢中だからですか?

ありがとうございました。

4

1 に答える 1

1

PHP の foreach() ステートメントは、密かに配列のコピーを作成し、そのコピーを繰り返します。これは、コピー オン ライト セマンティクスを使用するため、パフォーマンスへの影響はありません。したがって、foreach ループ内で配列に書き込む場合にのみ、配列が実際にメモリにコピーされます。あなたがここでしていること。したがって、2 つのループは、実際には $subnets 配列の 2 つの異なるコピーを反復しています。1 つの配列から設定を解除しても、他の配列には影響しません。

これを修正する最も簡単な方法は、コピーを作成しないように PHP に指示することです。両方のループで次の変更を行います。

foreach(array() as &$row) {} 

また

foreach(array() as $key => &$row) {}

そうは言っても、ここでのアルゴリズムは改善できると思います。だから、あなたがしているように見えるのは次のとおりです。

  1. 各サブネットを繰り返す
  2. 入れる
  3. 挿入された行の ID のクエリ
  4. 配列を繰り返し、ID を含むアイテムを $ip_to_add に追加します。

私の質問は、最終的に $ip_to_add をどのように見せたいですか? 現在、重複がある場合、テーブルへの挿入は 1 つだけですが、$ip_to_add には重複した行が含まれますか? $ip_to_add には、元の $subnets 配列と同じ数の項目があるように見えますか? それはあなたが必要とするものですか?

そうでない場合、私がすることは次のとおりです。

  1. アレイの重複除外
  2. それを繰り返し、挿入し、mysql_insert_id()を使用して ID を取得し、それを配列に追加します。
于 2013-06-28T22:51:14.013 に答える