简体   繁体   English

PHP-带foreach功能的网站变慢

[英]PHP - Function with foreach slowing down site

I'm working on a project that connects to an external API. 我正在开发一个连接到外部API的项目。 I have already made the connection and I've implemented several functions to retrieve the data, that's all working fine. 我已经建立了连接,并且已经实现了几个函数来检索数据,一切正常。

The following function however, works exactly like it should, only it slows down my website significantly ( 25 seconds + ). 但是,以下功能完全可以正常工作,只是大大降低了我的网站速度(超过25秒)。

Is this because of the nested foreach loop? 这是因为嵌套的foreach循环吗? And what can i do to refactor the code? 我该怎么做才能重构代码?

/**
 * @param $acti
 */
function getBijeenkomstenFromAct ($acti) {
    $acties = array();
    foreach ($acti as $act) {
        $bijeenkomsten = $this->getBijeenkomstenFromID($act['id']);
        if (in_array('Doorlopende activiteit', $act['type'])) {
            foreach ($bijeenkomsten as $bijeenkomst) {
                $acties[] = array(
                    'id'         => $act['id'],
                    'Naam'       => $act['titel'],
                    'interval'   => $act['interval'],
                    'activiteit' => $bijeenkomst['activiteit'],
                    'datum'      => $bijeenkomst['datum']
                );
            }
        } else {
            $acties[] = array (
                'id'            => $act['id'],
                'type'          => $act['type'],
                'activiteit'    => $act['titel'],
                'interval'      => $act['interval'],
                'dag'           => $act['dag'],
                'starttijd'     => $act['starttijd'],
                'eindtijd'      => $act['eindtijd']

            );
        }
    }
    return $acties;
}

The function "getBijeenkomstenfromID" is working fine and on it's own not slow at all. 函数“ getBijeenkomstenfromID”可以正常工作,其本身一点也不慢。 Just to be sure, here is the function: 只是要确定,这是函数:

/**
 * @param $activitieitID
 *
 * @return mixed
 *
 */
public function getBijeenkomstenFromID($activitieitID) {
    $options = array(
        //'datumVan'      => date('Y-m-d'),
        'activiteit'    => array (
            'activiteit'    => $activitieitID
        ),
        'limit'     => 5,
        'datumVan'  => date(("Y-m-d"))
    );
    $bijeenkomsten = $this->webservice->activiteitBijeenkomstOverzicht($this->api_key, $options);

    return $bijeenkomsten;
}

It looks like you're calling on the API from within the first foreach loop, which is not efficient. 好像您是在第一个foreach循环中调用API那样,效率不高。

Every time you do this: 每次您这样做:

$bijeenkomsten = $this->getBijeenkomstenFromID($act['id']);

you're adding a lot of "dead" time to your script since you have to put on with network latency, the time you need to allow for the API to actually do the work and transmit it back to you. 由于必须忍受网络延迟,因此您在脚本中增加了很多“停滞”时间,这是允许API实际完成工作并将其传输回给您的时间。 Even though this may be quick (let's say 100ms total), if your first foreach loop iterates 100 times, you already have accumulated 10 seconds of waiting, and that's before getBijeenkomstenFromAct ($acti) has done any real processing. 即使这可能很快(比如说总共100毫秒),但是如果您的第一个foreach循环迭代100次,则您已经累积了10秒的等待时间,而那是在getBijeenkomstenFromAct($ acti)进行任何实际处理之前。

The best practice here would be to split this if possible. 如果可能的话,此处的最佳做法是将其拆分。 My suggestion: 我的建议:

Make getBijeenkomstenFromID($activitieitID) run asynchronously on its own for all the IDs you need to lookup in the API. 对于需要在API中查找的所有ID,使getBijeenkomstenFromID($ activitieitID)单独异步运行。 The key here is for it to run as a separate process and then have it pass the array it constructs to getBijeenkomstenFromAct so that it can loop and process it happily. 这里的关键是使其作为单独的进程运行,然后将其构造的数组传递给getBijeenkomstenFromAct,以便它可以快乐地循环和处理它。

So yes, basically I'm suggestion that you orchestrate your process backwards for efficiency's sake 所以是的,基本上我建议您为效率起见,将流程向后编排

Look into curl_multi : http://php.net/manual/en/function.curl-multi-exec.php 看看curl_multihttp : //php.net/manual/en/function.curl-multi-exec.php

It will let you call an external API asynchronously and process the returns all at once. 它可以让您异步调用外部API并立即处理所有返回。 Be aware that APIs often have their own limitations on asynchronous calls, and common sense dictates that you probably shouldn't be hammering a website with 200 separate calls. 请注意,API通常在异步调用上有其自身的局限性,并且常识表明您可能不应该对网站进行200次单独的调用。 But if your number of calls is under a dozen or two (and the API allows it), curl_multi will do nicely. 但是,如果您的调用次数少于或少于一打(并且API允许),curl_multi会做得很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM