使用array_fill的匿名函数

时间:2014-02-14 15:37:36

标签: php anonymous-function

所以我的目标是创建一串随机字母,字母可以在字符串中重复。所以我认为我可以聪明地做到这一点:

$str = implode(
  array_fill(0,10,
    function(){ 
      $c='abcdefghijklmnopqrstuvwxyz';
      return (string)$c{rand(0,strlen($c)-1)};
    }
  )
);
echo $str;

但我收到以下错误:

  

捕获致命错误:无法转换类Closure的对象   串起来......

这实际上是我脚本中唯一的东西,所以不,它不是别的东西。现在,手册指出array_fill的第3个arg描述是“用于填充的值”,并且它被列为接受混合类型。现在我知道“混合”并不一定等同于“任何”类型,但对我来说似乎我认为我应该能够使用匿名函数作为第3个arg,只要它返回一个字符串,对吗?但显然我不能这样做..

所以,我不一定要求为什么我不能这样做;它很可能归结为权力 - 而不是将其写入引擎盖下的代码中。但我想我只是想仔细检查一下我是否正确地执行了这个代码,因为如果php允许它(但不是这样)它应该“工作”,相比之下我可能在别的地方搞砸了?

2 个答案:

答案 0 :(得分:3)

如果没有该函数的显式变体,则没有理由期望函数执行您的回调,而不是简单地将其保留为变量。

让我们稍微分解一下逻辑:

// Declare the callback
$something = function(){ 
  $c='abcdefghijklmnopqrstuvwxyz';
  return (string)$c{rand(0,strlen($c)-1)};
}

无论这个函数做什么,我们现在都有一个恰好是Closure的变量。

// Fill the array
$list = array_fill(0,10,$something);

该数组现在已满10份$something。这恰好是我们Closure的10个指针。 PHP没有理由认为那不是你想要的。

// Join up the items in the array to make a string
$str = implode($list);

现在,implode()必须创建一个字符串,因此它会在继续之前将它给定的数组中的每个项目转换为字符串。对于一个对象,它将尝试调用__toString()(或内置对象的等效“引擎盖”),但Closure没有这样的方法。这就是您的错误来源。

所以,不,你没有完全搞砸,但是假设PHP只是因为你知道你想要的那样来执行回调是不合理的。


正如Mark Baker在评论中指出的那样,您可以使用array_map来执行回调;重复使用上面的$something,并为了清晰起见将其分解:

// Create 10 items, with nothing interesting in them
$list_of_nulls = array_fill(0, 10, null);

// Run the callback for each item of that list
// It will be given the current value each time, but ignore it
$list = array_map($something, $list_of_nulls);

// Now you have the list you wanted to join up
$str = implode($list);

当然,您也可以在循环中运行该函数10次:

$str = '';
for ( $i=0; $i<10; $i++ ) {
    $str .= $something();
}

答案 1 :(得分:0)

这可以通过array_fillarray_map完成:

$number_of_items = 25;

$array = array_map(function() {
  // Your callback here
  return 'foo';
}, array_fill(0, $number_of_items, null));