değerine göre php kopyalama dizi elemanları, başvuruya göre değil

5 Cevap php

Ben aşağıdaki kodu vardır:

$data['x'] = $this->x->getResults();  

$data['y'] = $data['x'];

//some code here to modify $data['y']
//this causes (undesirably) $data['x] to be modified as well

I ['y'] $ verileri değiştirerek, $ veri tüm unsurları başvuruları kendilerini olduğundan sanırım ayrıca $ verileri değiştirir ['x'] .. ne istediğiniz değil ki. Ben aynı kalması $ veri ['x'] istiyorum. Ben değerine göre öğeleri kopyalamak böylece burada elemanları KQUEUE için herhangi bir yolu var mı?

Teşekkürler.

Güncelleme: $ this-> x-> getResults (); bir nesne dizisi döndürür. Ben o zaman gibi bir şey yapabilirsiniz: $ veri ['x'] [0] -> date_create ...

Update: my latest attempt to clone the array looks something like this:

   $data['x'] = $this->x->getResults();     
   $data['y'] = $data['y'];
   foreach($data['x'] as $key=>$row) {
       $data['y'][$key]->some_attr = clone $row->some_attr;
   }

Ben kapalı bir şekilde buradayım? Ben hata bir "non-nesne çağırdı __clone yöntemi" elde tutmak. Benim en iyi seçenek, her öğe üzerinde yineleme ve onu klonlamak gibi yanıtları okuma görünüyor (ben bu kod ile yapmaya çalışıyor ne olduğu ..).

UPDATE: Just münhal: foreach döngü içinde ben sadece hattını değiştirmek için gereken:

$data['y'][$key] = clone $row;

Ve bu işe yarıyor! Yardım için herkese teşekkürler.

5 Cevap

Sen aslında yararlanabilirsiniz PHP olacak bir işlev çağrısının sonuçları inceleyebilirsiniz.

İşte benim hazırladığım bazı örnek kod:

$x = 'x';
$y = 'y';
$arr = array(&$x,&$y);
print_r($arr);

echo "<br/>";
$arr2 = $arr;
$arr2[0] = 'zzz';
print_r($arr);
print_r($arr2);

echo "<br/>";
$arr2 = array_flip(array_flip($arr));
$arr2[0] = '123';
print_r($arr);
print_r($arr2);

Sonuçlar şöyle:

Array ( [0] => x [1] => y )
Array ( [0] => zzz [1] => y ) Array ( [0] => zzz [1] => y )
Array ( [0] => zzz [1] => y ) Array ( [0] => 123 [1] => y ) 

Bunu görebilmesi $arr $arr2 için sonraki değişiklikler farklılıklara $arr2 sonuçlarına en Atama esnasında array_flip() kullanılmasının sonuçları, gibi array_flip() bir çözümlemesi zorlar çağırır.

Bu korkunç verimli görünmüyor, ama $this->x->getResults() bir dizi dönen eğer sizin için işe yarayabilecek:

$data['x'] = array_flip(array_flip($this->x->getResults()));
$data['y'] = $data['x'];

this (unanswered) thread Başka bir örnek için bkz.

İade dizideki her şey ancak bir nesne ise, o zaman bir nesneyi kopyalamak için tek yol clone() kullanmak için, ve $data['x'] arasında yineleme var ve her bir elemanı klon olacak olan { [(2)]}.

Örnek:

$data['x'] = $this->x->getResults();
$data['y'] = array();
foreach($data['x'] as $key => $obj) {
    $data['y'][$key] = clone $obj;
}

array_flip() won't work when array values are not strings nor integers. I found a simple solution, however:

$clonedArr = (array)clone(object)$arr;

Bu, bir nesne üzerinde klonun özellikleri sayesinde çalışır.

Not simple. Read about clone

AMA! Lütfen elemanları not objects ve not refence type variables hiçbir sorun varsa.

Başvuru türleri için örnek:

$v=11;
$arr[]=&$v;

Nesnelerle çalışıyorsanız, bunun yerine bir reference in, clone , to create a copy bir nesnenin bakmak isteyebilirsiniz.

Burada çok kısa bir örnek:

İlk olarak, bir dizi, o değerin çalışır:

$data['x'] = array(
    'a' => 'test',
    'b' => 'glop',
);
$data['y'] = $data['x'];
$data['y'][0] = 'Hello, world!';
var_dump($data['x']); // a => test : no problem with arrays

Varsayılan olarak, nesneler ile, bu referans ile çalışır:

$data['x'] = (object)array(
    'a' => 'test',
    'b' => 'glop',
);
$data['y'] = $data['x'];
$data['y']->a = 'Hello, world!';
var_dump($data['x']); // a => Hello, world! : objects are by ref

But, if you clone the object, you work on a copy :
I guess this is your case ?

$data['x'] = (object)array(
    'a' => 'test',
    'b' => 'glop',
);
$data['y'] = clone $data['x'];
$data['y']->a = 'Hello, world!';
var_dump($data['x']); // a => test : no ref, because of cloning

Bu yardımcı olur umarım

Nesneleri içeren çok boyutlu diziler kopyalamak için bu işlevi kullanabilirsiniz.

<?php
function arrayCopy( array $array ) {
    $result = array();
    foreach( $array as $key => $val ) {
        if( is_array( $val ) ) {
            $result[$key] = arrayCopy( $val );
        } elseif ( is_object( $val ) ) {
            $result[$key] = clone $val;
        } else {
            $result[$key] = $val;
        }
    }
    return $result;
}
?>