我有一个多维数组,例如:
$values = array(
'one' => array(
'title' => 'Title One',
'uri' => 'http://example.com/one',
),
'two' => array(
'title' => 'Title Two',
'uri' => 'http://example.com/two',
),
);
...我想通过我的implode
函数中的闭包来解析它,àla:
$final_string = implode(' | ', function($values) {
$return = array();
foreach($values as $value)
$return[] = '<a href="' . $value['uri'] . '">' . $value['title'] . '</a>';
return $return;
});
但是,此用法会产生Invalid arguments passed
错误。我是否缺少可以使用closures的语法?我正在使用PHP v5.3.16。
答案 0 :(得分:19)
使用array_map
:
$final_string = implode(' | ', array_map(function($item) {
return '<a href="' . $item['uri'] . '">' . $item['title'] . '</a>';
}, $values));
我相信您可以在真正的代码中正确地将这些值转换为HTML。
至于为什么这样做而你的代码没有,你将一个函数作为第二个参数传递给implode
。坦率地说,这没有多大意义:你可以将一堆字符串连接在一起,或者甚至可以连接一堆函数,但是你不能将一个函数连接在一起。这听起来很奇怪,特别是如果你这样说的话。
相反,我们首先要使用函数转换数组中的所有项,并将 的结果传递给implode
。此操作通常称为map
。幸运的是,PHP提供了这个功能,array_map
。在我们转换了数组中的项目后,我们可以加入结果。
答案 1 :(得分:4)
似乎您需要将函数分配给变量,然后将其传递以使其工作。
$fn = function($values) {
$return = array();
foreach($values as $value)
$return[] = '<a href="' . $value['uri'] . '">' . $value['title'] . '</a>';
return $return;
};
$final_string(' | ', $fn($values));
echo $final_string;
我不知道原因是什么,并且需要更深入地检查它才能给你一个正确的理由。
您可以看到代码正常工作here
编辑:将此答案转换为社区维基,以便每个人都可以在这里做出贡献。
编辑:@kmfk解释
当你将闭包直接传递给implode
方法 - 它明确地想要第二个类型为array
的参数时,它实际上会检查instanceof
- 因此无效的参数。 implode
函数不期望mixed
类型,并且不知道执行闭包以获得array
。
当您首次将该函数分配给变量时,它会导致PHP首先评估该变量,并最终将函数的返回值传递给implode
。
在这种情况下,您将从函数返回一个数组并将其传递给implode
- 这将检出。
匿名函数为instanceof Closure
和
Closure !== array
答案 2 :(得分:2)
Ashwin的回答是正确的。 原因如下:
当你将闭包直接传递给implode
方法 - 它明确地想要第二个类型为array
的参数时,它实际上会检查instanceof
- 因此无效的参数。 implode
函数不期望mixed
并且不知道执行闭包。
当您首次将该函数分配给变量时,它会导致PHP首先评估该变量,并最终将函数的返回值传递给implode
。
在这种情况下,您将从函数返回一个数组并将其传递给implode
- 这将检出。
编辑/添加:匿名函数为instanceof Closure
。
Closure !== array
答案 3 :(得分:0)
你不能将implode用于你想要实现的目标,因为implode只接受array
作为第二个参数。
你可以尝试这样的事情。
$values = array(
'one' => array(
'title' => 'Title One',
'uri' => 'http://example.com/one',
),
'two' => array(
'title' => 'Title Two',
'uri' => 'http://example.com/two',
),
);
$links = array();
foreach ($values as $value) {
$links[] = "<a href='" . $value['uri'] . "'>" . $value['title'] . "</a>";
}
$string = implode(" | ", $links);
答案 4 :(得分:0)
function implode_callback( $array, $separator = '', $callback = false )
{
return implode(
$separator,
$callback === false ?
$array : array_map( $callback, $array )
);
}
使用示例:
$tab = array( 1, 2, 3 );
echo implode_callback( $tab, '<hr>', function($x) { return "<p>$x</p>"; } );