Czy istnieje funkcja umożliwiająca skopiowanie tablicy PHP do innej?
Zostałem spalony kilka razy, próbując skopiować tablice PHP. Chcę skopiować tablicę zdefiniowaną wewnątrz obiektu na globalny poza nim.
Czy istnieje funkcja umożliwiająca skopiowanie tablicy PHP do innej?
Zostałem spalony kilka razy, próbując skopiować tablice PHP. Chcę skopiować tablicę zdefiniowaną wewnątrz obiektu na globalny poza nim.
Odpowiedzi:
W PHP tablice są przypisywane przez kopiowanie, podczas gdy obiekty są przypisywane przez odniesienie. To znaczy że:
$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);
Przyniesie:
array(0) {
}
Natomiast:
$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);
Wydajność:
object(stdClass)#1 (1) {
["foo"]=>
int(42)
}
Możesz się pomylić z zawiłościami takimi jak ArrayObject
, który jest obiektem, który działa dokładnie jak tablica. Będąc obiektem ma jednak semantykę odniesienia.
Edycja: @AndrewLarsson podnosi punkt w komentarzach poniżej. PHP ma specjalną funkcję zwaną „referencjami”. Są one nieco podobne do wskaźników w językach takich jak C / C ++, ale nie do końca takie same. Jeśli tablica zawiera referencje, to podczas gdy sama tablica jest przekazywana przez kopię, referencje nadal będą rozstrzygane w pierwotnym celu. To zwykle pożądane zachowanie, ale pomyślałem, że warto o tym wspomnieć.
$copy = $original;
. Co nie działa, jeśli elementy tablicy są odwołaniami.
php
przedstawia nam najmniej oczekiwany wynik , ponieważ to rozwiązanie nie zawsze działa . $a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
drukuje array0
podczas $a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
drukowania array1
. Najwyraźniej niektóre tablice są kopiowane przez odniesienie.
PHP domyślnie skopiuje tablicę. Odnośniki w PHP muszą być jawne.
$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a
Jeśli masz tablicę zawierającą obiekty, musisz wykonać kopię tej tablicy bez dotykania jej wewnętrznego wskaźnika i potrzebujesz wszystkich obiektów do klonowania (aby nie modyfikować oryginałów podczas wprowadzania zmian w kopiowanym tablica), użyj tego.
Sztuką nie dotykania wewnętrznego wskaźnika tablicy jest upewnienie się, że pracujesz z kopią tablicy, a nie z oryginalną tablicą (lub odniesieniem do niej), więc użycie parametru funkcji wykona zadanie (a zatem jest to funkcja, która przyjmuje tablicę).
Pamiętaj, że nadal będziesz musiał zaimplementować __clone () na swoich obiektach, jeśli chcesz, aby ich właściwości również były klonowane.
Ta funkcja działa dla dowolnego typu tablicy (w tym typu mieszanego).
function array_clone($array) {
return array_map(function($element) {
return ((is_array($element))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
__FUNCTION__
jest genialne.
Kiedy to zrobisz
$array_x = $array_y;
PHP kopiuje tablicę, więc nie jestem pewien, jak zostałbyś spalony. W twoim przypadku
global $foo;
$foo = $obj->bar;
powinien działać dobrze.
Aby się poparzyć, pomyślałbym, że musiałbyś albo użyć referencji, albo oczekiwać, że obiekty wewnątrz tablic zostaną sklonowane.
array_merge()
to funkcja, w której możesz skopiować jedną tablicę do drugiej w PHP.
$a_c = array_combine(array_keys($a), array_values($a))
.
proste i sprawia, że głębokie kopiowanie przerywa wszystkie linki
$new=unserialize(serialize($old));
Lubię array_replace
(lub array_replace_recursive
).
$cloned = array_replace([], $YOUR_ARRAY);
Działa jak Object.assign
z JavaScript.
$original = [ 'foo' => 'bar', 'fiz' => 'baz' ];
$cloned = array_replace([], $original);
$clonedWithReassignment = array_replace([], $original, ['foo' => 'changed']);
$clonedWithNewValues = array_replace([], $original, ['add' => 'new']);
$original['new'] = 'val';
spowoduje
// original:
{"foo":"bar","fiz":"baz","new":"val"}
// cloned:
{"foo":"bar","fiz":"baz"}
// cloned with reassignment:
{"foo":"changed","fiz":"baz"}
// cloned with new values:
{"foo":"bar","fiz":"baz","add":"new"}
array_slice($arr, 0)
co z kluczami, kiedy nie zależy ci na nich array_values($arr)
? Myślę, że mogą być szybsze niż wyszukiwanie w tablicy. Ponadto w javascript jest dość popularne Array.slice()
do klonowania tablic.
array_slice
wszystkie pozostałe metody tutaj wymienione działają bardzo dobrze. Ale jeśli chcesz scalić kilka par klucz-wartość (jak jest to również możliwe w przypadku obiektów JS za pośrednictwem Object.assign
lub składni rozproszonej ), array_replace
może być bardziej przydatne.
array_values()
która działała idealnie w moim przypadku użycia.
Jeśli masz w tablicy tylko podstawowe typy, możesz to zrobić:
$copy = json_decode( json_encode($array), true);
Nie będziesz musiał ręcznie aktualizować referencji.
Wiem, że to nie będzie działać dla wszystkich, ale zadziałało dla mnie
Ponieważ nie zostało to uwzględnione w żadnej z odpowiedzi i jest teraz dostępne w PHP 5.3 (zakładając, że Original Post używa 5.2).
W celu utrzymania struktury tablicy i zmiany jej wartości wolę używać array_replace
lub w array_replace_recursive
zależności od mojego przypadku użycia.
http://php.net/manual/en/function.array-replace.php
Oto przykład użycia array_replace
i array_replace_recursive
wykazania, że jest w stanie utrzymać indeksowaną kolejność i może usunąć odwołanie.
Poniższy kod został napisany przy użyciu krótkiej składni tablicowej dostępnej od PHP 5.4, która zastępuje array()
się []
.
http://php.net/manual/en/language.types.array.php
Działa zarówno na tablicach indeksowanych offsetowo, jak i indeksowanych nazwach
$o1 = new stdClass;
$a = 'd';
//This is the base array or the initial structure
$o1->ar1 = ['a', 'b', ['ca', 'cb']];
$o1->ar1[3] = & $a; //set 3rd offset to reference $a
//direct copy (not passed by reference)
$o1->ar2 = $o1->ar1; //alternatively array_replace($o1->ar1, []);
$o1->ar1[0] = 'z'; //set offset 0 of ar1 = z do not change ar2
$o1->ar1[3] = 'e'; //$a = e (changes value of 3rd offset to e in ar1 and ar2)
//copy and remove reference to 3rd offset of ar1 and change 2nd offset to a new array
$o1->ar3 = array_replace($o1->ar1, [2 => ['aa'], 3 => 'd']);
//maintain original array of the 2nd offset in ar1 and change the value at offset 0
//also remove reference of the 2nd offset
//note: offset 3 and 2 are transposed
$o1->ar4 = array_replace_recursive($o1->ar1, [3 => 'f', 2 => ['bb']]);
var_dump($o1);
Wynik:
["ar1"]=>
array(4) {
[0]=>
string(1) "z"
[1]=>
string(1) "b"
[2]=>
array(2) {
[0]=>
string(2) "ca"
[1]=>
string(2) "cb"
}
[3]=>
&string(1) "e"
}
["ar2"]=>
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
array(2) {
[0]=>
string(2) "ca"
[1]=>
string(2) "cb"
}
[3]=>
&string(1) "e"
}
["ar3"]=>
array(4) {
[0]=>
string(1) "z"
[1]=>
string(1) "b"
[2]=>
array(1) {
[0]=>
string(2) "aa"
}
[3]=>
string(1) "d"
}
["ar4"]=>
array(4) {
[0]=>
string(1) "z"
[1]=>
string(1) "b"
[2]=>
array(2) {
[0]=>
string(2) "bb"
[1]=>
string(2) "cb"
}
[3]=>
string(1) "f"
}
Wiem to już dawno temu, ale to zadziałało dla mnie ..
$copied_array = array_slice($original_array,0,count($original_array));
W ten sposób kopiuję moje tablice w Php:
function equal_array($arr){
$ArrayObject = new ArrayObject($arr);
return $ArrayObject->getArrayCopy();
}
$test = array("aa","bb",3);
$test2 = equal_array($test);
print_r($test2);
To daje:
Array
(
[0] => aa
[1] => bb
[2] => 3
)
$test2 = $test;
? Jaki problem ArrayObject
tutaj rozwiązujesz?
Tworzy kopię obiektu ArrayObject
<?php
// Array of available fruits
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);
$fruitsArrayObject = new ArrayObject($fruits);
$fruitsArrayObject['pears'] = 4;
// create a copy of the array
$copy = $fruitsArrayObject->getArrayCopy();
print_r($copy);
?>
z https://www.php.net/manual/en/arrayobject.getarraycopy.php
Zdefiniuj to:
$copy = create_function('$a', 'return $a;');
Skopiuj $ _ARRAY do $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
W tablicy php wystarczy przypisać je do innej zmiennej, aby uzyskać kopię tej tablicy. Ale najpierw musisz upewnić się co do jego typu, niezależnie od tego, czy jest to tablica, czy obiekt tablicowy, czy obiekt stdObject.
Dla prostej tablicy php:
$a = array(
'data' => 10
);
$b = $a;
var_dump($b);
output:
array:1 [
"data" => 10
]
private function cloneObject($mixed)
{
switch (true) {
case is_object($mixed):
return clone $mixed;
case is_array($mixed):
return array_map(array($this, __FUNCTION__), $mixed);
default:
return $mixed;
}
}