Intereting Posts
regex для URL-адреса и изображения в тексте или html Сохранять клики внутри файла .txt / .php на сервере Как получить доступ к контейнеру службы в глобальной вспомогательной функции symfony2 (услуге)? Переменные сеанса PHP не передаются на следующую страницу URL Rewrite / Mod Rewrite .htaccess на Apache и PHP Зачем использовать mysql_real_escape_string, не помешает ли все это предотвратить? Удалить определенные элементы из XML с помощью PHP Удалите поле проверки, если товары корзины относятся к определенным категориям товаров Статические методы или нет? PHP – Как объединить массивы внутри массива Внутренняя ошибка произошла во время: «PHP CodeSniffer». в zend studio 10.0 Повторяющиеся события в «nth» будни каждого месяца Symfony2: обратный Uri (Referrer) во время переключения локали Сериализованное отражение PHP PHP-REGEX: акцентированные буквы соответствуют неактивным, и наоборот. Как достичь этого?

PHP: проверьте, является ли объект / массив ссылкой

Извините, что попросил, его поздно, и я не могу понять, как это сделать … любой может помочь?

$users = array( array( "name" => "John", "age" => "20" ), array( "name" => "Betty", "age" => "22" ) ); $room = array( "furniture" => array("table","bed","chair"), "objects" => array("tv","radio","book","lamp"), "users" => &$users ); 

var_dump $ room показывает:

 ... 'users' => & ... 

Это означает, что «пользователи» являются ссылкой.

Я хотел бы сделать что-то вроде этого:

 foreach($room as $key => $val) { if(is_reference($val)) unset($room[$key]); } 

Основная цель – скопировать массив без каких-либо ссылок.

Это возможно?

Спасибо.

Вы можете проверить ссылки в многомерном массиве, сделав копию массива, а затем изменив и протестировав каждую запись по очереди:

 $roomCopy = $room; foreach ($room as $key => $val) { $roomCopy[$key]['_test'] = true; if (isset($room[$key]['_test'])) { // It's a reference unset($room[$key]); } } unset($roomCopy); с $roomCopy = $room; foreach ($room as $key => $val) { $roomCopy[$key]['_test'] = true; if (isset($room[$key]['_test'])) { // It's a reference unset($room[$key]); } } unset($roomCopy); 

С вашими данными примера $room['furniture'] и $roomCopy['furniture'] будут отдельными массивами (поскольку $roomCopy – это копия $room ), поэтому добавление нового ключа к одному не повлияет на другое. Но $room['users'] и $roomCopy['users'] будут ссылаться на один и тот же массив $users (так как это скопированная ссылка, а не массив), поэтому, когда мы добавляем ключ в $roomCopy['users'] это видно в $room['users'] .

Лучшее, что я могу сделать, это тест двух переменных, чтобы определить, является ли ссылка ссылкой на другую:

 $x = "something"; $y = &$x; $z = "something else"; function testReference(&$xVal,&$yVal) { $temp = $xVal; $xVal = "I am a reference"; if ($yVal == "I am a reference") { echo "is reference<br />"; } else { echo "is not reference<br />"; } $xVal = $temp; } testReference($x,$y); testReference($y,$x); testReference($x,$z); testReference($z,$x); testReference($y,$z); testReference($z,$y); 

но я сомневаюсь, что это очень помогает

Действительно грязный метод (не очень хорошо протестирован):

 $x = "something"; $y = &$x; $z = "something else"; function isReference(&$xVal) { ob_start(); debug_zval_dump(&$xVal); $dump = ob_get_clean(); preg_match('/refcount\((\d*)\)/',$dump,$matches); if ($matches[1] > 4) { return true; } else { return false; } } var_dump(isReference($x)); var_dump(isReference($y)); var_dump(isReference($z)); 

Чтобы использовать этот последний метод в коде, вам нужно сделать что-то вроде:

 foreach($room as $key => $val) { if(isReference($room[$key])) unset($room[$key]); } 

потому что $ val никогда не является ссылкой, поскольку это копия исходного элемента массива; и использование & $ val всегда делает ссылку

возможно, что-то рекурсивное.

 function removeReferences($inbound) { foreach($inbound as $key => $context) { if(is_array($context)) { $inbound[$key] = removeReferences($context) }elseif(is_object($context) && is_reference($context)) { unset($inbound[$key]); //Remove the entity from the array. } } return $inbound; } с function removeReferences($inbound) { foreach($inbound as $key => $context) { if(is_array($context)) { $inbound[$key] = removeReferences($context) }elseif(is_object($context) && is_reference($context)) { unset($inbound[$key]); //Remove the entity from the array. } } return $inbound; } 
 function var_reference_count(&$xVal) { $ao = is_array($xVal)||is_object($xVal); if($ao) { $temp= $xVal; $xVal=array(); } ob_start(); debug_zval_dump(&$xVal); $dump = ob_get_clean(); if($ao) $xVal=$temp; preg_match('/refcount\((\d*)\)/',$dump,$matches); return $matches[1] - 3; } //------------------------------------------------------------------------------------------- 

Это работает с объектами и массивами HUDGE.

если вы хотите избавиться от рекурсивных элементов:

 <?php $arr=(object)(NULL); $arr->a=3; $arr->b=&$arr; //$arr=array('a'=>3, 'b'=>&$arr); print_r($arr); $arr_clean=eval('return '.strtr(var_export($arr, true), array('stdClass::__set_state'=>'(object)')).';'); print_r($arr_clean); ?> 

вывод:

 stdClass Object ( [a] => 3 [b] => stdClass Object *RECURSION* ) stdClass Object ( [a] => 3 [b] => )