Có một chức năng để tạo một bản sao của một mảng PHP sang một mảng khác không?
Tôi đã bị đốt cháy một vài lần khi cố gắng sao chép mảng PHP. Tôi muốn sao chép một mảng được xác định bên trong một đối tượng ra toàn cầu bên ngoài nó.
Có một chức năng để tạo một bản sao của một mảng PHP sang một mảng khác không?
Tôi đã bị đốt cháy một vài lần khi cố gắng sao chép mảng PHP. Tôi muốn sao chép một mảng được xác định bên trong một đối tượng ra toàn cầu bên ngoài nó.
Câu trả lời:
Trong mảng PHP được gán bởi bản sao, trong khi các đối tượng được gán bởi tham chiếu. Điều này có nghĩa rằng:
$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);
Sẽ mang lại:
array(0) {
}
Trong khi:
$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);
Sản lượng:
object(stdClass)#1 (1) {
["foo"]=>
int(42)
}
Bạn có thể bị lẫn lộn bởi những điều phức tạp như ArrayObject
, đó là một đối tượng hoạt động chính xác như một mảng. Là một đối tượng, tuy nhiên, nó có ngữ nghĩa tham khảo.
Chỉnh sửa: @AndrewLarsson nêu lên một điểm trong các bình luận bên dưới. PHP có một tính năng đặc biệt gọi là "tài liệu tham khảo". Chúng có phần giống với con trỏ trong các ngôn ngữ như C / C ++, nhưng không hoàn toàn giống nhau. Nếu mảng của bạn chứa các tham chiếu, thì trong khi bản thân mảng được truyền bằng bản sao, các tham chiếu vẫn sẽ phân giải đến đích ban đầu. Tất nhiên đó thường là hành vi mong muốn, nhưng tôi nghĩ nó đáng được đề cập.
$copy = $original;
. Mà không hoạt động nếu các phần tử mảng là tài liệu tham khảo.
php
trình bày cho chúng tôi kết quả ít mong đợi nhất , bởi vì giải pháp này không phải lúc nào cũng hoạt động . $a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
in array0
trong khi $a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
in array1
. Rõ ràng một số mảng được sao chép bằng cách tham khảo.
PHP sẽ sao chép mảng theo mặc định. Tài liệu tham khảo trong PHP phải rõ ràng.
$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a
Nếu bạn có một mảng chứa các đối tượng, bạn cần tạo một bản sao của mảng đó mà không chạm vào con trỏ bên trong của nó và bạn cần tất cả các đối tượng được sao chép (để bạn không sửa đổi bản gốc khi bạn thay đổi bản sao mảng), sử dụng này.
Mẹo để không chạm vào con trỏ bên trong của mảng là đảm bảo bạn đang làm việc với một bản sao của mảng chứ không phải mảng ban đầu (hoặc tham chiếu đến nó), do đó, sử dụng tham số hàm sẽ hoàn thành công việc (do đó, đây là một hàm có trong một mảng).
Lưu ý rằng bạn vẫn sẽ cần triển khai __clone () trên các đối tượng của mình nếu bạn muốn các thuộc tính của chúng cũng được sao chép.
Hàm này hoạt động cho bất kỳ loại mảng nào (bao gồm cả loại hỗn hợp).
function array_clone($array) {
return array_map(function($element) {
return ((is_array($element))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
__FUNCTION__
này là tuyệt vời.
Khi bạn làm
$array_x = $array_y;
PHP sao chép mảng, vì vậy tôi không chắc bạn sẽ bị đốt cháy như thế nào. Đối với trường hợp của bạn,
global $foo;
$foo = $obj->bar;
nên làm việc tốt
Để bị đốt cháy, tôi nghĩ bạn sẽ phải sử dụng các tài liệu tham khảo hoặc mong muốn các đối tượng bên trong các mảng được nhân bản.
array_merge()
là một hàm trong đó bạn có thể sao chép một mảng sang mảng khác trong PHP.
$a_c = array_combine(array_keys($a), array_values($a))
.
đơn giản và làm cho bản sao sâu phá vỡ tất cả các liên kết
$new=unserialize(serialize($old));
Tôi thích array_replace
(hoặc array_replace_recursive
).
$cloned = array_replace([], $YOUR_ARRAY);
Nó hoạt động như Object.assign
từ 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';
sẽ cho kết quả
// 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)
hoặc khi bạn không quan tâm đến chìa khóa , array_values($arr)
? Tôi nghĩ rằng họ có thể nhanh hơn tìm kiếm trong một mảng. Ngoài ra, trong javascript, nó khá phổ biến để sử dụng Array.slice()
để sao chép mảng.
array_slice
và tất cả các phương thức khác được đề cập ở đây hoạt động rất tốt. Nhưng nếu bạn muốn hợp nhất một số cặp khóa-giá trị (vì nó cũng có thể với các Đối tượng JS thông qua Object.assign
hoặc cú pháp trải rộng ), array_replace
có thể hữu ích hơn.
array_values()
đó hoạt động hoàn hảo cho trường hợp sử dụng của tôi.
Nếu bạn chỉ có các loại cơ bản trong mảng của mình, bạn có thể làm điều này:
$copy = json_decode( json_encode($array), true);
Bạn sẽ không cần cập nhật các tài liệu tham khảo theo cách thủ công
Tôi biết nó sẽ không hiệu quả với tất cả mọi người, nhưng nó hiệu quả với tôi
Vì điều này không được đề cập trong bất kỳ câu trả lời nào và hiện có sẵn trong PHP 5.3 (giả sử Bài gốc được sử dụng 5.2).
Để duy trì cấu trúc mảng và thay đổi giá trị của nó, tôi thích sử dụng array_replace
hoặc array_replace_recursive
tùy thuộc vào trường hợp sử dụng của tôi.
http://php.net/manual/en/feft.array-replace.php
Dưới đây là một ví dụ sử dụng array_replace
và array_replace_recursive
chứng minh rằng nó có thể duy trì thứ tự được lập chỉ mục và có khả năng xóa tham chiếu.
Mã dưới đây được viết bằng cú pháp mảng ngắn có sẵn kể từ PHP 5.4 thay thế array()
bằng []
.
http://php.net/manual/en/lingu.types.array.php
Hoạt động trên các mảng được lập chỉ mục và tên được bù
$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);
Đầu ra:
["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"
}
Tôi biết điều này từ lâu, nhưng điều này làm việc cho tôi ..
$copied_array = array_slice($original_array,0,count($original_array));
Đây là cách tôi sao chép mảng của mình trong Php:
function equal_array($arr){
$ArrayObject = new ArrayObject($arr);
return $ArrayObject->getArrayCopy();
}
$test = array("aa","bb",3);
$test2 = equal_array($test);
print_r($test2);
Kết quả này:
Array
(
[0] => aa
[1] => bb
[2] => 3
)
$test2 = $test;
? Vấn đề gì đang ArrayObject
giải quyết ở đây?
Tạo một bản sao của 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);
?>
từ https://www.php.net/manual/en/arrayobject.getarraycopy.php
Xác định điều này:
$copy = create_function('$a', 'return $a;');
Sao chép $ _ARRAY sang $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
Trong mảng php, bạn chỉ cần gán chúng cho biến khác để lấy bản sao của mảng đó. Nhưng trước tiên, bạn cần chắc chắn về kiểu của nó, cho dù đó là mảng hay mảngObject hay stdObject.
Đối với mảng php đơn giản:
$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;
}
}