【问题标题】:How can i pass a single additional argument to array_map callback in PHP?如何在 PHP 中将单个附加参数传递给 array_map 回调?
【发布时间】:2026-01-26 16:45:01
【问题描述】:

如何将单个附加参数传递给array_map 回调?在我的示例中,我想将$smsPattern(作为第二个参数,在$featureNames 中的当前元素之后)传递给$getLimit 闭包的函数array_map

$features = $usage->getSubscription()->getUser()->getRoles();

// SMS regular expression in the form of ROLE_SEND_SMS_X
$smsPattern = '/^ROLE_SEND_SMS_(?P<l>\d+)$/i';

// Function to get roles names and X from a role name
$getNames = function($r) { return trim($r->getRole()); };
$getLimit = function($name, $pattern) {
    if(preg_match($pattern, $name, $m)) return $m['l'];
};

// Get roles names and their limits ignoring null values with array_filter
$featuresNames = array_map($getNames, $features);
$smsLimits     = array_filter(array_map($getLimit,  $featureNames, $smsPattern));

使用这段代码,我收到了一个奇怪的警告:

警告:array_map() [function.array-map]:参数 #3 应该 是一个数组。

当然,原因是为了将$getLimit 闭包与另一个正则表达式(如$smsPattern)重用。谢谢。

【问题讨论】:

  • 为什么不使用array_walk(),那么你可以传递一个额外的参数
  • 你用array_filter做什么?
  • @EmilVikström 删除空值。
  • 好的!我什至不知道 array_filter 没有回调就可以工作。现在我知道了,我也将它添加到我的答案中。

标签: php arrays callback closures array-map


【解决方案1】:

这正是闭包的含义:

$getLimit = function($name) use ($smsPattern) {
    if(preg_match($smsPattern, $name, $m)) return $m['l'];
};

$smsLimits = array_filter(array_map($getLimit, $features));

如果你想将其推广到其他模式,请将函数创建包装到另一个函数中:

function patternMatcher($pattern) {
    return function($name) use ($pattern) {
        if(preg_match($pattern, $name, $m)) return $m['l'];
    };
}

$getLimit = patternMatcher($smsPattern);
$smsLimits = array_filter(array_map($getLimit, $features));

在这里它被包装成一个匿名函数:

$patternMatcher = function($pattern) {
    return function($name) use ($pattern) {
        if(preg_match($pattern, $name, $m)) return $m['l'];
    };
};

$smsLimits = array_filter(array_map($patternMatcher($smsPattern), $features));

【讨论】:

    【解决方案2】:

    如文档中所述,您可以在数组之后将其他参数传递给 array_map()。问题是参数必须是一个数组。此数组中的每个值都与正在处理的数组中的相应索引一起传递给回调,因此您希望它们具有相同的长度。如果您只想为每次迭代使用一个参数,则可以使用array_fill() 填充如下参数数组:

    $smsLimits = array_map(
        $getLimit,
        $featureNames,
        array_fill(0, count($featureNames), $smsPattern)
    );
    

    一个常见的用例是您可能希望从 url 数组中修剪单个字符,例如 /

    $urls = ['http://example.com/','http://sub.example.com/'];
    $urls = array_map('rtrim', $urls, array_fill(0, count($urls), '/'));
    

    这会导致:

    Array
    (
        [0] => http://example.com
        [1] => http://sub.example.com
    )
    

    【讨论】: