我在 StackOverflow 上找到了以下解决方案,从对象数组中获取特定对象属性的数组:PHP - 从对象数组中提取属性 https://stackoverflow.com/questions/1118994/php-extracting-a-property-from-an-array-of-objects/25807920#25807920
建议的解决方案是使用array_map
并在其中创建一个函数create_function
如下:
$catIds = array_map(create_function('$o', 'return $o->id;'), $objects);
会发生什么?:array_map
在本例中遍历每个数组元素stdClass
目的。首先它创建一个像这样的函数:
function($o) {
return $o->id;
}
其次,它为当前迭代中的对象调用此函数。它有效,它的工作原理几乎与这个类似的解决方案相同:
$catIds = array_map(function($o) { return $o->id; }, $objects);
但该解决方案仅在 PHP 版本 >= 5.3 中运行,因为它使用Closure
概念=>http://php.net/manual/de/class.closure.php http://php.net/manual/de/class.closure.php
现在真正的问题是:
第一个解决方案是create_function
增加内存,因为创建的函数将被写入内存并且不会被重用或销毁。在第二个解决方案中Closure
它会。
因此,这些解决方案给出了相同的结果,但在内存方面具有不同的行为。
以下示例:
// following array is given
$objects = array (
[0] => stdClass (
[id] => 1
),
[1] => stdClass (
[id] => 2
),
[2] => stdClass (
[id] => 3
)
)
BAD
while (true)
{
$objects = array_map(create_function('$o', 'return $o->id;'), $objects);
// result: array(1, 2, 3);
echo memory_get_usage() ."\n";
sleep(1);
}
4235616
4236600
4237560
4238520
...
GOOD
while (true)
{
$objects = array_map(function($o) { return $o->id; }, $objects);
// result: array(1, 2, 3);
echo memory_get_usage() ."\n";
sleep(1);
}
4235136
4235168
4235168
4235168
...
我花了很多时间来找出这个问题,现在我想知道,这是垃圾收集器的错误还是我犯了一个错误?
为什么将已经创建和调用的函数留在内存中是有意义的,因为它永远不会被重用?
这是一个运行示例:http://ideone.com/9a1D5g http://ideone.com/9a1D5g
Updated:当我递归搜索我的代码及其依赖项时,例如PEAR 和 Zend 然后我发现了这个BAD太频繁了。
Updated:当两个函数嵌套时,我们从内到外计算该表达式。换句话说,首先是开始create_function
(一次)并且返回函数名称是单次调用的参数array_map
。但是因为 GC 忘记将其从内存中删除(没有指向内存中函数的指针)并且 PHP 无法重用已经位于内存中的函数,让我认为存在错误,而不仅仅是“性能不佳”的情况。这行特定的代码是 PHPDoc 中的一个示例,并在许多大型框架中重用,例如Zend 和 PEAR 等等。再多一行,您就可以解决这个“错误”,检查一下。但我并不是在寻找解决方案:我是在寻找真相。这是一个错误还是这只是我的方法。而后者我还无法决定。