一、基本使用
array_walk ( array &$array
, callable $callback
[, mixed $userdata
= NULL
] ) : bool
使用用户自定义函数对数组中的每个元素做回调处理;将用户自定义函数 funcname
应用到 array
数组中的每个单元。
array_walk() 会遍历整个数组。相当于使用了一次foreach
1、成功时返回true,回调函数中使用return没有任何效果;
2、参数callback:典型情况下 callback 接受两个参数。array 参数的值作为第一个,键名作为第二个。
如果 callback 需要直接作用于数组中的值,则给 callback 的第一个参数指定为引用。这样任何对这些单元的改 变也将会改变原始数组本身。
不适合传内置参数,尤其参数数量超过预期,将抛出警告,例如strtolower()
3、参数userdata:如果提供了可选参数 userdata,将被作为第三个参数传递给 callback funcname。
//例1
$fruits = array( "d" => "lemon" , "a" => "orange" , "b" => "banana" , "c" => "apple" );
function test_print ( $item , $key )
{
echo " $key . $item <br />\n" ;
return $key . $item ;//return 没有任何效果
}
echo '<pre>';
array_walk ( $fruits , 'test_print' );
print_r($fruits);
/*
d . lemon
a . orange
b . banana
c . apple
Array
(
[d] => lemon
[a] => orange
[b] => banana
[c] => apple
)
*/
//例2、&改变原数组和第三参数的使用
$fruits = array( "d" => "lemon" , "a" => "orange" , "b" => "banana" , "c" => "apple" );
function test_alter (&$item , $key , $prefix )
{
$item = " $prefix : $item " ;
}
echo '<pre>';
array_walk ( $fruits , 'test_alter' , 'fruit' );
print_r($fruits);
/*
Array
(
[d] => fruit : lemon
[a] => fruit : orange
[b] => fruit : banana
[c] => fruit : apple
)
*/
4、只有 array 的值才可以被改变,用户不应在回调函数中改变该数组本身的结构。例如增加/删除单元,unset 单元等等。如果 array_walk() 作用的数组改变了,则此函数的的行为未经定义,且不可预期。(但实际上使用匿名函数时,use & 可以实现改变原数组表结构。但这里有的地方调试a键位对应132,所以最好不要这样)
//例3
$arr = [2, 3, 4];
array_walk($arr, function (&$item, $key) use (&$arr){
$item = 2* $item;
$arr['a'] = 66;
});
echo '<pre>';
print_r($arr);
/*
* Array
(
[0] => 4
[1] => 6
[2] => 8
[a] => 66
)
* */
$config = [
1 => ['title'=> '推荐','code'=>1],
2 => ['title'=> '搞笑','code'=>1],
3 => ['title'=> '奇闻','code'=>2],
];
数组如上,现在要取出数组里面code为1的title内容,结果要下面这样的(保留了一级索引)
[1=>'推荐',2=>'搞笑']
使用map的时候,在匿名函数里面是没有key值的,而walk是同时存在key val两个值的,所以这应该是他们最大的区别吧。
所以直接使用map的话,是无法实现上面的需求的,除非再定义一个回调函数,使用回调函数来处理,楼主没有亲测,感兴趣的可以试试。
现在来说说walk是如何实现的,其实很简单,在匿名函数里面直接使用外面的config,这里就相当于使用了一次foreach
array_walk($config, function($value, $key) use (&$config ){
if($value['code'] == 1){
$config[$key] = $value['title'];
}else{
unset($config[$key]);
}
});
后就能得到你想要的结果了,而且还不需要定义一个新数组,直接操作原来的数据一步到位
三、情景:商户管理模块,使用elementui表格行合并,需要统计每个商户的所有产品信息,其中有一个字段为产品总消耗
$merchants = [
['id' =>1 ,'name' => '白'],
['id' =>2 ,'name' => '黑'],
['id' =>3 ,'name' => '黄']
];
//循环商户,根据商户id获取商户拥有的产品
$products = [
['pid' => 11, 'pname' => '白产品1', 'price' => 50],
['pid' => 12, 'pname' => '白产品2', 'price' => 100],
['pid' => 13, 'pname' => '白产品3', 'price' => 200],
];
//循环产品,构造以产品信息为单位的数组返回
foreach($products as $key => &$value) {
$value['merchant_id'] = 1;
$value['merchant_name'] = '白';
}
//但是商户产品总价值需要单独处理获取
$merchant_price_sum = array_sum(array_column($products, 'price'));
array_walk($products,function(&$value, $key, $param){
$value['merchant_price_sum'] = $param;
}, $merchant_price_sum);
/*
Array
(
[0] => Array
(
[pid] => 11
[pname] => 白产品1
[price] => 50
[merchant_id] => 1
[merchant_name] => 白
[merchant_price_sum] => 350
)
[1] => Array
(
[pid] => 12
[pname] => 白产品2
[price] => 100
[merchant_id] => 1
[merchant_name] => 白
[merchant_price_sum] => 350
)
[2] => Array
(
[pid] => 13
[pname] => 白产品3
[price] => 200
[merchant_id] => 1
[merchant_name] => 白
[merchant_price_sum] => 350
)
)
*/
四、情景:我们的sql拼接的时候需要将每一个键也就是表字段加上反引号(` 字段`),给所有的值也就是表字段的值加上引号('值')。用来确保数据的安全。
//对字段两边加反引号,以保证数据库安全
function add_special_char(&$value) {
if('*' == $value || false !== strpos($value, '(') || false !== strpos($value, '.')
|| false !== strpos ( $value, '`')) {
//不处理包含* 或者 使用了sql方法。
} else {
$value = '`'.trim($value).'`';
}
//匹配到这些,替换为空
if (preg_match("/\b(select|insert|update|delete)\b/i", $value)) {
$value = preg_replace("/\b(select|insert|update|delete)\b/i", '', $value);
}
return $value;
}
//对字段值两边加引号,以保证数据库安全
function escape_string(&$value, $key='', $quotation) {
if ($quotation) {
$q = '\'';
} else {
$q = '';
}
$value = $q.$value.$q;
return $value;
}
$fields = ['id', 'name', 'sex', 'phone', '*', '(', 'insert' ,'update'];
$values = [4, '小红', '女', '13674122361', 'in' ,'up'];
array_walk($fields, 'add_special_char');
array_walk($values, 'escape_string', true);
/*
Array
(
[0] => `id`
[1] => `name`
[2] => `sex`
[3] => `phone`
[4] => *
[5] => (
[6] => ``
[7] => ``
)
Array
(
[0] => '4'
[1] => '小红'
[2] => '女'
[3] => '13674122361'
[4] => 'in'
[5] => 'up'
)
*/