Intereting Posts
разница между использованием сеанса через экземпляр HTTP-запроса и использованием глобального помощника сеанса в Laravel X-Frame-Options SAMEORIGIN блокирует iframe в моем домене php относительные URL-адреса для абсолютного преобразования URL-адресов с в конечном итоге базовым href html-тегом Получить путь изображения в PHP / SQLite Как построить расширение PHP, которое выполняется во многих версиях PHP? подготовленные заявления – создание единого метода * Yii addInCondition Laravel: Как мне вернуть маршрут маршрута с завершающими косыми чертами? Правильное выравнивание изображения PHPExcel Вызовы в шаблонах как вставить несколько полей в один столбец в codeigniter Документация PHP GraphViz Изменение фонового изображения исходного изображения PHP imagecopymerge прозрачно для черного Получить текущее местоположение пользователя в PHP Разработка API – как сделать его защищенным?

Есть ли функция, чтобы сделать копию массива 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 ++, но не совсем одинаковы. Если ваш массив содержит ссылки, тогда, когда сам массив передается копией, ссылки будут по-прежнему разрешаться исходной цели. Это, конечно, обычно желаемое поведение, но я думал, что это стоит упомянуть.

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)) ? call_user_func(__FUNCTION__, $element) : ((is_object($element)) ? clone $element : $element ) ); }, $array); } 

Когда вы это сделаете

 $array_x = $array_y; 

PHP копирует массив, поэтому я не уверен, как вы сожгли бы вас. Для вашего случая,

 global $foo; $foo = $obj->bar; 

должен работать нормально.

Чтобы сгореть, я думаю, вам придется либо использовать ссылки, либо ожидать, что объекты внутри массивов будут клонированы.

array_merge() – это функция, в которой вы можете скопировать один массив в другой в PHP.

Если в вашем массиве есть только базовые типы, вы можете сделать это:

 $copy = json_decode( json_encode($array), true); 

Вам не нужно обновлять ссылки вручную
Я знаю, что это не сработает для всех, но это сработало для меня

простой и делает глубокую копию всех ссылок

 $new=unserialize(serialize($old)); 

Поскольку это не было затронуто ни в одном из ответов и теперь доступно в PHP 5.3 (предполагается, что Original Post использует 5.2).

Чтобы поддерживать структуру массива и изменять его значения, я предпочитаю использовать array_replace или array_replace_recursive зависимости от моего array_replace_recursive использования.

http://php.net/manual/en/function.array-replace.php

Вот пример использования array_replace и array_replace_recursive демонстрирующий, что он способен поддерживать индексированный порядок и способен удалить ссылку.

http://ideone.com/SzlBUZ

Код ниже написан с использованием синтаксиса короткого массива, доступного с 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 ) 

Определите это:

 $copy = create_function('$a', 'return $a;'); 

Скопируйте $ _ARRAY в $ _ARRAY2:

 $_ARRAY2 = array_map($copy, $_ARRAY); 

Самый безопасный и дешевый способ, который я нашел, это:

 <?php $b = array_values($a); 

Это также имеет преимущество для переопределения массива.

Это не будет работать так, как ожидалось, в ассоциативном массиве (хеш), но не каждый из предыдущих ответов.

В 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; } } 
 <?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; } ?>