¿Cómo hago una solicitud GET asincrónica en PHP?


97

Deseo realizar una solicitud GET simple a otro script en un servidor diferente. ¿Cómo hago esto?

En un caso, solo necesito solicitar un script externo sin la necesidad de ningún resultado.

make_request('http://www.externalsite.com/script1.php?variable=45'); //example usage

En el segundo caso, necesito obtener la salida de texto.

$output = make_request('http://www.externalsite.com/script2.php?variable=45');
echo $output; //string output

Para ser honesto, no quiero jugar con CURL ya que este no es realmente el trabajo de CURL. Tampoco quiero usar http_get porque no tengo las extensiones PECL.

¿Funcionaría fsockopen? Si es así, ¿cómo hago esto sin leer el contenido del archivo? ¿No hay otra forma?

Gracias a todos

Actualizar

Debería haber agregado, en el primer caso, no quiero esperar a que el script devuelva nada. Según tengo entendido, file_get_contents () esperará a que la página se cargue por completo, etc.


6
@William: Sí, la mayoría de las preguntas pueden considerarse duplicados exactos de sí mismos. 8-) Creo que publicaste el enlace incorrecto ...
RichieHindle


1
Quería publicar el enlace que musicfreak publicó, mezclé mis pestañas ;-)
William Brendel

2
@Richie: ¿ La mayoría de las preguntas? ;)
Sasha Chedygov

1
Volví a titular la pregunta para diferenciarla de la otra, ya que parece que desea hacer una solicitud, no le importa usar la respuesta (por lo que puede suceder mientras se ejecuta el resto del script). ¡Revertirlo si me equivoco!
Día

Respuestas:


52

file_get_contents harás lo que quieras

$output = file_get_contents('http://www.example.com/');
echo $output;

Editar: una forma de disparar una solicitud GET y regresar de inmediato.

Citado de http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html

function curl_post_async($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);
}

Lo que hace esto es abrir un socket, disparar una solicitud de obtención, cerrar inmediatamente el socket y regresar.


6
curl_post_async envía una solicitud POST, no una GET.
Vinko Vrsalovic

13
¿Tengo razón al decir que esta función tiene un nombre incorrecto? Realmente no tiene nada que ver con la biblioteca curl. Es fsock_post_async () más bien
MikeMurko

61
¡Esto NO es asíncrono! En particular, si el servidor del otro lado está inactivo, este código se colgará durante 30 segundos (el quinto parámetro en fsockopen). Además, fwrite se tomará su tiempo para ejecutarse (que puede limitar con stream_set_timeout ($ fp, $ my_timeout). Lo mejor que puede hacer es establecer un tiempo de espera bajo en fsockopen en 0.1 (100ms) y $ my_timeout en 100ms . Corre el riesgo, sin embargo, que la solicitud de tiempo de espera.
Chris Cinelli

4
Esto no tiene nada que ver con async. Esto es lo más sincronizado posible ... Async significa realizar otras tareas mientras se completa esta tarea. Es una ejecución paralela.
CodeAngry

17
Esto no es asincrónico ni está usando curl, cómo te atreves a llamarlo curl_post_asyncy obtener incluso votos positivos ...
Daniel W.

33

Así es como hacer que la respuesta de Marquis funcione con solicitudes POST y GET:

  // $type must equal 'GET' or 'POST'
  function curl_request_async($url, $params, $type='POST')
  {
      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);

      // Data goes in the path for a GET request
      if('GET' == $type) $parts['path'] .= '?'.$post_string;

      $out = "$type ".$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";
      // Data goes in the request body for a POST request
      if ('POST' == $type && isset($post_string)) $out.= $post_string;

      fwrite($fp, $out);
      fclose($fp);
  }

2
Este es un fragmento de código útil, y lo he estado usando aquí y allá, pero ahora encuentro que necesito hacer lo mismo, pero con un sitio SSL. ¿Hay algo que deba cambiar además del tipo HTTP / 1.1 y el puerto?
Kevin Jhangiani

2
En respuesta a la pregunta sobre el uso de esto para SSL, puede convertirlo en SSL cambiando el puerto a 443 y agregando ssl: // al nombre del puerto en fsockopen: $ fp = fsockopen ("ssl: //". $ Parts ['host '],
Michael Dogger

1
"¿Hay algo que deba cambiar además del tipo HTTP / 1.1 y el puerto?" - Sí, debería llamar a fsockopen () con el nombre de host como en ssl://hostnamelugar de simplemente hostname.
Cowlby

22
¡Esto NO es asíncrono! En particular, si el servidor del otro lado está inactivo, este código se colgará durante 30 segundos (el quinto parámetro en fsockopen). Además, fwrite se tomará su tiempo para ejecutarse (que puede limitar con stream_set_timeout ($ fp, $ my_timeout). Lo mejor que puede hacer es establecer un tiempo de espera bajo en fsockopen en 0.1 (100ms) y $ my_timeout en 100ms . Corre el riesgo, sin embargo, que la solicitud de tiempo de espera.
Chris Cinelli

1
Content-Length no debe establecerse para GET. Tal vez en algunos escenarios no cause errores, pero en mi caso resultó en que la solicitud no fuera procesada por el script php llamado.
user3285954

13

Con respecto a su actualización, acerca de no querer esperar a que se cargue la página completa, creo que HEADlo que está buscando es una solicitud HTTP .

get_headers debería hacer esto; creo que solo solicita los encabezados, por lo que no se enviará el contenido completo de la página.

"PHP / Curl: la solicitud HEAD lleva mucho tiempo en algunos sitios" describe cómo realizar una HEADsolicitud usando PHP / Curl

Si desea activar la solicitud y no retrasar el script en absoluto, hay algunas formas de diversas complejidades.

  • Ejecute la solicitud HTTP como un proceso en segundo plano, php ejecutará un proceso en segundo plano ; básicamente, ejecutaría algo como "wget -O /dev/null $carefully_escaped_url": esto será específico de la plataforma, y ​​debe tener mucho cuidado con los parámetros de escape al comando
  • Ejecutar un script PHP en segundo plano , básicamente lo mismo que el método de proceso UNIX, pero ejecutar un script PHP en lugar de un comando de shell
  • Tenga una "cola de trabajos", utilizando una base de datos (o algo como beanstalkd, que probablemente sea excesivo). Usted agrega una URL a la cola y un proceso en segundo plano o cron-job verifica de forma rutinaria si hay nuevos trabajos y realiza solicitudes en la URL

+1 para varias opciones interesantes en las que no había pensado antes
Jasdeep Khalsa

"Creo que solo solicita los encabezados": tal vez, pero no hay nada que impida que un documento envíe un cuerpo de respuesta completo en respuesta a una solicitud HEAD. Y supongo que este método usaría fsock debajo del capó y lo obligaría a esperar (y leer) la respuesta completa.
hiburn8

6

Tu no Si bien PHP ofrece muchas formas de llamar a una URL, no ofrece soporte listo para usar para realizar ningún tipo de procesamiento asíncrono / enhebrado por solicitud / ciclo de ejecución. Cualquier método para enviar una solicitud de una URL (o una declaración SQL, o etc.) esperará algún tipo de respuesta. Necesitará algún tipo de sistema secundario que se ejecute en la máquina local para lograr esto (busque en Google "cola de trabajos php")


1
Hay un truco aquí: stackoverflow.com/questions/124462/asynchronous-php-calls (respuesta de Christian Davén) pero estoy de acuerdo en que una cola sería la forma correcta de hacerlo.
Chris Cinelli

Creo que esta respuesta de 2009 ahora está desactualizada. La biblioteca PHP de Guzzle ahora tiene soporte para realizar solicitudes concurrentes y asincrónicas.
Simon East

6

Te recomendaría una biblioteca PHP bien probada: curl-easy

<?php
$request = new cURL\Request('http://www.externalsite.com/script2.php?variable=45');
$request->getOptions()
    ->set(CURLOPT_TIMEOUT, 5)
    ->set(CURLOPT_RETURNTRANSFER, true);

// add callback when the request will be completed
$request->addListener('complete', function (cURL\Event $event) {
    $response = $event->response;
    $content = $response->getContent();
    echo $content;
});

while ($request->socketPerform()) {
    // do anything else when the request is processed
}

La biblioteca PHP de Guzzle también tiene soporte para realizar solicitudes concurrentes y asincrónicas.
Simon East

Guzzle afirma que tiene soporte, pero probar su método postAsync parece que lo hace 150 ms de forma síncrona y luego 2 ms de forma asíncrona. Pasé más de una hora tratando de solucionarlo sin éxito, no lo recomendaría.
Velizar Hristov

4

Si está utilizando un entorno Linux, puede utilizar el comando exec de PHP para invocar el curl de Linux. Aquí hay un código de muestra, que hará una publicación HTTP asincrónica.

function _async_http_post($url, $json_string) {
  $run = "curl -X POST -H 'Content-Type: application/json'";
  $run.= " -d '" .$json_string. "' " . "'" . $url . "'";
  $run.= " > /dev/null 2>&1 &";
  exec($run, $output, $exit);
  return $exit == 0;
}

Este código no necesita bibliotecas PHP adicionales y puede completar la publicación http en menos de 10 milisegundos.


1
esta es una muy mala idea: el ejecutivo falla mucho: imagina que 6/200 clientes no recibirán la confirmación por correo electrónico de una reserva pagada ...
HellBaby

Esto funcionó para mí, en la medida en que solo necesito un ping para iniciar otro script en otro servidor. Lo usé así: _async_http_post ($ url, ''); Y esto funciona en servidores mutualizados de OVH ... Lo cual es genial.
Kilowog

4
function make_request($url, $waitResult=true){
    $cmi = curl_multi_init();

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    curl_multi_add_handle($cmi, $curl);

    $running = null;
    do {
        curl_multi_exec($cmi, $running);
        sleep(.1);
        if(!$waitResult)
        break;
    } while ($running > 0);
    curl_multi_remove_handle($cmi, $curl);
    if($waitResult){
        $curlInfos = curl_getinfo($curl);
        if((int) $curlInfos['http_code'] == 200){
            curl_multi_close($cmi);
            return curl_multi_getcontent($curl);
        }
    }
    curl_multi_close($cmi);
}

Puede hacer que devuelva un objeto que le permite llamar getstatus()o waitSend()o waitResult(). De esa manera, la persona que llama puede obtener un comportamiento completamente asincrónico llamando en un bucle para verificar si hay resultados y, si no, continuar con cualquier otra tarea que se esté ejecutando. Hmm, ahora quiero portar Taskde .net a php…
binki

3

Interesante problema. Supongo que solo desea activar algún proceso o acción en el otro servidor, pero no le importa cuáles son los resultados y desea que su secuencia de comandos continúe. Probablemente hay algo en cURL que puede hacer que esto suceda, pero es posible que desee considerar usar exec()para ejecutar otro script en el servidor que realiza la llamada si cURL no puede hacerlo. (Por lo general, la gente quiere los resultados de la llamada al script, por lo que no estoy seguro de si PHP tiene la capacidad de activar el proceso). Con exec()usted podría ejecutar un wgetscript PHP o incluso otro que realice la solicitud con file_get_conents().


2

Será mejor que considere utilizar Message Queues en lugar de los métodos recomendados. Estoy seguro de que esta será una mejor solución, aunque requiere un poco más de trabajo que simplemente enviar una solicitud.


2

déjame mostrarte mi camino :)

necesita nodejs instalado en el servidor

(mi servidor envía 1000 https get request tarda solo 2 segundos)

url.php:

<?
$urls = array_fill(0, 100, 'http://google.com/blank.html');

function execinbackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
        pclose(popen("start /B ". $cmd, "r"));  
    } 
    else { 
        exec($cmd . " > /dev/null &");   
    } 
} 
fwite(fopen("urls.txt","w"),implode("\n",$urls);
execinbackground("nodejs urlscript.js urls.txt");
// { do your work while get requests being executed.. }
?>

urlscript.js>

var https = require('https');
var url = require('url');
var http = require('http');
var fs = require('fs');
var dosya = process.argv[2];
var logdosya = 'log.txt';
var count=0;
http.globalAgent.maxSockets = 300;
https.globalAgent.maxSockets = 300;

setTimeout(timeout,100000); // maximum execution time (in ms)

function trim(string) {
    return string.replace(/^\s*|\s*$/g, '')
}

fs.readFile(process.argv[2], 'utf8', function (err, data) {
    if (err) {
        throw err;
    }
    parcala(data);
});

function parcala(data) {
    var data = data.split("\n");
    count=''+data.length+'-'+data[1];
    data.forEach(function (d) {
        req(trim(d));
    });
    /*
    fs.unlink(dosya, function d() {
        console.log('<%s> file deleted', dosya);
    });
    */
}


function req(link) {
    var linkinfo = url.parse(link);
    if (linkinfo.protocol == 'https:') {
        var options = {
        host: linkinfo.host,
        port: 443,
        path: linkinfo.path,
        method: 'GET'
    };
https.get(options, function(res) {res.on('data', function(d) {});}).on('error', function(e) {console.error(e);});
    } else {
    var options = {
        host: linkinfo.host,
        port: 80,
        path: linkinfo.path,
        method: 'GET'
    };        
http.get(options, function(res) {res.on('data', function(d) {});}).on('error', function(e) {console.error(e);});
    }
}


process.on('exit', onExit);

function onExit() {
    log();
}

function timeout()
{
console.log("i am too far gone");process.exit();
}

function log() 
{
    var fd = fs.openSync(logdosya, 'a+');
    fs.writeSync(fd, dosya + '-'+count+'\n');
    fs.closeSync(fd);
}

1
Esta no es una solución PHP pura.
binki

2

Para mí, la pregunta sobre la solicitud GET asincrónica se debe a que me encontré con una situación en la que necesito hacer cientos de solicitudes , obtener y tratar con datos de resultados en cada solicitud y cada solicitud requiere milisegundos significativos de ejecución que llevan a minutos (!) De ejecución total con simple file_get_contents.

En este caso, fue muy útil el comentario de w_haigh en php.net sobre la función http://php.net/manual/en/function.curl-multi-init.php

Entonces, aquí está mi versión mejorada y limpia de hacer muchas solicitudes simultáneamente. Para mi caso es equivalente a la forma "asincrónica". ¡Puede ser de ayuda para alguien!

// Build the multi-curl handle, adding both $ch
$mh = curl_multi_init();

// Build the individual requests, but do not execute them
$chs = [];
$chs['ID0001'] = curl_init('http://webservice.example.com/?method=say&word=Hello');
$chs['ID0002'] = curl_init('http://webservice.example.com/?method=say&word=World');
// $chs[] = ...
foreach ($chs as $ch) {
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,  // Return requested content as string
        CURLOPT_HEADER => false,         // Don't save returned headers to result
        CURLOPT_CONNECTTIMEOUT => 10,    // Max seconds wait for connect
        CURLOPT_TIMEOUT => 20,           // Max seconds on all of request
        CURLOPT_USERAGENT => 'Robot YetAnotherRobo 1.0',
    ]);

    // Well, with a little more of code you can use POST queries too
    // Also, useful options above can be  CURLOPT_SSL_VERIFYHOST => 0  
    // and  CURLOPT_SSL_VERIFYPEER => false ...

    // Add every $ch to the multi-curl handle
    curl_multi_add_handle($mh, $ch);
}

// Execute all of queries simultaneously, and continue when ALL OF THEM are complete
$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running);

// Close the handles
foreach ($chs as $ch) {
    curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);

// All of our requests are done, we can now access the results
// With a help of ids we can understand what response was given
// on every concrete our request
$responses = [];
foreach ($chs as $id => $ch) {
    $responses[$id] = curl_multi_getcontent($ch);
    curl_close($ch);
}
unset($chs); // Finita, no more need any curls :-)

print_r($responses); // output results

Es fácil reescribir esto para manejar POST u otros tipos de solicitudes HTTP (S) o cualquier combinación de ellas. Y soporte de cookies, redireccionamientos, http-auth, etc.


Ohh ... Veo la pregunta creada en 2009, y escribo mi respuesta en 2016 :) Pero muchos de nosotros google php se vuelve asincrónico y vinimos aquí.
FlameStorm

Sí, también vine aquí cuando busqué en Google. Es posible que algunos codificadores también quieran buscar en la biblioteca PHP Guzzle, que tiene soporte para realizar solicitudes simultáneas y asincrónicas.
Simon East

1

Tratar:

//Your Code here
$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
}
else if ($pid)
{
echo("Bye")  
}
else
{
     //Do Post Processing
}

Esto NO funcionará como un módulo de Apache, debe usar CGI.


1

Encontré este enlace interesante para hacer procesamiento asincrónico (obtener solicitud).

askapache

Además, puede realizar un procesamiento asincrónico utilizando una cola de mensajes como, por ejemplo, beanstalkd.


1

Aquí hay una adaptación de la respuesta aceptada para realizar una solicitud GET simple.

Una cosa a tener en cuenta si el servidor reescribe la URL, esto no funcionará. Deberá utilizar un cliente http con más funciones.

  /**
   * Performs an async get request (doesn't wait for response)
   * Note: One limitation of this approach is it will not work if server does any URL rewriting
   */
  function async_get($url)
  {
      $parts=parse_url($url);

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

      $out = "GET ".$parts['path']." HTTP/1.1\r\n";
      $out.= "Host: ".$parts['host']."\r\n";
      $out.= "Connection: Close\r\n\r\n";
      fwrite($fp, $out);
      fclose($fp);
  }

1

Solo algunas correcciones en los guiones publicados anteriormente. Lo siguiente me funciona

function curl_request_async($url, $params, $type='GET')
    {
        $post_params = array();
        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);
        echo print_r($parts, TRUE);
        $fp = fsockopen($parts['host'],
            (isset($parts['scheme']) && $parts['scheme'] == 'https')? 443 : 80,
            $errno, $errstr, 30);

        $out = "$type ".$parts['path'] . (isset($parts['query']) ? '?'.$parts['query'] : '') ." 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";
        // Data goes in the request body for a POST request
        if ('POST' == $type && isset($post_string)) $out.= $post_string;
        fwrite($fp, $out);
        fclose($fp);
    }

Tengo un problema, donde fwrite devuelve un número positivo de bytes, pero no se llama al punto final del script (no se registra) ... solo funciona cuando uso: while (! Feof ($ fp)) {fgets ($ fp , 128); }
Miguel

1

Nadie parece mencionar a Guzzle , que es un cliente HTTP de PHP que facilita el envío de solicitudes HTTP. Puede funcionar con o sin Curl. Puede enviar solicitudes tanto síncronas como asincrónicas.

$client = new GuzzleHttp\Client();
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

Sí, muchas de las respuestas en este hilo son bastante antiguas, pero Guzzle es definitivamente la mejor opción que encontré en 2018, gracias por publicar.
Simon East

0

Basado en este hilo, hice esto para mi proyecto codeigniter. Funciona muy bien. Puede tener cualquier función procesada en segundo plano.

Un controlador que acepta las llamadas asincrónicas.

class Daemon extends CI_Controller
{
    // Remember to disable CI's csrf-checks for this controller

    function index( )
    {
        ignore_user_abort( 1 );
        try
        {
            if ( strcmp( $_SERVER['REMOTE_ADDR'], $_SERVER['SERVER_ADDR'] ) != 0 && !in_array( $_SERVER['REMOTE_ADDR'], $this->config->item( 'proxy_ips' ) ) )
            {
                log_message( "error", "Daemon called from untrusted IP-address: " . $_SERVER['REMOTE_ADDR'] );
                show_404( '/daemon' );
                return;
            }

            $this->load->library( 'encrypt' );
            $params = unserialize( urldecode( $this->encrypt->decode( $_POST['data'] ) ) );
            unset( $_POST );
            $model = array_shift( $params );
            $method = array_shift( $params );
            $this->load->model( $model );
            if ( call_user_func_array( array( $this->$model, $method ), $params ) === FALSE )
            {
                log_message( "error", "Daemon could not call: " . $model . "::" . $method . "()" );
            }
        }
        catch(Exception $e)
        {
            log_message( "error", "Daemon has error: " . $e->getMessage( ) . $e->getFile( ) . $e->getLine( ) );
        }
    }
}

Y una biblioteca que hace las llamadas asincrónicas

class Daemon
{
    public function execute_background( /* model, method, params */ )
    {
        $ci = &get_instance( );
        // The callback URL (its ourselves)
        $parts = parse_url( $ci->config->item( 'base_url' ) . "/daemon" );
        if ( strcmp( $parts['scheme'], 'https' ) == 0 )
        {
            $port = 443;
            $host = "ssl://" . $parts['host'];
        }
        else 
        {
            $port = 80;
            $host = $parts['host'];
        }
        if ( ( $fp = fsockopen( $host, isset( $parts['port'] ) ? $parts['port'] : $port, $errno, $errstr, 30 ) ) === FALSE )
        {
            throw new Exception( "Internal server error: background process could not be started" );
        }
        $ci->load->library( 'encrypt' );
        $post_string = "data=" . urlencode( $ci->encrypt->encode( serialize( func_get_args( ) ) ) );
        $out = "POST " . $parts['path'] . " HTTP/1.1\r\n";
        $out .= "Host: " . $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";
        $out .= $post_string;
        fwrite( $fp, $out );
        fclose( $fp );
    }
}

Este método se puede llamar para procesar cualquier modelo :: método () en el 'fondo'. Utiliza argumentos variables.

$this->load->library('daemon');
$this->daemon->execute_background( 'model', 'method', $arg1, $arg2, ... );

0

Sugerencia: formatee una página HTML FRAMESET que contenga, digamos, 9 marcos en su interior. Cada marco OBTENDRÁ una "instancia" diferente de su página myapp.php. Habrá 9 subprocesos diferentes ejecutándose en el servidor web, en paralelo.


0

Para PHP5.5 +, mpyw / co es la solución definitiva. Funciona como si fuera tj / co en JavaScript.

Ejemplo

Suponga que desea descargar los avatares de varios usuarios de GitHub especificados. Los siguientes pasos son necesarios para cada usuario.

  1. Obtener contenido de http://github.com/mpyw (OBTENER HTML)
  2. Búscalo <img class="avatar" src="...">y solicítalo (OBTENER IMAGEN)

---: Esperando mi respuesta
... : Esperando otra respuesta en flujos paralelos

Muchos curl_multiscripts basados ​​en famosos ya nos proporcionan los siguientes flujos.

        /-----------GET HTML\  /--GET IMAGE.........\
       /                     \/                      \ 
[Start] GET HTML..............----------------GET IMAGE [Finish]
       \                     /\                      /
        \-----GET HTML....../  \-----GET IMAGE....../

Sin embargo, esto no es lo suficientemente eficiente. ¿Quiere reducir los tiempos de espera inútiles ...?

        /-----------GET HTML--GET IMAGE\
       /                                \            
[Start] GET HTML----------------GET IMAGE [Finish]
       \                                /
        \-----GET HTML-----GET IMAGE.../

Sí, es muy fácil con mpyw / co. Para obtener más detalles, visite la página del repositorio.


-1

Aquí está mi propia función PHP cuando hago POST en una URL específica de cualquier página ...

Ejemplo: * uso de mi función ...

<?php
    parse_str("email=myemail@ehehehahaha.com&subject=this is just a test");
    $_POST['email']=$email;
    $_POST['subject']=$subject;
    echo HTTP_Post("http://example.com/mail.php",$_POST);***

    exit;
?>
<?php
    /*********HTTP POST using FSOCKOPEN **************/
    // by ArbZ

    function HTTP_Post($URL,$data, $referrer="") {

    // parsing the given URL
    $URL_Info=parse_url($URL);

    // Building referrer
    if($referrer=="") // if not given use this script as referrer
      $referrer=$_SERVER["SCRIPT_URI"];

    // making string from $data
    foreach($data as $key=>$value)
      $values[]="$key=".urlencode($value);
    $data_string=implode("&",$values);

    // Find out which port is needed - if not given use standard (=80)
    if(!isset($URL_Info["port"]))
      $URL_Info["port"]=80;

    // building POST-request: HTTP_HEADERs
    $request.="POST ".$URL_Info["path"]." HTTP/1.1\n";
    $request.="Host: ".$URL_Info["host"]."\n";
    $request.="Referer: $referer\n";
    $request.="Content-type: application/x-www-form-urlencoded\n";
    $request.="Content-length: ".strlen($data_string)."\n";
    $request.="Connection: close\n";
    $request.="\n";
    $request.=$data_string."\n";

    $fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
    fputs($fp, $request);
    while(!feof($fp)) {
        $result .= fgets($fp, 128);
    }
    fclose($fp); //$eco = nl2br();

    function getTextBetweenTags($string, $tagname) {
        $pattern = "/<$tagname ?.*>(.*)<\/$tagname>/";
        preg_match($pattern, $string, $matches);
        return $matches[1]; }
    //STORE THE FETCHED CONTENTS to a VARIABLE, because its way better and fast...
    $str = $result;
    $txt = getTextBetweenTags($str, "span"); $eco = $txt;  $result = explode("&",$result);
    return $result[1];
<span style=background-color:LightYellow;color:blue>".trim($_GET['em'])."</span>
</pre> "; 
}
</pre>

-2

Prueba este código ...

$chu = curl_init();

curl_setopt($chu, CURLOPT_URL, 'http://www.myapp.com/test.php?someprm=xyz');

curl_setopt($chu, CURLOPT_FRESH_CONNECT, true);
curl_setopt($chu, CURLOPT_TIMEOUT, 1);

curl_exec($chu);
curl_close($chu);

No olvide habilitar la extensión PHP CURL.


Puede configurar, CURLOPT_TIMEOUT_MSpor ejemplo, 100 milisegundos en lugar de lo CURLOPT_TIMEOUTque es en segundos y tiene un mínimo de 1 segundo, para una ejecución más rápida.
Jason Silver

-5

Esto funciona bien para mí, lamentablemente no puede recuperar la respuesta de su solicitud:

<?php
header("http://mahwebsite.net/myapp.php?var=dsafs");
?>

Funciona muy rápido, sin necesidad de sockets tcp sin procesar :)


Esta función agrega un encabezado a la respuesta ... no envía una solicitud de encabezado. php.net/manual/bg/function.header.php
Lachezar Todorov
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.