First, this won't work - $value isn't bound to the source value array (To do this use "foreach ($array as $key => &$value)" and note the ampersand which causes the value to be passed by reference). Second, if you did receive the $value by reference, deleting a value on an object or array under iteration can cause undefined behavior by PHP.

First, this won't work - $value isn't bound to the source value array (To do this use "foreach ($array as $key => &$value)" and note the ampersand which causes the value to be passed by reference).

LOOK CLOSER. He's calling $tt (the parent) by key for the unset, NOT $value. As such you don't have to pull $value by reference! Not sure where you were going with that, but... no, you're WAY off the money there.

Michael_Morris said:

Second, if you did receive the $value by reference, deleting a value on an object or array under iteration can cause undefined behavior by PHP.

unset inside foreach works just fine. First, foreach does the same thing as an array_walk, which is a pointer based operation using internal pointers... so the pointer to 'next' should still be valid even with the unset....

Which is why his code runs just FINE!

Oh, and array_filter and it's kine are problematic since you can't pass values to the user function and frankly heavy on the overhead (with the nested userland function call) is the slowest of them too... after mentioning it above I gave it a whirl, NOT worth the effort.

unset inside foreach works just fine. First, foreach does the same thing as an array_walk, which is a pointer based operation using internal pointers... so the pointer to 'next' should still be valid even with the unset....

Should and is aren't always the same with PHP and you should know that by now.

Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.

I've seen PHP do bizarre things if you unset an element - particularly the element that will be next - in a foreach. Now granted, this behavior may have be fixed, but I long ago made it a point to avoid calling unset on the object I'm iterating on (I still do it when I absolutely need to, but that code gets extra heavy testing as a result).

And don't you just love that most array functions have arguments in the order (needle, haystack) and most string functions work in (haystack, needle) order?? heh heh - Love PHP, but I don't love it's inconsistencies.

Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.

Since the foreach is looping through a copy of the array, changing the original array will not alter the array which is being looped through, and thus, no conflict should occur.

most array functions have arguments in the order (needle, haystack) and most string functions work in (haystack, needle) order??

At least they're consistent within those two, completely unrelated, groups of functions. I never understood how folks get hung up on this particular setup; maybe we shouldn't have used the term "needle" and "haystack" for both groups.

I still feel the defining feature of PHP 6 should be shunting all existing functions to a legacy namespace. With a php.ini setting enabled the legacy namespace is imported to the root namespace. Otherwise the whole function library should be redone in an object oriented manner. All arrays would be array objects with the array methods tied to them, same with strings. This would be an enormous change and unlikely to ever occur, but it would be the perfect time to address these problems while using the ini flag to maintain BC.

That does rank amongst my pet peeves about PHP -- namespace and parameter orders. It literally feels like they just rolled a D6 on the order of parameters in functions... maybe it's the machine language/assembly coder in me, but come on... pick one, AT&T (dest, value) or Intel (target, value)... don't mix and match willy-nilly.