简体   繁体   中英

PHP: Removing object by reference from associative array

I've got a recursive function searching an object by index in a multidimensional, associative array.

$settings = array(
'title' => new XCPreferenceShortText('title'),
'html' => new XCPreferenceLongText('html'),
'_blog' => array(
    '_blog' => new XCPreferenceHeading('blog'),
    'acceptcomments' => new XCPreferenceBoolean('acceptcomments'),
    'per_page' => new XCPreferenceNumberSet('per_page')
),
'_publishing' => array(
    '_publishing' => new XCPreferenceHeading('publishing'),
    'published' => new XCPreferenceBoolean('published'),
    'publishon' => new XCPreferenceDate('publishon'),
)
);

The code traverses the array and whenever is_array($value) returns true, it recurses the whole thing.

function &find($idx, $pref_array = false) {

    if ($pref_array === false)
        $pref_array = &$this->preferences;

    foreach ($pref_array as $key => $data) {
        if (is_array($data)) {
            $res = $this->find($idx, $data);
            if ($res !== false)
                return $res;
        }
        else if ($key == $idx)
            return $pref_array[$idx];
    }

    return false;
}

This function finds (and returns a reference to the result) an object associated to a given key – but when I store the return value / reference in a variable and set that var to null, this has no effect on the actual element in the "original" array.

You have to call the function like this:

$value = &find($idx);
$value = null;
//just to be safe, in case you re-use $value later on
unset($value);

Saying the function returns by reference is insufficient to create a store a reference on calling.

By the way, you should be aware an iterator called RecursiveArrayIterator exists.

I improved the function call as Artefacto suggested – but the function still didn't return a reference for elements retrieved by recursion only.

The mistake was, in this case, the recursion call itself. Below you will find an adjusted version which works for me:

foreach ($pref_array as $key => $data) {
        if (is_array($data)) {
            $res = &$this->find($idx, &$pref_array[$key]);
            if ($res !== false)
                return $res;
        }
        else if ($key == $idx) {
            return $pref_array[$idx];
        }
    }

Calling &$this->find($idx, $data); before was wrong as $data actually was no reference. In order to get a reference to the array I just had to fetch the array from the referenced variable ( $pref_array ).

Thanks a lot guys.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM