循环函数非常耗时

时间:2011-11-08 18:07:02

标签: php function loops curl foreach

我有php函数解析一个xml url并给我一个数组。这个函数使用一个特殊的id并提供与在表单中传递的id相关的所有信息。现在我有20个不同的ID,我使用foreach循环以这种形式传递这些id,如下所示

<?php 
    $relatedSlides = $result['RelatedSlideshows'];
    if(!empty($relatedSlides)){
        $k=1;
        foreach($relatedSlides as $Related){
            RelatedSlides($Related);
            if($k%6==0){
                echo '</tr><tr>';
            }
            $k++;
        }
    }
?>

这是foreach循环。 $relatedSlides是所有幻灯片ID的数组。现在我正在编写解析特定id信息的函数。

function RelatedSlides($slideId){
    $secret_key = 'my api key';
    $ts=time();
    $hash=sha1($secret_key.$ts);
    $key = 'my secret key';
    $url = 'http://www.slideshare.net/api/2/get_slideshow?api_key='.$key.'&ts='.$ts.'& hash='.$hash.'&slideshow_id='.$slideId.'&detailed=1';
    echo $url;
    $ch=curl_init() or die (curl_error());
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla Firefox');
    $query = curl_exec($ch);
    $errorCode = curl_errno($ch); 
    curl_close($ch);
    $array = (array) simplexml_load_string($query);
    //echo '<pre>';
    //print_r($array);
    //return $array;
    echo "<font size=\"18\">return code is ".$errorCode."</font>";
    echo '<td valign="top"><div id="slide_thumb"><a href="viewslide.php?slideId='.$array['ID'].'&title='.$array['StrippedTitle'].'"><img src=" '.$array['ThumbnailURL'].'" width="100" height="100"/></a></div><div id="slide_thum_des"><strong>Views:</strong>'.$array['NumViews'].'<br /><ahref="'.$array['DownloadUrl'].'">'.$array['Title'].'....</a></div></td>';
}

当我调用此函数时,我的连接每次都会超时。功能绝对正确。它提供了有关特定id的所有数据,但是当我在许多id的foreach循环中运行它时,“连接已被重置”或“连接超时”显示。

2 个答案:

答案 0 :(得分:0)

超时是由于你的功能花了你已经说过的时间。这是正常的,它也可以在PHP配置或Apache中调整(不记得,但我会先检查PHP配置)。 请记住,超时是有原因的 - 例如。当你遇到inf循环时很好的超时 - 很少但很可能。

我认为解决这个问题的一种方法是将这个问题分成几部分,并使用AJAX实际进行不会花费很长时间的单个调用。

例如

  1. 使用一些JS / JQuery脚本加载页面。
  2. 调用异步以获取ID列表(通过jquery通过ajax调用完成 - 最简单)
  3. 在客户端解析响应(JSON?)并为每个id async执行每个请求。
  4. 等待所有结果返回并以您想要的方式显示它们。

答案 1 :(得分:0)

您可以尝试以下几点:

  1. 在RelateSlides()函数之外设置curl处理程序。这样,您不必每次迭代都继续构建和拆除$ ch资源。

  2. 检查slideshare.net api,看看是否有可以通过的参数来下拉较小的文件。

  3. 正如Luke明智地提到的,你可以使页面异步,这意味着你可以用6个图块渲染页面,然后让每个图块为你想要的幻灯片进行ajax调用。这样,至少用户可以在瓷砖加载时看到某些东西,而不是在您同时拉出所有图像时“挂起”。

  4. 我相信slidehare有一个非常强大的cdn托管这些图片,你可能想看看他们是否有更接近你的网络服务器的服务器。

  5. 快速提问,slidehare.net是如何建议你去拉图像的卷曲选项?您可以创建一个图像标记,其中包含直接指向其api的链接:

     echo '<img src="http://www.slideshare.net/api/2/get_slideshow?api_key='.$key.'&ts='.$ts.'& hash='.$hash.'&slideshow_id='.$slideId.'&detailed=1' />';
    

    如果您正在为扩展数据执行curl选项,您可能需要考虑缓存扩展数据,这样您就不必继续进行无关的simplexml_load_string调用。