Reference detection in array from another function

arrays, loops, php, reference

Solution

Introduction

I think a better approach would be to create a copy of the array and compare modification rather than use global pin and it can still be a `100% Recursive`

Example 1

This is from your example above :

$array = array(1,2,3);
$array[4] = &$array;
wrap($array);

Output

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [4] => ref
)

Example 2

Are we really sure its detecting reference or just a copy of the array

//Case 1 : Expect no modification
$array = array(1, 2, 3, array(1, 2, 3));
wrap( $array);

//Case 2 : Expect Modification in Key 2
$array = array(1, 2, 3, array(1, 2, 3));
$array[2] = &$array;
wrap( $array);

Output

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)
Array
(
    [0] => 1
    [1] => 2
    [2] => ref
    [3] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

)

Example 3

Is this really recursive ?

$array = array(1, 2, 3, array(1, 2, 3));
$array[4][4][2][6][1] = array(1,2,3=>&$array);
wrap( $array);

Output

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [4] => Array
        (
            [4] => Array
                (
                    [2] => Array
                        (
                            [6] => Array
                                (
                                    [1] => Array
                                        (
                                            [0] => 1
                                            [1] => 2
                                            [3] => ref   <-- GOT YOU
                                        )

                                )

                        )

                )

        )

)

Your Modified Function

/**
 * Added printf since test now returns array
 * @param array $arr
 */
function wrap(array $arr) {
    printf("<pre>%s<pre>", print_r(test($arr), true));
}


/**
 * - Removed Top Refrence
 * - Removed Global
 * - Add Recursion
 * - Returns array
 * @param array $arr
 * @return array
 */
function test(array $arr) {
    $temp = $arr;
    foreach ( $arr as $key => &$v ) {
        if (is_array($v)) {
            $temp[$key]['_PIN_'] = true;
            $v = isset($arr[$key]['_PIN_']) ? "ref" : test($v);
        }
    }
    unset($temp); // cleanup
    return $arr;
}

Problem

So I'm using the pin method, but the reference is detected one level too late: ``` $pin = time(); function wrap($arr){ test($arr); } function test(&$arr){ global $pin; if(in_array($pin, $arr)) return print "ref"; $arr[] = $pin; foreach($arr as &$v){ if($v != $pin){ if(is_array($v)) return test($v); print $v . " "; } } } $array = array(1, 2, 3); $array[4] = &$array; wrap($array); ``` I get `1 2 3 1 2 3 rec` But I expect `1 2 3 rec` If I just do `test($arr)` then it works, but the problem is that I need to wrap the test function inside another one that accepts values not references :( Is there any way I can detect the reference at the right moment with my wrapper function too?

Original source