views:

155

answers:

3

So I have this function, and it returns me a reference to a particular point to the array passed in. I want to make a call to unset that will then remove the result from the array/reference, but calling unset only removes the reference, not the data from the original array. Any thoughts?

+1  A: 

Setting the reference to null will destroy the data that the reference (and any other reference) is linked to.

See Unsetting References in the manual for more on this. Basically you want to do the following (taken from the comments):

$a = 1;
$b =& $a;
$c =& $b;  //$a, $b, $c reference the same content '1'

$b = null; //All variables $a, $b or $c are unset

In your case, it'll look something like this:

$a =& getArrayReference($whatever);
$a = null;

EDIT

To clear up any misconceptions, here's what you get when you unset array references:

$arr = array('x','y','z');

$x =& $arr[1];
unset($x);
print_r($arr);
//gives Array ( [0] => x [1] => y [2] => z )

$x =& $arr[1];
$x = null;
print_r($arr);
//gives Array ( [0] => x [1] => [2] => z ) 

Notice how the second array index does not have it's content deleted in the first example with unset(), but the second example of setting the reference to null accomplishes this.

Note: If you need to unset the array index as well, which I'm a bit unclear on as to whether you do or not, then you'll need to find a way to reference the key of the array instead of the value, likely by altering the return value of your function.

zombat
That is not true. This will just set $a, $b and $c to "null". Consider this: <?php $a = array('foo', 'bar'); $b = $b = null; var_dump($a);There would still be two values in the array $a;
runish
@runish: That's what the original poster is trying to accomplish - the destruction of the referenced content. Your example is wrong however. There would still be two array indexes, but the data will be gone.
zombat
Only that the content is not destroyed, it is just nullified.
runish
Nullification is the same as destruction in terms of getting it out of memory. I clarified my answer a bit, as I'm unclear as to whether the poster requires that the array index itself be removed, or just the array value.
zombat
thanks for the thoughts guys. (1) i don't want it JUST nullified. i want it removed entirely from the array. is that the only solution?
onassar
A: 

Note that the behavior of unset on references is by design. You could instead return the index of the element to remove, or an array of indices if the array isn't flat.

For example, you could use the following function:

function delItem(&$array, $indices) {
    $tmp =& $array;
    for ($i=0; $i < count($indices)-1; ++$i) {
        $key = $indices[$i];
        if (isset($tmp[$key])) {
            $tmp =& $tmp[$key];
        } else {
            return array_slice($indices, 0, $i+1);
        }
    }
    unset($tmp[$indices[$i]]);
    return False;
}

Or, if you prefer exceptions,

function delItem(&$array, $indices) {
    $tmp =& $array;
    while (count($indices) > 1) {
        $i = array_shift($indices);
        if (isset($tmp[$i])) {
            $tmp =& $tmp[$i];
        } else {
            throw new RangeException("Index '$i' doesn't exist in array.");
        }
    }
    unset($tmp[$indices[0]]);
}
outis
if i get back an array of indexes (where the size of the array of indexes is n) how do i access the value to unset it?
onassar
A: 

It is expected behavior that unsetting a reference does not unset the variable being referenced. One solution is to return the key instead of the value, and using that to unset the original value.

runish