php - 传递引用不适用于 array_walk_recursive 的附加参数,除非它是已弃用的调用时传递引用

标签 php pass-by-reference

一段时间以来,我一直在使用“传统”递归函数来展平多维数组,例如

$baseArray = array(array('alpha'),
                   array('beta','gamma'),
                   array(),
                   array(array('delta','epsilon'),
                         array('zeta',array('eta',
                                            'theta'
                                           ),
                              ),
                        ),
                   array('iota'),
                  );

到一个简单的一维数组。

昨晚,我想看看使用 array_walk_recursive()看看我能否让它更高效、更清洁。

我的第一次尝试不是很成功:

function flattenArray($arrayValue, $arrayKey, &$flatArray) {
    $flatArray[] = $arrayValue;
}


$flattenedArray = array();
array_walk_recursive($baseArray,'flattenArray',$flattenedArray);

我认为它应该可以工作,但我得到的只是一系列错误:

Warning: Cannot use a scalar value as an array in C:\xampp\htdocs\arrayTest.php on line 16

结果是:

array(0) { }

我的 flattenArray() 函数中的类型提示给了我

Catchable fatal error: Argument 3 passed to flattenArray() must be an array, integer given in C:\xampp\htdocs\arrayTest.php on line 16

使用闭包得到相同的结果

我能让它工作的唯一方法(无需为我的 flattenedArray 使用全局或静态)是使用调用时间传递引用:

function flattenArray($arrayValue, $arrayKey, $flatArray) {
    $flatArray[] = $arrayValue;
}


$flattenedArray = array();
array_walk_recursive($baseArray,'flattenArray',&$flattenedArray);

产生正确的结果

array(9) { [0]=> string(5) "alpha" [1]=> string(4) "beta" [2]=> string(5) "gamma" [3]=> string(5) "delta" [4]=> string(7) "epsilon" [5]=> string(4) "zeta" [6]=> string(3) "eta" [7]=> string(5) "theta" [8]=> string(4) "iota" }

但给了我一个意想不到的警告

Deprecated: Call-time pass-by-reference has been deprecated in C:\xampp\htdocs\arrayTest.php on line 22

我知道 PHP 是一种古怪的语言,但这似乎有点极端。文档清楚地表明 array_walk_recursive 的第一个参数是按引用传递的,但似乎其他参数只能在调用时按引用传递。奇怪!

PHP版本是5.3.8

关于如何使用 array_walk_recursive 正确展平我的数组,而不会出现弃用错误的任何建议(除了提交错误报告)。

编辑

附言

我知道我可以使用闭包绕过这个问题:

$flattenedArray = array();
array_walk_recursive($baseArray, function($arrayValue, $arrayKey) use(&$flattenedArray){ $flattenedArray[] = $arrayValue; } );
var_dump($flattenedArray);

但由于这是当前允许与 PHP 5.2.0 一起使用的库所必需的,因此使用需要更高版本的 PHP 的功能不是一个实际的选择

最佳答案

这样想:您将 $flatArray 传递给 array_walk_recursive 按值array_walk_recursive 将进一步通过引用 将参数传递给您的函数。但是当它按值传递给 array_walk_recursive 时,引用将已经指向不同的值。

我知道,这似乎是一个奇怪的限制,但当您仔细想想时,这也是合乎逻辑的。

顺便说一句,我想你无意中还发现了另一个问题,它实际上看起来像是严重的内存损坏(看看打印的数组的第三个元素@ http://codepad.viper-7.com/ZYNrNd )。我会调查的。

附带说明,一种简单的扁平化方法是使用 RecursiveArrayIterator:

$flattenedArray = array();
foreach (new RecursiveIteratorIterator(
             new RecursiveArrayIterator($baseArray),
             RecursiveIteratorIterator::LEAVES_ONLY
         ) as $value) {
    $flattenedArray[] = $value;
}

关于php - 传递引用不适用于 array_walk_recursive 的附加参数,除非它是已弃用的调用时传递引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8587580/

相关文章:

php - 处理Laravel 4上传大文件异常

php - 使 Symfony2 资源与 SSL 一起工作

c - Valgrind C : Accessing by reference and unitialized value

python - 在 Python 函数中使用大数据结构时的效率

php - 根据页面更改主体类别

php - 翻译日期(“d F Y (H :i) function php

c++ - 编程风格 : object with passages by references or value? (c++)

java - 在Java中的方法中初始化对象

python通过引用传递

php - 如何从 PHP 脚本生成表格格式的输出