Cómo realizar solicitudes HTTP en PHP y no esperar la respuesta

Resuelto Brent asked hace 54 años • 17 respuestas

¿Existe alguna forma en PHP de realizar llamadas HTTP y no esperar una respuesta? No me importa la respuesta, solo quiero hacer algo como file_get_contents(), pero no esperar a que finalice la solicitud antes de ejecutar el resto de mi código. Esto sería muy útil para activar "eventos" de algún tipo en mi aplicación o desencadenar procesos largos.

¿Algunas ideas?

Brent avatar Jan 01 '70 08:01 Brent
Aceptado

La respuesta que había aceptado previamente no funcionó. Todavía esperaba respuestas. Sin embargo, esto funciona, tomado de ¿Cómo realizo una solicitud GET asincrónica en PHP?

function post_without_wait($url, $params)
{
    foreach ($params as $key => &$val) {
      if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
    }
    $post_string = implode('&', $post_params);

    $parts=parse_url($url);

    $fp = fsockopen($parts['host'],
        isset($parts['port'])?$parts['port']:80,
        $errno, $errstr, 30);

    $out = "POST ".$parts['path']." HTTP/1.1\r\n";
    $out.= "Host: ".$parts['host']."\r\n";
    $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out.= "Content-Length: ".strlen($post_string)."\r\n";
    $out.= "Connection: Close\r\n\r\n";
    if (isset($post_string)) $out.= $post_string;

    fwrite($fp, $out);
    fclose($fp);
}
 avatar May 27 '2010 21:05

Si controlas el objetivo al que deseas llamar de forma asincrónica (por ejemplo, tu propio "longtask.php"), puedes cerrar la conexión desde ese extremo y ambos scripts se ejecutarán en paralelo. Funciona así:

  1. Quick.php abre longtask.php a través de cURL (aquí no hay magia)
  2. longtask.php cierra la conexión y continúa (¡magia!)
  3. cURL vuelve a quick.php cuando se cierra la conexión
  4. Ambas tareas continúan en paralelo

He probado esto y funciona bien. Pero quick.php no sabrá nada sobre el rendimiento de longtask.php, a menos que cree algún medio de comunicación entre los procesos.

Pruebe este código en longtask.php, antes de hacer cualquier otra cosa. Cerrará la conexión, pero seguirá ejecutándose (y suprimirá cualquier resultado):

while(ob_get_level()) ob_end_clean();
header('Connection: close');
ignore_user_abort();
ob_start();
echo('Connection Closed');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();

El código se copia de las notas aportadas por el usuario del manual de PHP y se ha mejorado algo.

Christian Davén avatar Feb 13 '2010 18:02 Christian Davén

Puedes hacer trucos usando exec() para invocar algo que pueda realizar solicitudes HTTP, como wget, pero debes dirigir toda la salida del programa a algún lugar, como un archivo o /dev/null; de lo contrario, el proceso PHP esperará esa salida. .

Si desea separar completamente el proceso del hilo de Apache, intente algo como (no estoy seguro de esto, pero espero que entienda la idea):

exec('bash -c "wget -O (url goes here) > /dev/null 2>&1 &"');

No es un buen negocio y probablemente querrá algo como un trabajo cron que invoque un script de latido que sondee una cola de eventos de base de datos real para realizar eventos asincrónicos reales.

Internet Friend avatar Sep 23 '2008 23:09 Internet Friend