2012-04-29 85 views
1

我需要通过Facebook PHP SDK返回的大型数组来移动帮助。我正在尝试查找用户的所有帖子,然后检查帖子是否包含“链接”键。我已经读过,在这个大小的数组上使用foreach循环效率不高,因为要复制1MB数据来处理它。我应该如何有效地遍历信息?从大型多维数组中过滤帖子,PHP,Facebook API

阵列的结构是这样,其中“x”是每个帖子的数量:

Array 
(
    [data] => Array 
     (
      [x] => Array 
       (
        [from] => Array 
         (
          [name] => james 
         ) 

        [message] => Thanks for the great interview! 
        [link] => http://example.com/link.html 
        [description] => Description here 
        [etc] => Various other keys possible 
       ) 
     ) 
) 

然后我当前的代码如下所示,其中$饲料是从Facebook的API数组:

for ($x=0, $y=0; $x<=1000, $y<=19; $x++) { 

    if (array_key_exists('james', $feed['data'][$x]['from']['name'])) { 

     if (!array_key_exists('link', $feed['data'][$x])) { 

      echo "<div>" . $feed['data'][$x]['message'] . "<hr>" . $feed['data'][$x]['description'] . "</div>"; 

      $y++; 
     }; 

    }; 

}; 

我已阅读了各种迭代器,但我不知道要使用哪个!希望你能帮助我,欢呼声,乔

回答

1

谈到的foreach性能 并在事实上使用array_key_exists它是一种非意识 恕我直言,这是更好的像

foreach($feed['data'] as $post){ 
      if($post['from']['name']==='youruser'){ 
      //has user 
      } 
      if(isset($post['link'])){ 
      //has link 
      } 
}  

把它放在cillosis方式 ,它应该会更快。

+0

非常感谢 - 是的,这只是描述我的逻辑 - 我知道这是非常低效的代码。我使用的是foreach,然后使用上面的技术进行优化。再次感谢你的帮助! :) – Joe 2012-04-29 14:36:24

1

你是在事实正确的,遍历大数组时foreach可能会很慢,因为在默认情况下它使用值的副本和喜欢你所提到的,复制可以消耗内存并花费一点时间。

但是,另一种使用foreach的方式是,通过引用,它不创建副本。它与原始值一起工作。这意味着无论数组的大小如何,都不会再次放入内存。下面是引用为shared by another StackOverflow user一个的foreach的例子:

$a = array('hello', 'world'); 
$asRef =& $a; 
$ontime = 0; 
foreach($asRef as $i => $v) 
{ 
    if (!$ontime++) $a = array('hash', 'the cat'); 
    echo " $i: $v\n"; 
} 

您可以选择使用从用C语言编写,是相当快的SPL的ArrayIterator的选项。只是如何将工作一个简单的例子:

// This would be your large facebook array 
$big_array = array(1,2,3,...,10000,10001); 

// Get the iterator object 
$array_iterator = new ArrayIterator($big_array); 

foreach($array_iterator as $item) 
{ 
    //Do something with $item here 
} 

我没有做任何的基准,但我会想象通过引用传递的阵列,通过ArrayIterator可能会是一个很好的解决方案。

+0

非常感谢 - 当我精简我的代码时,我会实现这些技术。 :) – Joe 2012-04-29 15:41:41

-1

foreach并不总是复制。当它复制时,它只复制正在迭代的立即数据结构;它不会复制任何值。例如,如果你没有

foreach ($arr['data'] as $k => $v) .... 

,如果有100个个子元素(你简写的一种作为[X]),那么它将使阵列,复制这些100个密钥,但不会复制的值,该键指向的值是子数组/树。内部它只是存储一个指针,并指向子数组的内存地址,而不需要复制。

我认为你没有什么大不了的,因为实际获取的数据量非常少。 foreach几乎总是非常非常快...

如果你想瞥一眼,看看你的循环之前和之后的memory_get_usage()和memory_get_peak_usage()。

+0

当然,如果你的网站在某个时候处理大量的流量,最好是有更高效的代码?当然是 – Joe 2012-04-29 15:42:56

+0

。然而,与其他机会相比,此处每分钟花费的开发人员花费的利益可能非常低。 – goat 2012-04-29 15:47:59