มีฟังก์ชั่นในการทำสำเนาอาร์เรย์ PHP ไปยังอีกชุดหรือไม่?
ฉันถูกเขียนไปหลายครั้งพยายามคัดลอกอาร์เรย์ PHP ฉันต้องการคัดลอกอาร์เรย์ที่กำหนดไว้ภายในวัตถุไปยังโกลบอลด้านนอก
มีฟังก์ชั่นในการทำสำเนาอาร์เรย์ PHP ไปยังอีกชุดหรือไม่?
ฉันถูกเขียนไปหลายครั้งพยายามคัดลอกอาร์เรย์ PHP ฉันต้องการคัดลอกอาร์เรย์ที่กำหนดไว้ภายในวัตถุไปยังโกลบอลด้านนอก
คำตอบ:
ในอาร์เรย์ PHP ได้รับมอบหมายโดยการคัดลอกในขณะที่วัตถุได้รับมอบหมายโดยการอ้างอิง ซึ่งหมายความว่า:
$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);
จะให้ผล:
array(0) {
}
โดย:
$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);
อัตราผลตอบแทน:
object(stdClass)#1 (1) {
["foo"]=>
int(42)
}
คุณอาจสับสนกับความสลับซับซ้อนเช่นArrayObject
ซึ่งเป็นวัตถุที่ทำหน้าที่เหมือนกับอาเรย์ อย่างไรก็ตามในการเป็นวัตถุมันมีความหมายอ้างอิง
แก้ไข: @AndrewLarsson ยกประเด็นในความคิดเห็นด้านล่าง PHP มีคุณสมบัติพิเศษที่เรียกว่า "การอ้างอิง" พวกมันค่อนข้างคล้ายกับพอยน์เตอร์ในภาษาเช่น C / C ++ แต่ไม่เหมือนกัน หากอาเรย์ของคุณมีการอ้างอิงในขณะที่อาเรย์ของตัวเองถูกส่งผ่านโดยการคัดลอกการอ้างอิงจะยังคงแก้ไขไปยังเป้าหมายเดิม แน่นอนว่าเป็นพฤติกรรมที่ต้องการ แต่ฉันคิดว่ามันคุ้มค่าที่จะกล่าวถึง
$copy = $original;
. ซึ่งไม่ทำงานหากองค์ประกอบอาเรย์อ้างอิง
php
นำเสนอเรามีผลที่คาดหวังน้อยเพราะการแก้ปัญหานี้ไม่ได้เสมอไป $a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
พิมพ์array0
ขณะพิมพ์$a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];
array1
เห็นได้ชัดว่าบางอาร์เรย์จะถูกคัดลอกโดยอ้างอิง
PHP จะคัดลอกอาร์เรย์โดยค่าเริ่มต้น การอ้างอิงใน PHP ต้องมีความชัดเจน
$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a
หากคุณมีอาร์เรย์ที่มีวัตถุคุณต้องทำสำเนาของอาร์เรย์นั้นโดยไม่ต้องสัมผัสตัวชี้ภายในและคุณต้องการให้วัตถุทั้งหมดถูกโคลน (เพื่อที่ว่าคุณจะไม่แก้ไขต้นฉบับเมื่อคุณทำการเปลี่ยนแปลงคัดลอก อาร์เรย์) ใช้สิ่งนี้
เคล็ดลับที่จะไม่สัมผัสตัวชี้ภายในของอาเรย์คือการตรวจสอบให้แน่ใจว่าคุณกำลังทำงานกับสำเนาของอาเรย์และไม่ใช่อาเรย์ดั้งเดิม (หรือการอ้างอิงถึงอาเรย์) ดังนั้นการใช้พารามิเตอร์ฟังก์ชั่นจะทำให้งานเสร็จ นี่คือฟังก์ชั่นที่ใช้ในอาเรย์)
โปรดทราบว่าคุณยังต้องใช้__clone ()บนวัตถุของคุณหากคุณต้องการให้คุณสมบัติของพวกมันถูกโคลน
ฟังก์ชั่นนี้ใช้ได้กับอาเรย์ทุกประเภท (รวมถึงแบบผสม)
function array_clone($array) {
return array_map(function($element) {
return ((is_array($element))
? array_clone($element)
: ((is_object($element))
? clone $element
: $element
)
);
}, $array);
}
__FUNCTION__
นี้ยอดเยี่ยม
เมื่อคุณทำ
$array_x = $array_y;
PHP คัดลอกอาเรย์ดังนั้นฉันไม่แน่ใจว่าคุณจะเผาไหม้อย่างไร สำหรับกรณีของคุณ
global $foo;
$foo = $obj->bar;
ควรทำงานได้ดี
เพื่อที่จะได้เผาฉันจะคิดว่าคุณอาจต้องใช้การอ้างอิงหรือคาดหวังว่าวัตถุภายในอาร์เรย์จะถูกโคลน
array_merge()
เป็นฟังก์ชันที่คุณสามารถคัดลอกอาร์เรย์หนึ่งไปยังอีกใน PHP
$a_c = array_combine(array_keys($a), array_values($a))
สำหรับการรักษากุญแจ:
ง่ายและทำให้การคัดลอกลึกทำลายลิงค์ทั้งหมด
$new=unserialize(serialize($old));
ฉันชอบarray_replace
(หรือarray_replace_recursive
)
$cloned = array_replace([], $YOUR_ARRAY);
มันทำงานได้เหมือนObject.assign
จาก 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';
จะส่งผลให้
// 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)
เมื่อไหร่ที่คุณไม่ใส่ใจเรื่องกุญแจarray_values($arr)
? ฉันคิดว่าพวกเขาอาจเร็วกว่าการค้นหาในอาเรย์ นอกจากนี้ในจาวาสคริปต์ก็ค่อนข้างนิยมใช้Array.slice()
โคลนอาร์เรย์
array_slice
และวิธีการอื่น ๆ ที่กล่าวถึงในที่นี้ทำงานได้ดีมาก แต่ถ้าคุณต้องการผสานคู่ของคีย์ - ค่า - คู่ (เพราะมันเป็นไปได้กับ JS-Objects ผ่านObject.assign
หรือไวยากรณ์สเปรด ) array_replace
อาจมีประโยชน์มากกว่า
array_values()
ที่ทำงานได้อย่างสมบูรณ์แบบสำหรับกรณีการใช้งานของฉัน
หากคุณมีประเภทพื้นฐานเท่านั้นในอาเรย์ของคุณคุณสามารถทำได้:
$copy = json_decode( json_encode($array), true);
คุณไม่จำเป็นต้องอัปเดตข้อมูลอ้างอิงด้วยตนเอง
ฉันรู้ว่ามันจะไม่ทำงานสำหรับทุกคน แต่มันใช้งานได้สำหรับฉัน
เนื่องจากสิ่งนี้ไม่ได้ครอบคลุมในคำตอบใด ๆ และขณะนี้มีให้ใน PHP 5.3 (สันนิษฐานว่าโพสต์ต้นฉบับใช้ 5.2)
เพื่อรักษาโครงสร้างอาเรย์และเปลี่ยนค่าของมันฉันชอบที่จะใช้array_replace
หรือarray_replace_recursive
ขึ้นอยู่กับกรณีการใช้ของฉัน
http://php.net/manual/en/function.array-replace.php
นี่คือตัวอย่างการใช้array_replace
และการarray_replace_recursive
แสดงให้เห็นถึงความสามารถในการรักษาลำดับดัชนีและความสามารถในการลบการอ้างอิง
โค้ดข้างล่างนี้เขียนโดยใช้ไวยากรณ์อาร์เรย์สั้นมีตั้งแต่ PHP 5.4 ซึ่งแทนที่ด้วย
array()
http://php.net/manual/en/language.types.array.php[]
ใช้งานได้ทั้งอ็อฟเซ็ตดัชนีและออฟเซ็ตที่จัดทำดัชนีชื่อ
$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);
เอาท์พุท:
["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"
}
ฉันรู้เรื่องนี้เมื่อนานมาแล้ว แต่สิ่งนี้ได้ผลสำหรับฉัน ..
$copied_array = array_slice($original_array,0,count($original_array));
นี่คือวิธีที่ฉันกำลังคัดลอกอาร์เรย์ของฉันใน Php:
function equal_array($arr){
$ArrayObject = new ArrayObject($arr);
return $ArrayObject->getArrayCopy();
}
$test = array("aa","bb",3);
$test2 = equal_array($test);
print_r($test2);
ผลลัพธ์นี้:
Array
(
[0] => aa
[1] => bb
[2] => 3
)
$test2 = $test;
? มีปัญหาอะไรArrayObject
แก้ที่นี่?
<?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;
}
?>
วิธีที่ปลอดภัยที่สุดและถูกที่สุดที่ฉันพบคือ:
<?php
$b = array_values($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);
?>
จากhttps://www.php.net/manual/th/arrayobject.getarraycopy.php
กำหนดสิ่งนี้:
$copy = create_function('$a', 'return $a;');
คัดลอก $ _ARRAY ไปยัง $ _ARRAY2:
$_ARRAY2 = array_map($copy, $_ARRAY);
ในอาเรย์ของ php คุณต้องกำหนดให้ตัวแปรอื่น ๆ เพื่อรับสำเนาของอาเรย์นั้น แต่ก่อนอื่นคุณต้องตรวจสอบให้แน่ใจเกี่ยวกับประเภทของมันไม่ว่าจะเป็นอาร์เรย์หรือ arrayObject หรือ stdObject
สำหรับอาร์เรย์ 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;
}
}
$arr_one_copy = array_combine(array_keys($arr_one), $arr_one);
เพียงโพสต์อีกหนึ่งโซลูชัน;)
foreach($a as $key => $val) $b[$key] = $val ;
รักษาทั้งคีย์และค่า Array 'a' เป็นสำเนาที่แน่นอนของอาร์เรย์ 'b'