@accountnujen

Как обработать ошибки curl php, если connect_time = 0?

У меня скрипт делает curl запрос. В параметрах я указал вот это:
curl_setopt_array($ch, [
CURLOPT_CONNECTTIMEOUT => 20, 
CURLOPT_TIMEOUT => 400, 
CURLOPT_RETURNTRANSFER => 1, 
CURLOPT_HTTPAUTH=>CURLAUTH_ANY]);

$b = curl_getinfo($ch);
if ($b['total_time'] > 399) {
  servicetg("Превышено время ожидания <code>total_time</code>. Время ожидания {$b['total_time']} секунд\nПопытка N$i");
} else 
if($b['connect_time'] > 19){
   servicetg("Превышено время подключения <code>connect_time</code>. Время ожидания {$b['connect_time']} секунд\nПопытка N$i");
} else
if ($http === 200) {
  return [$a,$b];
} else {
  servicetg("⚠⚠⚠\n<b>Критическая непредвиденная ошибка</b>\nКод состояния: $http\nВремя ожидания {$b['total_time']}\nПопытка N$i");
}

по моей логике должно было быть всё хорошо, однако, если хост недоступен, но мне выкинет исключение, потому что по какой-то причине connect_time будет равен 0 секунд.
[url] => http://....
[content_type] => 
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 20.001279
[namelookup_time] => 0.0017
[connect_time] => 0
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[redirect_url] => 
[primary_ip] => 
[certinfo] => Array
    (
    )

[primary_port] => 0
[local_ip] => 
[local_port] => 0
[http_version] => 0
[protocol] => 0
[ssl_verifyresult] => 0
[scheme] => 
[appconnect_time_us] => 0
[connect_time_us] => 0
[namelookup_time_us] => 1700
[pretransfer_time_us] => 0
[redirect_time_us] => 0
[starttransfer_time_us] => 0
[total_time_us] => 20001279


я, конечно, могу перестроить проверку, где будет
if 200
else if total_time > 399
else if total_time > 19 && http_code === 0
else

но кто-нибудь может объяснить, на кой тогда существует connect_time, если он всегда пустой?
  • Вопрос задан
  • 107 просмотров
Пригласить эксперта
Ответы на вопрос 1
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Думаю, вы правильно мыслите, то есть надо просто добавить пару проверок

Я тоже предпочитаю curl, а не Guzzle и им подобные.
Моя проверка как правило так выглядит:

// двойная инверсия как раз про "если хоть одно не выполнилось"
if (! (! curl_errno($ch)
&& 200 === curl_info($ch, CURLINFO_HTTP_CODE)
&& strlen(curlmulti_get_content($ch)) // для wordpress вместо strlen будет empty() т.к. их апишка ещё цифру 0 возвращает, когда отработало, но плохо
)) {
  // ... retry
}


И я оставил только CURLOPT_CONNECT_TIMEOUT, т.к. CURLOPT_TIMEOUT - это время на выполнение функции полностью (сломало меня, когда я много запросов запустил и поставил тайаут 5, так все курлы не успевали выполнится в мульти), вне зависимости от сети.

Так же у меня тоже была проблема, что курл единожды использованный нельзя просто "запустить еще раз", надо клонировать, а ресурс - не клонируется. Решил её через свою обертку curlBlueprint куда я напихиваю опции, а потом создаю ресурсы при помощи широко-понятных методов get/post/put... в итоге запросить повторно для меня это $chNew = $cbp->{get|post}(curl_getinfo($chUsed, CURLINFO_EFFECTIVE_URL));

https://github.com/6562680/support посмотрите реализацию XCurl.

При этом единственное, что отличает "юзаный курл" от "не юзаного" - это total_time, который у свежего строго 0.0. Ну и да, код ошибки тоже у свежего 0.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы