0

良い一日。どういうわけか次のような問題に直面しました:ループ内でリセットされて補充される変数があります。その変数をプロパティとして他の変数に割り当てます($ item-> subitemsのように)。たとえば、$item を $items の配列に収集した後。この変数はループごとに再設定および再入力され、異なるデータが含まれます。おおよそのサンプル コードは次のとおりです。

<?php
$seasons = array(1,2);
$ltabs= array(1);
$all = array(1,2,3,4,5,6,7,8,9,0);
        foreach ($ltabs as $tab)
        {
            //Resetting an object instance
            $itm=false;
            //Re-Initing object
            if (1==1)
            {
                $itm->height = 1;
                $itm->width  = 2;
            }
            else
            {
                $itm->height = 3;
                $itm->width  = 4;
            }
            //And thats where crap happens
            //foreach($seasons as $season) //Dont work that way too
            for ($y=0;$y<count($seasons);$y++)
            {
                //Re-initing local array for needed values
                $itemz=array();
                //$itm->items = array();
                for($a=0;$a < count($all);$a++) {
                    if ($all[$a] % $seasons)//Not tested, supposed to gove ANY dofference in arrays. 
                    {
                        $itemz[]=$all[$a];
                    }
                 }
                $itm->items = $itemz;
                $rtabs[$season] = $itm;
                unset($itemz);
                //unset($itemz);
            }
        }
        //Returns crap.
        var_dump($rtabs);
?>

しかし、しようとすると

<?php
foreach($rtabs as $itm)
{
    var_dump($itm->items);
}
?>  

これらすべてのサブアイテムに同じデータ セットが含まれていることがわかります。このサブループで $itm 変数全体を再割り当てするだけで、それを無効にすることに成功しました。しかし、私は理解したいと思います-なぜそれはそのように動作するのですか?..この記事によると-ガベージコレクターとphpのコピーオンライトは、この$itemz配列をリセットしたときに初期化する必要があります。非常に非論理的に見えます。どんな助けでも大歓迎です。

4

1 に答える 1

2

PHP では、オブジェクトは参照によってコピーされるため、次の行で:

$rtabs[$season] = $itm;

$itmオブジェクトのコピーを配列に配置するのではなく、オブジェクトへの参照をコピーしています。rtabs後で元のオブジェクトを変更すると、配列内のバージョンも変更されます。

別のコピーを作成する場合は、次のようにする必要があります。

$rtabs[$season] = clone $itm;
于 2013-05-12T00:14:53.567 に答える