Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Array Functions : array_walk

array_walk

Apply a user function to every member of an array (PHP 4, PHP 5)
bool array_walk ( array &array, callback funcname [, mixed userdata] )

Example 291. array_walk() example

<?php
$fruits
= array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");

function
test_alter(&$item1, $key, $prefix)
{
   
$item1 = "$prefix: $item1";
}

function
test_print($item2, $key)
{
   echo
"$key. $item2<br />\n";
}

echo
"Before ...:\n";
array_walk($fruits, 'test_print');

array_walk($fruits, 'test_alter', 'fruit');
echo
"... and after:\n";

array_walk($fruits, 'test_print');
?>

The above example will output:

Before ...:
d. lemon
a
. orange
b
. banana
c
. apple
... and after:
d. fruit: lemon
a
. fruit: orange
b
. fruit: banana
c
. fruit: apple ?>

Code Examples / Notes » array_walk

el_porno

You want to get rid of the whitespaces users add in your form fields...?
Simply use...:
class SomeVeryImportantClass
{
...
   public function mungeFormData(&$data)
   {
       array_walk($data, array($this, 'munge'));
   }
   private function munge(&$value, &$key)
   {
       if(is_array($value))
       {
           $this->mungeFormData($value);
       }
       else
       {
           $value = trim($value);
       }
   }
...
}
so...
$obj = new SomeVeryImportantClass;
$obj->mungeFormData($_POST);
___
eNc


appletalk

To use array_walk with a class simply do:
array_walk($input, array($this, method) );


webmaster

to the note right before this one.  that will only trim leading and trailing white space. if you want to trim white space inside the string (ie 'hello     world' to 'hello world') you should use this:
$val = preg_replace ( "/\s\s+/" , " " , $val ) ;
this will also trim leading and trailing white space.


thomas dot hebinck

This is a short way to concatenate a string to each element of an array:
$arr=array(1,2,3,4,5,6,7,8,9,0);
$str=' test'; // must not include ' or " ...
array_walk($arr,create_function('&$elem','$elem .= "' . $str . '";'));
var_export($arr);
The output is:
array ( 0 => '1 test', 1 => '2 test', 2 => '3 test', 3 => '4 test', 4 => '5 test', 5 => '6 test', 6 => '7 test', 7 => '8 test', 8 => '9 test', 9 => '0 test', )


paul

one rather important note that was lost in the Great PHP Doc Note Purge of '04 is that you can call methods using array_walk(). Let's assume that we have a class named 'Search', in which there is a method called 'convertKeywords'. Here's how you would call that convertKeywords method from inside the class:
   array_walk($keywords, array($this, 'convertKeywords'));
Notice that, instead of giving a string as the second argument, you give an array with two items: the variable that holds the class (in this case, $this), and the method to call. Here's what it would look like if you were to call convertKeywords from an already-instantiated class:
   $search = new Search;
   array_walk($keywords, array($search, 'convertKeywords'));


eierkoek

normaly the $_GET array will add slashes to the array values. To remove all slashes in this array, i created the folowing code
 set_magic_quotes_runtime (0);
 function StripAllSlashes (&$ArrayGET, $Value)
 {
   if (is_array ($ArrayGET)) array_walk ($ArrayGET, "StripAllSlashes");
   else $ArrayGET = stripslashes ($ArrayGET);
 }
 if (isset ($_GET) && get_magic_quotes_gpc ()) array_walk ($_GET, "StripAllSlashes");
I hope this code was usefull,
Eierkoek


nihaopaul

no sure if this should go under array-walk but it does what i need, it searches a multidimensionial array by using an array to walk it, it either returns a value or an array.
function walker($walk, $array) {
if (count($walk) >0) {
foreach($array as $key => $value) {
if ($key == $walk[0]) {
if (is_array($value)) {
unset($walk[0]);
return walker(array_values($walk), $value);
} else {
if (isset($value)) {
if (count($walk) == 1) {
return $value;
} else {
return 0;
}
} else {
return 0;
}
}
}
}
return 0;
} else {
return $array;
}
}


bisqwit

It's worth nothing that array_walk can not be used to change keys in the array.
The function may be defined as (&$value, $key) but not (&$value, &$key).
Even though PHP does not complain/warn, it does not modify the key.


andrzej martynowicz

It can be very useful to pass the third (optional) parameter by reference while modifying it permanently in callback function. This will cause passing modified parameter to next iteration of array_walk(). The exaple below enumerates items in the array:
<?
function enumerate( &$item1, $key, &$startNum ) {
  $item1 = $startNum++ ." $item1";
}
$num = 1;
$fruits = array( "lemon", "orange", "banana", "apple");
array_walk($fruits, 'enumerate', $num );
print_r( $fruits );
echo '$num is: '. $num ."\n";
?>
This outputs:
Array
(
   [0] => 1 lemon
   [1] => 2 orange
   [2] => 3 banana
   [3] => 4 apple
)
$num is: 1
Notice at the last line of output that outside of array_walk() the $num parameter has initial value of 1. This is because array_walk() does not take the third parameter by reference.. so what if we pass the reference as the optional parameter..
<?
$num = 1;
$fruits = array( "lemon", "orange", "banana", "apple");
array_walk($fruits, 'enumerate', &$num ); // reference here
print_r( $fruits );
echo '$num is: '. $num ."\n";
echo "we've got ". ($num - 1) ." fruits in the basket!";
?>

This outputs:
Array
(
   [0] => 1 lemon
   [1] => 2 orange
   [2] => 3 banana
   [3] => 4 apple
)
$num is: 5
we've got 4 fruits in the basket!
Now $num has changed so we are able to count the items (without calling count() unnecessarily).
As a conclusion, using references with array_walk() can be powerful toy but this should be done carefully since modifying third parameter outside the array_walk() is not always what we want.


ludvig dot ericson

In response to 'ibolmo', this is an extended version of string_walk, allowing to pass userdata (like array_walk) and to have the function edit the string in the same manner as array_walk allows, note now though that you have to pass a variable, since PHP cannot pass string literals by reference (logically).
<?php
function string_walk(&$string, $funcname, $userdata = null) {
   for($i = 0; $i < strlen($string); $i++) {
       # NOTE: PHP's dereference sucks, we have to do this.
       $hack = $string{$i};
       call_user_func($funcname, &$hack, $i, $userdata);
       $string{$i} = $hack;
   }
}
function yourFunc($value, $position) {
   echo $value . ' ';
}
function yourOtherFunc(&$value, $position) {
   $value = str_rot13($value);
}
# NOTE: We now need this ugly $x = hack.
string_walk($x = 'interesting', 'yourFunc');
// Ouput: i n t e r e s t i n g
string_walk($x = 'interesting', 'yourOtherFunc');
echo $x;
// Output: vagrerfgvat
?>
Also note that calling str_rot13() directly on $x would be much faster ;-) just a sample.


jon langevin >>intel352 :

In response to "Andrzej Martynowicz at gmail dot com", regarding the use of array_walk with the optional 3rd parameter being modified by reference:
while your solution works, yet another option is to call array_walk like so:
<?php
array_walk($array1, 'userfunction', &$array2byreference);
function userfunction(&$array1value, $key, $array2){
    // process $array1value and $array2, $array2 will retain the values
}
?>


jerk

if you want to modify every value of an multidimensional array use this function used here:
<?php
$array = array (1=>1, 2=> 2, 3 => array(1=>11, 2=>12, 3=>13));
$text = "test";
function modarr(&$array, $text) {
       foreach ($array as $key => $arr) {
               if(is_array($arr)) $res[$key] = modarr(&$arr,$text);
               // modification function here
               else $res[$key] = $arr.$text;
               }
       return $res;
}
$erg = modarr($array, $text);
print_r($erg);  
?>
result will be_
<?php
Array ( [1] => 1test [2] => 2test [3] => Array ( [1] => 11test [2] => 12test [3] => 13test ) )
?>


memandeemail

If you are using array_walk on a class, dont will work
so ... try this on your own class:
class your_own_class {
/**
* @return void
* @param array $input
* @param string $funcname
* @desc A little workaround, do the same thing.
*/
function array_walk($input, $funcname) {
foreach ($input as $key => $value) $this->$funcname($value, $key);
}
}


05-nov-2004 07:22

If array_walk_recursive() is not present and you want to apply htmlentities() on each array element you can use this:
function array_htmlentities(&$elem)
{
 if (!is_array($elem))
 {
   $elem=htmlentities($elem);
 }
 else
 {
   foreach ($elem as $key=>$value)
     $elem[$key]=array_htmlentities($value);
 }
 return $elem;
} // array_htmlentities()
If you want to output an array with print_r() and you have html in it this function is very helpful.


ibolmo

If anyone is interested to implement the array_walk functionality to a string. I've made this handy function. Note that this can be easily extended for any type of purpose. I've used this to convert from a string of bytes to a hex string then back from hex to a byte string.
<?php
function string_walk($string,$funcname)
{
for($i=0;$i<strlen($string);$i++) {
call_user_func($funcname,$string{$i});
}
}
function yourFunc($val)
{
echo $val.' ';
}
string_walk('interesting','yourFunc');
//ouput: i n t e r e s t i n g
?>


enlightened one

Beware that "array ($this, method)" construct. If you're wanting to alter members of the "$this" object inside "method" you should construct the callback like this:
 $callback[] = &$this;
 $callback[] = method;
 array_walk ($input, $callback);
Creating your callback using the array() method as suggested by "appletalk" results in a copy of $this being passed to method, not the original object, therefor any changes made to the object by method will be lost when array_walk() returns. While you could construct the callback with "array(&$this, method)", I believe this relies on the deprecated runtime pass-by-reference mechanism which may be removed in future releases of PHP. Better to not create a dependence on that feature now than having to track it down and fix it in the future.


lgaga dot dont dot spam

Behaviour like array_walk_recursive() can be achieved in php <=5 by a callback function to array_walk() similar to this:
function walkcallback(&$val,$key) {
   if (is_array($val)) array_walk($val,'walkcallback',$new);
   else {
       // do what you want with $val and $key recursively
   }
}


hayley watson

As well as being able to pass the array the callback will be working on by reference, one can pass the optional userdata parameters by reference also:
<?php
function surprise($x,$key,$xs)
{
//$key is unused here.
$x.='!';
array_push($xs,$x);
}
$array1 = array('this','that','the other');
$array2 = array();
array_walk($array1,'surprise',&$array2);
print_r($array1);
print_r($array2);
?>
Of course, that precise example would be better handled by array_map, but the principle is there.


hioctiane

<?php
/*Thanks to Jerk, thats what I need all the time.
I have a little Upgrade to your code.
Now the values of your $array will be handled by a consign method from a consign object(optional, otherwise taking this operator).*/
class user_function {
function user_function() {
}
/**
 *
 * handle all values from multidimensional array by $function from $object
 *
 */
function walk_multi_array(&$array, $method, $object=NULL) {
//when argument object is given
if (is_object($object)) {
//check if it is object
if (!is_object($object))
return false;
//check if object has method
if (!array_search(strtolower($method), get_class_methods(get_class($object))))
return false;
}
//no argument object is given
else {
//check if this class has method
if (!array_search(strtolower($method), get_class_methods(get_class($this))))
return false;
}
foreach ($array as $key => $value) {
//$value is array
if(is_array($value))
//recursiv call of walk_multi_array
$result[$key] = $this->walk_multi_array(&$value, $method, $object);
//$value is value
else {
if (is_object($object))
$result[$key] = $object->$method($value);
else
$result[$key] = $this->$method($value);
}
}
return $result;
}
}
class  test_class {
function test_class() {
}
function strtoup($value) {
return strtoupper($value);
}
}
$test_class = new test_class;
$user_function = new user_function;
$array = array (
1 => "testFall1",
2 => array (
21 => "tesTfaLL21",
22 => array (
221 => "TESTFALL221",
222 => "testfall222"
   )
  ),
3 => "testfall3"
);
echo "<pre>";
print_r($user_function->walk_multi_array($array, 'strtoup', $test_class));
echo "</pre>";
?>
Output:
Array
(
   [1] => TESTFALL1
   [2] => Array
       (
           [21] => TESTFALL21
           [22] => Array
               (
                   [221] => TESTFALL221
                   [222] => TESTFALL222
               )
       )
   [3] => TESTFALL3
)


caliban

> I believe this relies on the deprecated runtime
> pass-by-reference mechanism
The array() keyword is a language construct, not a function, so I don't think this is applicable.


Change Language


Follow Navioo On Twitter
array_change_key_case
array_chunk
array_combine
array_count_values
array_diff_assoc
array_diff_key
array_diff_uassoc
array_diff_ukey
array_diff
array_fill_keys
array_fill
array_filter
array_flip
array_intersect_assoc
array_intersect_key
array_intersect_uassoc
array_intersect_ukey
array_intersect
array_key_exists
array_keys
array_map
array_merge_recursive
array_merge
array_multisort
array_pad
array_pop
array_product
array_push
array_rand
array_reduce
array_reverse
array_search
array_shift
array_slice
array_splice
array_sum
array_udiff_assoc
array_udiff_uassoc
array_udiff
array_uintersect_assoc
array_uintersect_uassoc
array_uintersect
array_unique
array_unshift
array_values
array_walk_recursive
array_walk
array
arsort
asort
compact
count
current
each
end
extract
in_array
key
krsort
ksort
list
natcasesort
natsort
next
pos
prev
range
reset
rsort
shuffle
sizeof
sort
uasort
uksort
usort
eXTReMe Tracker