PHP: check if object/array is a reference

后端 未结 5 1978

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

$users = array(
    array(
        \"name\" => \"John\",
        \"age\"   =         


        
相关标签:
5条回答
  • 2020-12-17 15:53
    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.

    0 讨论(0)
  • 2020-12-17 15:57

    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'].

    0 讨论(0)
  • 2020-12-17 15:58

    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

    0 讨论(0)
  • 2020-12-17 16:03

    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;
    }
    
    0 讨论(0)
  • 2020-12-17 16:04

    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] => ) 
    
    0 讨论(0)
提交回复
热议问题