将 array_map 与多参数函数一起使用?

Using array_map with multi-argument function?

我正在构建一个递归函数,它执行任何深度嵌套数组的任何函数。例如,我想 STRIPSLASH 中的所有数组值:

function RECURSER($array,$function_name){ 
   return is_array($array) ? array_map('RECURSER', $array, $function_name) : $function_name($array); 
}

但是当我执行时:

recursive_for_array_value( $MY_ARRAY, 'stripslashes')

上述函数无法将第二个参数发送到array_map

array_map 接受一个函数和多个数组作为参数。也许您需要通过匿名函数递归调用 recurser。

function RECURSER($array,$function_name){ 
     if (is_array($array))
        return array_map(function ($element) use ($function_name) {
           return RECURSER($element,$function_name);
       },$array);                
   return $function_name($array);
}

stripslashes作为单行PHP函数的用例可以写成:

array_walk_recursive($array, function (&$value) { $value = stripslashes($value); });

任意函数的RECURSOR:

$result= Recursiver_of_Array($array, 'stripslashes');

代码:

function Recursiver_of_Array($array,$function_name=false){ 
    if ($function_name) { $GLOBALS['current_func_name']= $function_name; }
    return is_array($array) ? array_map('Recursiver_of_Array', $array) : $GLOBALS['current_func_name']($array); 
}

现在我要开始说我可能永远不会在任何实际项目中使用它,但这是一个有趣的 challenge/question 和 T.Todua 的答案有效但使用 $GLOBALS可以避免。

我的立场是 array_walk_recursive() 是一个比递归调用 array_map() 更适合的函数——毕竟,array_walk_recursive() 是专门设计用于访问叶节点并避免单调乏味的检查当前项目的类型为 "array"。 use() 有效地将函数字符串传递到递归函数的作用域中。

*注意:您 可以 仅将函数字符串作为 a string in a SUPER fringe case where the function prints to screen AND requires two arguments -- the first arg being the element value and the second arg being the element key.

传递

因为您只想处理元素值并通过引用修改它们,所以 &$v 是必要的。

这里是有关检查动态函数名称的相关 post 阅读:What exactly is the difference between the is_callable and function_exists in PHP?

这是我的替代方案:

代码:(Demo)

$multidim_array = ['a' => [' \one ', ['b' => 'two\', [['c' => 'thr\ee']]]]];
$func = 'stripslashes';
if (function_exists($func)) {
    array_walk_recursive($multidim_array, function(&$v)use($func){$v = $func($v);});
    var_export($multidim_array);
} else {
    echo "not callable";
}

如果您想进一步探索这个兔子洞,您可以可以通过设置传递多个参数的选项来扩展它的潜在效用:

代码:(Demo)

$func = 'strpos';
if (function_exists($func)) {
    $more = true;
    $param2 = 'o';
    array_walk_recursive($multidim_array, function(&$v)use($func, $more, $param2) {
        if ($more) {
            $v = $func($v, $param2);
        } else {
            $v = $func($v);
        }
    });
    var_export($multidim_array);
} else {
    echo "um... I'm not calling $func";
}

最后,我 whole-heartedly 不认可的方法是使用 eval() -- 因为你可以在一英里外看到尾巴、角和干草叉。

Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

这有效,但真的不应该被娱乐:

if (function_exists($func)) {
    array_walk_recursive($multidim_array, function(&$v)use($func) {eval("$v = $func($v);"); });
    var_export($multidim_array);
} else {
    echo "um... I'm not calling $func";
}