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_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)
?配列で検索するよりも高速かもしれません。また、JavaScriptでは、Array.slice()
配列の複製に使用するのが一般的です。
array_slice
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"
}
これは私が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
ここでどのような問題を解決していますか?
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/en/arrayobject.getarraycopy.phpから
これを定義します。
$copy = create_function('$a', 'return $a;');
$ _ARRAYを$ _ARRAY2にコピーします。
$_ARRAY2 = array_map($copy, $_ARRAY);
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;
}
}