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 resu开发者_运维知识库lt) 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.
精彩评论