PHP:检查对象/数组是否是引用

发布于 2024-09-07 19:17:56 字数 675 浏览 5 评论 0原文

很抱歉问,已经晚了,我想不出办法......有人可以帮忙吗?

$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]);
}

主要目标是复制数组而不使用任何引用。

这可能吗?

谢谢。

Sorry to ask, its late and I can't figure a way to do it... anyone can help?

$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 shows:

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

Which means "users" is a reference.

I would like to do something like this:

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

The main goal is to copy the array WITHOUT any references.

Is that possible?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

少女的英雄梦 2024-09-14 19:17:56

您可以通过制作数组的副本,然后依次更改和测试每个条目来测试多维数组中的引用:

$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'] 和 < code>$roomCopy['furniture'] 将是单独的数组(因为 $roomCopy$room 的副本),因此向其中添加一个新键不会影响对方。但是, $room['users']$roomCopy['users'] 将引用同一个 $users 数组(因为它是复制的引用,而不是数组),因此当我们向 $roomCopy['users'] 添加键时,它在 $room['users'] 中可见。

You can test for references in a multi-dimensional array by making a copy of the array, and then altering and testing each entry in turn:

$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);

With your example data, $room['furniture'] and $roomCopy['furniture'] will be separate arrays (as $roomCopy is a copy of $room), so adding a new key to one won't affect the other. But, $room['users'] and $roomCopy['users'] will be references to the same $users array (as it's the reference that's copied, not the array), so when we add a key to $roomCopy['users'] it is visible in $room['users'].

你的呼吸 2024-09-14 19:17:56

我能管理的最好方法是测试两个变量,以确定一个变量是否是对另一个变量的引用:

$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));

要在代码中使用最后一个方法,你' d 需要做类似的事情:

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

因为 $val 从来都不是引用,因为它是原始数组元素的副本;并使用 &$val 使其始终成为引用

The best I can manage is a test of two variables to determine if one is a reference to the other:

$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);

but I doubt if it's much help

Really dirty method (not well tested either):

$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));

To use this last method in your code, you'd need to do something like:

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

because $val is never a reference as it's a copy of the original array element; and using &$val makes it always a reference

删除→记忆 2024-09-14 19:17:56

也许是递归的东西。

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

something recursive maybe.

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;
}
时光暖心i 2024-09-14 19:17:56
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 对象和数组。

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;
}
//-------------------------------------------------------------------------------------------

This works with HUDGE objects and arrays.

笑脸一如从前 2024-09-14 19:17:56

如果你想摆脱递归元素:

<?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] => ) 

if you want to get rid of recursive elements:

<?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);
?>

output:

stdClass Object ( [a] => 3 [b] => stdClass Object *RECURSION* ) 
stdClass Object ( [a] => 3 [b] => ) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文