4

各投稿のparentIdを設定する次のPHPコードがあります。各データのparentIdは全て最終投稿IDになります。私のロジックの何が問題になっていますか?

ところで、それを配列に変更すると、すべてがOKになります。助けてください!

$data = array(
    (object)array('name' => 'myname')
);
$posts = array(
    (object)array('ID' => 1, 'data'=>$data),
    (object)array('ID' => 2, 'data'=>$data),
    (object)array('ID' => 3, 'data'=>$data)
);
foreach($posts as &$post){
    $post->data[0]->parentId = $post->ID;
}
print '<pre>';print_r($posts);die;
die;

結果:

Array
(
    [0] => stdClass Object
        (
            [ID] => 1
            [data] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => myname
                            [parentId] => 3 // expect to be 1
                        )

                )

        )

    [1] => stdClass Object
        (
            [ID] => 2
            [data] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => myname
                            [parentId] => 3 // expect to be 2 !!!
                        )

                )

        )

    [2] => stdClass Object
        (
            [ID] => 3
            [data] => Array
                (
                    [0] => stdClass Object
                        (
                            [name] => myname
                            [parentId] => 3
                        )

                )

        )

)
4

2 に答える 2

5

すべてのことを考慮して、ここでの本当のdata問題は、コードをもう一度見た後、プロパティを設定する方法です。PHP5 以降、オブジェクトはデフォルトで参照によって受け渡されます。PHP4 時代を覚えていますか? ( $newInstance = &new SomeClass();)、PHP5 はオブジェクトの参照を使用するようになったため、次のようにします。

$data = array(
    (object)array('name' => 'myname')//create object
);

次に、3 つのオブジェクトすべてに同じオブジェクトが割り当てられます (参照によって! )。そのため、最初に変更すると、3 つのインスタンスすべてに同じ変更が反映されます。

私は最近、ここにループ内の参照に関する長い回答を投稿しました。参照によるループはビジネスを進めるための最良の方法ではないため、一見の価値があるかもしれません。

いくつかのコード レビュー:
これらすべての配列を作成して個別にオブジェクトにキャストする代わりに、次のようにします。

$data = array(
    array('name' => 'myname')
);
$posts = array(
    array('ID' => 1, 'data'=>$data),
    array('ID' => 2, 'data'=>$data),
    array('ID' => 3, 'data'=>$data)
);
foreach($posts as $k => $post)
{
    $posts[$k]['data'][0]['parentId'] = $posts[$k]['ID'];
}
$posts = json_decode(json_encode($posts));//turns everything into objects
print_r($posts);

json_encode最初は、何かに対して効率が悪いように見えるかもしれませんがjson_decodejson_decodeデフォルトでは連想配列ではなく、オブジェクトを返します。少し前にいくつかのテスト スクリプトを実行しましたが、結局のところ、エンコードとデコードのアプローチは、各連想配列をキャストするよりも実際には高速でした...

于 2013-08-29T07:35:09.583 に答える
3

さて、私はあなたの問題を誤解しました.データオブジェクトを再利用すると参照の問題が発生するため、これは以下に示すようにクローンを使用することで回避できます.

<?php

$data = (object) array('name' => 'myname');

$posts = array(
    (object) array('ID' => 1, 'data'=> array(clone $data)),
    (object) array('ID' => 2, 'data'=> array(clone $data)),
    (object) array('ID' => 3, 'data'=> array(clone $data))
);

foreach($posts as $postKey => $post){
    $posts[$postKey]->data[0]->parentId = $posts[$postKey]->ID;
}
print '<pre>';
print_r($posts); 
于 2013-08-29T07:34:28.703 に答える