Configurar el tiempo de espera de Curl en PHP

Resuelto Moki asked hace 54 años • 0 respuestas

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?

Moki avatar Jan 01 '70 08:01 Moki
Aceptado

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
msangel avatar Jun 16 '2012 19:06 msangel

Hmm, me parece que CURLOPT_TIMEOUTdefine la cantidad de tiempo que cualquier función cURL puede tardar en ejecutarse. Creo que deberías mirar CURLOPT_CONNECTTIMEOUTen 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.

Chad Birch avatar Apr 06 '2010 01:04 Chad Birch

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

Simon E. avatar Dec 09 '2013 03:12 Simon E.