Бесконечный цикл с curl_multi_select - PullRequest
0 голосов
/ 17 июня 2019

Я пытаюсь ускорить медленно выполняющийся сценарий, заменив file_get_contents выполнением следующего curl_multi:

//for example only
$vcards = array($id1=>$vcardstring1, $id2=>$vcardstring2, /* ... */);

function sendVcards(array $vcards, callable $f){
    //debug_message is a custom function defined elsewhere to print data and flush output for debugging
    //debug_message("Sending vcards");

    $multi = curl_multi_init();
    $reqs  = array();

    global $settings;

    foreach ($vcards as $id => $vcard_data) {
        //url for example only
        $url = "https://example.com/address-book/guid-123456.ics";
        $req = curl_init();
        $options = array(
            CURLOPT_URL => $url,
            CURLOPT_CUSTOMREQUEST => 'PUT',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => array(
                'Authorization: Basic ' . base64_encode("username" . ':' . "userpass"),
                'Content-Length: '.strlen($vcard_data),
            ),
            CURLOPT_POSTFIELDS => $vcard_data,
            CURLINFO_HEADER_OUT => true,
        );
        curl_setopt_array($req, $options);
        //debug_message("Set curl options");
        curl_setopt($req, CURLOPT_HEADER, 0);
        curl_multi_add_handle($multi, $req);
        $reqs[$id] = $req;
    }

    // While we're still active, execute curl
    $active = null;

    // Execute the handles
    do {
        $mrc = curl_multi_exec($multi, $active);
        //debug_message("Executed CURL 1");
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {
        if (curl_multi_select($multi) != -1) {
            do {
                $mrc = curl_multi_exec($multi, $active);
                //debug_message("Executed CURL 2");
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        } else {
            //debug_message("Not Executing CURL 2",$multi);
        }
    }


    //debug_message("Closing curl handles");
    // Close the handles
    foreach ($reqs as $id => $req) {
        $result = curl_multi_getcontent($req);

        //debug_message("vcard sent for ".$id);

        if(preg_match('/"([0-9-]+)"/',current(array_filter(curl_getinfo($req, CURLINFO_HEADER_OUT), function($var){ return preg_match("/\bETag\b/i", $var); })),$ETag)){
            $ETag = $ETag[1];
        } else {
            $ETag = "";
        }

        //debug_message("etag received: ".$ETag);

        $f($id,$ETag);
        curl_multi_remove_handle($multi, $req);
    }
    curl_multi_close($multi);
}

Проблема, с которой я сталкиваюсь, состоит в том, что сценарий входит в бесконечный цикл, потому что if (curl_multi_select($multi) != -1) никогда не равняется истине.

Я что-то упустил в процессе скручивания в приведенном выше сценарии или это ошибка получающего сервера?Казалось, раньше он работал нормально с теми же строками авторизации и теми же URL-адресами, используя file_get_contents, поэтому я не верю, что проблема связана с URL-адресом или его частью авторизации.

Я прошу прощения за широкий вопрос, но яЯ не очень знаком с curl_multi_select, и я старался изо всех сил, читая библиотеку php: https://www.php.net/manual/en/function.curl-multi-select.php, но мне не удалось решить эту проблему самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...