Today's function picked up a huge boost from PHP 5.3 in the form of closures. Because of how closures work array_walk can now have it's callback argument defined inline in a manner similar to javascript.

Code php:
$array = array(
  array (
    'l' => 1,
    'r' => 2
  ),
  array (
    'l' => 3,
    'r' => 4
  ),
  array (
    'l' => 5,
    'r' => 6
  )
);
 
array_walk( $array, function(&$array){
  $array['s'] = $array['l'] + $array['r'];
});

The above will result in

Code:
array(
  array (
    'l' => 1,
    'r' => 2,
    's' => 3
  ),
  array (
    'l' => 3,
    'r' => 4,
    's' => 7
  ),
  array (
    'l' => 5,
    'r' => 6,
    's' => 11
  )
);
Note that array walk can also pass additional arguments to the function as a third parameter, but the use clause of closures makes this unecessary

Same sample array as above

Code php:
$factor = 2;
 
array_walk( $array, function(&$array) use ($factor){
  $array['s'] = $array['l'] + $array['r'] * $factor;
});

So why use this instead of foreach? The main reason is that array_walk doesn't affect the internal pointer of an array. This allows it to be called from inside a foreach loop even while that array is being iterated on by the loop. While adding and deleting segments could be disastrous, in the right circumstance this can be highly useful. Another advantage of array_walk is the closure is its own function and therefore has it's own scope - it won't affect variables outside the "loop" unless they are imported with the use clause.

The examples on the php website focus on using array_walk without closures.