函数的循环非常耗时


Looping of a function is so time consuming

我有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的所有数据,但当我在foreach循环中运行许多id时,"连接已重置"或"连接超时"显示。

您可以尝试以下方法:

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

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

  3. 正如Luke明智地提到的那样,您可以使页面异步,这意味着您可以用6块磁贴呈现页面,然后让每个磁贴为您想要的幻灯片发出ajax调用。这样,至少用户可以在加载图片时看到一些东西,而不是在你一次拉出所有图片时"挂起"。

  4. 我相信slideshare有一个非常强大的cdn托管这些图像,你可能想看看他们的服务器是否离你的web服务器更近。

快速问题,是curl选项是slideshare.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调用。

超时是由于您的函数占用了您已经说过的时间。这是正常的,它也可以在PHP配置或Apache中进行调整(不记得了,我会先检查PHP配置)。请记住,超时的存在是有原因的。

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

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