Configurar el tiempo de espera de Curl en PHP
Estoy ejecutando una solicitud curl en una base de datos eXist a través de php. El conjunto de datos es muy grande y, como resultado, la base de datos tarda constantemente mucho tiempo en devolver una respuesta XML. Para solucionarlo, configuramos una solicitud curl, con lo que se supone que es un tiempo de espera prolongado.
$ch = curl_init();
$headers["Content-Length"] = strlen($postString);
$headers["User-Agent"] = "Curl/1.0";
curl_setopt($ch, CURLOPT_URL, $requestUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'admin:');
curl_setopt($ch,CURLOPT_TIMEOUT,1000);
$response = curl_exec($ch);
curl_close($ch);
Sin embargo, la solicitud curl finaliza constantemente antes de que se complete (<1000 cuando se solicita a través de un navegador). ¿Alguien sabe si esta es la forma correcta de establecer tiempos de espera en curl?
Ver documentación: http://www.php.net/manual/en/function.curl-setopt.php
CURLOPT_CONNECTTIMEOUT
- La cantidad de segundos que se deben esperar al intentar conectarse. Utilice 0 para esperar indefinidamente.
CURLOPT_TIMEOUT
- El número máximo de segundos para permitir que se ejecuten las funciones de cURL.
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 400); //timeout in seconds
Tampoco olvides ampliar el tiempo de ejecución del script php:
set_time_limit(0);// to infinity for example
Hmm, me parece que CURLOPT_TIMEOUT
define la cantidad de tiempo que cualquier función cURL puede tardar en ejecutarse. Creo que deberías mirar CURLOPT_CONNECTTIMEOUT
en su lugar, ya que eso le dice a cURL la cantidad máxima de tiempo que debe esperar hasta que se complete la conexión.
Hay una peculiaridad en esto que podría ser relevante para algunas personas... De los comentarios de los documentos PHP.
Si desea que cURL expire en menos de un segundo, puede usar
CURLOPT_TIMEOUT_MS
, aunque hay un error/"característica" en los "sistemas tipo Unix" que hace que libcurl expire inmediatamente si el valor es < 1000 ms con el error "cURL Error (28): Se alcanzó el tiempo de espera". La explicación de este comportamiento es:"Si libcurl está diseñado para utilizar el sistema de resolución de nombres estándar, esa parte de la transferencia seguirá utilizando una resolución de segundo completo para los tiempos de espera con un tiempo de espera mínimo permitido de un segundo".
Lo que esto significa para los desarrolladores de PHP es "No puedes usar esta función sin probarla primero, porque no puedes saber si libcurl está usando el solucionador de nombres de sistema estándar (pero puedes estar bastante seguro de que así es)".
El problema es que en (Li|U)nix, cuando libcurl usa el solucionador de nombres estándar, se genera un SIGALRM durante la resolución de nombres, lo que libcurl cree que es la alarma de tiempo de espera.
La solución es desactivar las señales usando CURLOPT_NOSIGNAL. A continuación se muestra un script de ejemplo que se solicita a sí mismo y provoca un retraso de 10 segundos para que pueda probar los tiempos de espera:
if (!isset($_GET['foo'])) {
// Client
$ch = curl_init('http://localhost/test/test_timeout.php?foo=bar');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
curl_close($ch);
if ($curl_errno > 0) {
echo "cURL Error ($curl_errno): $curl_error\n";
} else {
echo "Data received: $data\n";
}
} else {
// Server
sleep(10);
echo "Done.";
}
De http://www.php.net/manual/en/function.curl-setopt.php#104597