static void php_array_replace_recursive(PointerSet &seen, bool check, Array &arr1, CArrRef arr2) { if (check) { if (seen.find((void*)arr1.get()) != seen.end()) { raise_warning("array_replace_recursive(): recursion detected"); return; } seen.insert((void*)arr1.get()); } for (ArrayIter iter(arr2); iter; ++iter) { Variant key = iter.first(); CVarRef value = iter.secondRef(); if (arr1.exists(key, true) && value.isArray()) { Variant &v = arr1.lvalAt(key, AccessFlags::Key); if (v.isArray()) { Array subarr1 = v.toArray(); const ArrNR& arr_value = value.toArrNR(); php_array_replace_recursive(seen, v.isReferenced(), subarr1, arr_value); v = subarr1; } else { arr1.set(key, value, true); } } else { arr1.lvalAt(key, AccessFlags::Key).setWithRef(value); } } if (check) { seen.erase((void*)arr1.get()); } }
static void php_array_merge_recursive(PointerSet &seen, bool check, Array &arr1, CArrRef arr2) { if (check) { if (seen.find((void*)arr1.get()) != seen.end()) { raise_warning("array_merge_recursive(): recursion detected"); return; } seen.insert((void*)arr1.get()); } for (ArrayIter iter(arr2); iter; ++iter) { Variant key(iter.first()); CVarRef value(iter.secondRef()); if (key.isNumeric()) { arr1.appendWithRef(value); } else if (arr1.exists(key, true)) { // There is no need to do toKey() conversion, for a key that is already // in the array. Variant &v = arr1.lvalAt(key, AccessFlags::Key); Array subarr1(v.toArray()->copy()); php_array_merge_recursive(seen, v.isReferenced(), subarr1, value.toArray()); v.unset(); // avoid contamination of the value that was strongly bound v = subarr1; } else { arr1.addLval(key, true).setWithRef(value); } } if (check) { seen.erase((void*)arr1.get()); } }