我做了这个小班:
class Analyzer {
public static function analyze($phrases) {
$sortedPhrases = array();
array_walk($phrases, array('self', 'splitByLength'), $sortedPhrases);
var_dump($sortedPhrases);
}
private static function splitByLength($item, $key, &$resArr) {
// line stolen from here: http://stackoverflow.com/a/4786840/603003
// thanks to arnaud576875 <http://stackoverflow.com/users/576875/arnaud576875>
$len = count( preg_split('#\PL+#u', $item, -1, PREG_SPLIT_NO_EMPTY) );
if (!isset($resArr[$len])) {
$resArr[$len] = array();
}
$resArr[$len][] = $item;
var_dump($resArr);
}
}
$phrases = array(
"I can't believe the great content",
"I can't understand the superior information",
"I can't comprehend the amazing data",
"I cannot analyze the amazing data",
"I haven't written to the amazing data"
);
Analyzer::analyze($phrases);
执行脚本会产生以下输出:
array (size=1)
7 =>
array (size=1)
0 => string 'I can't believe the great content' (length=33)
...
array (size=3)
7 =>
array (size=3)
0 => string 'I can't believe the great content' (length=33)
1 => string 'I can't understand the superior information' (length=43)
2 => string 'I can't comprehend the amazing data' (length=35)
6 =>
array (size=1)
0 => string 'I cannot analyze the amazing data' (length=33)
8 =>
array (size=1)
0 => string 'I haven't written to the amazing data' (length=37)
array (size=0)
empty
除了最后一个来自 Analyzer :: analyze()的输出外,所有输出实际上都是正确的。似乎变量$sortedPhrases
在array_walk()之后以某种方式被清除。
答案 0 :(得分:5)
更好地了解array_walk
's documentation page。
<强>用户数据强>
如果提供了可选的userdata参数,则将其作为传递 回调函数的第三个参数。
这是第三个参数。它不是一个引用,它只是一个传递给回调函数的值。
您的问题中的一个(很多)解决方案是使用对象(对象总是通过引用传递):
class Analyzer {
public static function analyze($phrases) {
$arrObj = new ArrayObject();
array_walk($phrases, array('self', 'splitByLength'), $arrObj);
var_dump($arrObj->getArrayCopy());
}
private static function splitByLength($item, $key, $arrObj) {
// line stolen from here: http://stackoverflow.com/a/4786840/603003
// thanks to arnaud576875 <http://stackoverflow.com/users/576875/arnaud576875>
$len = count( preg_split('#\PL+#u', $item, -1, PREG_SPLIT_NO_EMPTY) );
if (!isset($arrObj[$len])) {
$arrObj[$len] = array();
}
$arrObj[$len][] = $item;
var_dump($arrObj->getArrayCopy());
}
}
(它不必是ArrayObject
,它可以是带有数组属性的stdClass对象,或者如果你想要创建自己的类......)
如果您真的想使用引用,可以将您的调用包装在匿名函数中:
$static = get_called_class();
array_walk($phrases, function($item, $key) use($static, &$sortedPhrases){
$static::splitByLength($item, $key, $sortedPhrases);
});
答案 1 :(得分:2)
虽然发送给回调函数的第三个参数本身不能是引用,但它可以包含引用。
另一种方法(使用对象或在闭包中包装回调)是将数组传递给回调,其中包含对要更新的变量的引用。包装数组按值传递,但它包含的是您想要更改的引用值。
class Analyzer {
public static function analyze($phrases) {
// …
array_walk($phrases,
array('self', 'splitByLength'),
array(&$sortedPhrases));
// …
}
private static function splitByLength($item, $key, $extra_args) {
$resArr = &$extra_args[0];
// …
}
}
答案 2 :(得分:1)
很确定这是错误的:
array_walk($phrases, array('self', 'splitByLength'), $sortedPhrases);
所以,试试这个:
$sortedPhrases = array_walk($phrases, 'splitByLength');
并在$sortedPhrases
中返回您的值,不要使用按引用传递(个人事物)