дожидаться ответа сервера (cURL PHP)

238
09 ноября 2017, 06:52

Добрый день, пожалуйста, помогите, пользуюсь библиотекой cURL (PHP), есть запрос к серверу ВКонтакте URL ($url ):

$ch = curl_init();
curl_setopt_array($ch, array(
            CURLOPT_USERAGENT => 'VK/1.0',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_POST => ($method == 'POST'),
            CURLOPT_POSTFIELDS => $postfields,
            CURLOPT_CONNECTTIMEOUT => 5,            
            CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, // предпочтительный ip  
            CURLOPT_URL => $url  
        ));

В итоге мы получаем контент который используем в дальнейшей работе. К примеру, создаем группу и получаем ее id, далее нам нужно опубликовать пост в созданной группе. Но проблема заключается в том, что ответ от сервера может приходить долго и получается такая ситуация, группа создается, но наш сервер не дождавшись ответа, проверяет есть ли id , его не оказывается и он не публикует запись, завершает работу? Какие есть варианты решения этой проблемы? Спасибо

Answer 1

Я сталкивался с подобными ситуациями а именно не мог понять - ошибка была из за того что данные не получили по причине того что сторонний сервер нам не отдал контент или это ошибка в нашем коде. В итоге написал для себя класс по получению данных со сторонних серверов - если ответ не пришел он пытается связаться еще 9 раз, после всех неудавшихся попыток выдает сообщение что ошибка возникла из за того что сервер не отдал контент

    interface ICUrlClass{
        public static function getData();
    }
    class CUrlException extends \Exception{}
    class CUrlClassException extends \Exception{}
    /*
    *@property cURL|FALSE $curl
    *@property integer $counter
    */
    class CUrlClass //implements ICUrlClass
    {
        protected static $curl=false;
        protected static $counter=0;
        /*
        *@param array $arr [ 'url'=>'url', 'headers'=>['Connection' => 'keep-alive', 'привет' => 'я умный парсер!'], 'method'=> 'post' | 'get' , 'data'=> NULL | string ]
        *@return string
        */
        public static function getData(array $arr){
            try{
                if(!isset($arr['url'])) throw new CUrlException('Не передан параметр url');
                if (!filter_var($arr['url'], FILTER_VALIDATE_URL)) throw new CUrlException('Не корректный url: '.$arr['url']);
                ++self::$counter;
                try{
                    if(!self::$curl) self::$curl=curl_init( $arr['url'] );
                }
                catch(\Exception $e){
                    throw new CUrlException('На сервере не установлена библиотека CUrl, либо внутренняя ошибка: '.$e->getMessage());
                }
                if(!self::$curl) throw new CUrlException('Не удалось сформировать дескриптор CUrl');
                //----------формируем загловки----------------------
                if(isset( $arr['headers'] ) ) curl_setopt( self::$curl, CURLOPT_HTTPHEADER,$arr['headers'] ); 
                if(isset( $arr['method'] ) ){
                    if( $arr['method'] == 'post' ) curl_setopt( self::$curl, CURLOPT_CUSTOMREQUEST, "POST");
                }
                if(isset( $arr['data'] ) ) curl_setopt( self::$curl, CURLOPT_POSTFIELDS, $arr['data'] );
                //--------------------------------------------------
                //вместо вывода в браузер - отдаем строковое значение
                curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, true);
                //задаем тайминг ожидания ответа от сервера
                curl_setopt(self::$curl, CURLOPT_CONNECTTIMEOUT, 10);
                //обходим редирект
                curl_setopt(self::$curl,CURLOPT_FOLLOWLOCATION, true ); 
                //устанавливаем конечное число обходов
                curl_setopt(self::$curl,CURLOPT_MAXREDIRS, 50 ); 
                //Инициируем запрос и сохраняем ответ в переменную
                $out=curl_exec(self::$curl); 
                //Получим HTTP-код ответа сервера
                $code=curl_getinfo(self::$curl,CURLINFO_HTTP_CODE); 
                $code=(int)$code;
                //если удаленный сервер не отвечает делаем 9 попыток
                if($code!=200 && $code!=204 && self::$counter<10 ){
                    return CUrlClass::getData($arr);
                    //return $code;
                }
                elseif($code!=200 && $code!=204 && self::$counter==10 ){
                    throw new CUrlException('К серверу было сделано 9 запросов: ни на один из них он не ответил. Код ответа сервера: '.$code);
                }
                else{
                    if(self::$curl!==false) curl_close(self::$curl);
                    self::$curl=false;
                    self::$counter=0;
                    return $out;
                }
            }
            catch(CUrlException $e){
                //return $e->getMessage();
                throw new CUrlClassException( $e->getMessage() );
            }
            finally {
                if(self::$curl!==false) curl_close(self::$curl);
                self::$curl=false;
                self::$counter=0;
            }
        }
    }

в вашем случае это $data = CUrlClass::getData(['url'=>'VK/1.0','method'=> 'post']);

Answer 2
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt ($ch, CURLOPT_TIMEOUT, 10);

В случае ожидания в течении 10 секунд, со значениями поиграйтесь, подберите что вам больше идет

READ ALSO
кириллица не записывается в json файл

кириллица не записывается в json файл

Есть формаС нее получаем данные POST'ом

326
Почему не рисуется QDateTimeAxis?

Почему не рисуется QDateTimeAxis?

При использовании библиотеки QtCharts столкнулся с проблемой - не отрисовывается ось QDateTimeAxis в том случае, если добавление данных на график и связывание...

284
Передача потока чтения из файла в функцию C++

Передача потока чтения из файла в функцию C++

В общем, передаю поток чтения из файла в функцию, чтобы строку считала, но вадаёт ошибку:

279
Создание структур C++

Создание структур C++

Не очень понимаю, что я делаю не такПрограмма просто завершается (с кодом 0) и ничего не выводит

376