Como faço uma solicitação GET assíncrona em PHP?


97

Desejo fazer uma solicitação GET simples para outro script em um servidor diferente. Como eu faço isso?

Em um caso, eu só preciso solicitar um script externo sem a necessidade de qualquer saída.

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

No segundo caso, preciso obter a saída de texto.

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

Para ser honesto, não quero mexer com o CURL, pois esse não é realmente o trabalho do CURL. Eu também não quero usar http_get porque não tenho as extensões PECL.

O fsockopen funcionaria? Em caso afirmativo, como faço isso sem ler o conteúdo do arquivo? Não há outra maneira?

Obrigado a todos

Atualizar

Devo acrescentar, no primeiro caso, não quero esperar que o script retorne nada. Pelo que entendi file_get_contents () vai esperar a página carregar totalmente etc?


6
@William: Sim, a maioria das perguntas pode ser considerada uma duplicata exata de si mesmas. 8-) Acho que você postou o link errado ...
RichieHindle


1
Eu pretendia postar o link musicfreak postado, mixou minhas abas ;-)
William Brendel

2
@Richie: Mais perguntas? ;)
Sasha Chedygov

1
Alterei o título da pergunta para diferenciá-la da outra, pois parece que você deseja fazer uma solicitação, mas não se preocupe em usar a resposta (então isso pode acontecer enquanto o resto do script é executado). Reverta se eu estiver enganado!
dbr

Respostas:


52

file_get_contents vai fazer o que você quiser

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

Edit: Uma maneira de disparar uma solicitação GET e retornar imediatamente.

Citado em 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);
}

O que isso faz é abrir um soquete, disparar um pedido get e imediatamente fechar o soquete e retornar.


6
curl_post_async envia uma solicitação POST, não GET.
Vinko Vrsalovic

13
Estou certo ao dizer que esta função foi nomeada incorretamente? Realmente não tem nada a ver com a biblioteca curl. É mais parecido com fsock_post_async ()
MikeMurko,

61
Isso NÃO é assíncrono! Em particular, se o servidor do outro lado estiver inativo, esse pedaço de código ficará travado por 30 segundos (o quinto parâmetro no fsockopen). Além disso, o fwrite vai demorar para ser executado (que você pode limitar com stream_set_timeout ($ fp, $ my_timeout). O melhor que você pode fazer é definir um tempo limite baixo em fsockopen para 0.1 (100ms) e $ my_timeout para 100ms . Você arrisca, porém, que o tempo limite do pedido seja atingido.
Chris Cinelli,

4
Isso não tem nada a ver com assíncrono. Isso é o mais sincronizado possível ... Assíncrono significa fazer outras tarefas enquanto esta tarefa está sendo concluída. É uma execução paralela.
CodeAngry de

17
Isso não é assíncrono nem está usando curl, como você ousa chamá-lo curl_post_asynce obter até mesmo votos positivos ...
Daniel W.

33

Veja como fazer a resposta do Marquis funcionar com solicitações POST e 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 é um trecho de código útil e tenho usado aqui e ali, mas agora acho que preciso fazer a mesma coisa, mas com um site SSL. Há algo que preciso alterar além do tipo HTTP / 1.1 e da porta?
Kevin Jhangiani,

2
Em resposta à pergunta sobre como usar isso para SSL, você pode torná-lo SSL alterando a porta para 443 e acrescentando ssl: // ao nome da porta em fsockopen: $ fp = fsockopen ("ssl: //". $ Parts ['host '],
Michael Dogger

1
"Há algo que eu preciso alterar além do tipo HTTP / 1.1 e da porta?" - Sim, você deve chamar fsockopen () com o nome do host em ssl://hostnamevez de apenas hostname.
Cowlby

22
Isso NÃO é assíncrono! Em particular, se o servidor do outro lado estiver inativo, esse pedaço de código ficará travado por 30 segundos (o quinto parâmetro no fsockopen). Além disso, o fwrite vai demorar para ser executado (que você pode limitar com stream_set_timeout ($ fp, $ my_timeout). O melhor que você pode fazer é definir um tempo limite baixo em fsockopen para 0.1 (100ms) e $ my_timeout para 100ms . Você arrisca, porém, que o tempo limite do pedido seja atingido.
Chris Cinelli,

1
Content-Length não deve ser definido para GET. Talvez em alguns cenários não cause erro, mas no meu caso resultou na solicitação não sendo processada pelo script php chamado.
user3285954

13

Em relação à sua atualização, sobre não querer esperar que a página inteira carregue - acho que uma HEADsolicitação HTTP é o que você está procurando ..

get_headers deve fazer isso - acho que ele só solicita os cabeçalhos, portanto, não será enviado o conteúdo completo da página.

"PHP / Curl: a solicitação HEAD demora muito em alguns sites" descreve como fazer uma HEADsolicitação usando PHP / Curl

Se você deseja acionar a solicitação e não atrasar o script, existem algumas maneiras, de complexidades variadas.

  • Execute a solicitação HTTP como um processo em segundo plano, o php executa um processo em segundo plano - basicamente você executaria algo como "wget -O /dev/null $carefully_escaped_url"- isso será específico da plataforma, e você deve ter muito cuidado ao escapar dos parâmetros para o comando
  • Executar um script PHP em segundo plano - basicamente o mesmo que o método de processo UNIX, mas executar um script PHP em vez de um comando shell
  • Tenha uma "fila de tarefas", usando um banco de dados (ou algo como beanstalkd que provavelmente é um exagero). Você adiciona um URL à fila e um processo em segundo plano ou cron-job verifica rotineiramente se há novos trabalhos e realiza solicitações no URL

+1 para várias opções interessantes que eu não pensei antes
Jasdeep Khalsa

"Acho que só solicita os cabeçalhos" - Talvez, mas não há nada que impeça um documento de enviar um corpo de resposta completo em resposta a uma solicitação HEAD. E suponho que esse método usaria fsock sob o capô e o forçaria a esperar (e ler) a resposta completa.
hiburn8 de

6

Você não. Embora o PHP ofereça muitas maneiras de chamar uma URL, ele não oferece suporte imediato para fazer qualquer tipo de processamento assíncrono / encadeado por solicitação / ciclo de execução. Qualquer método de envio de uma solicitação de URL (ou uma instrução SQL ou etc.) vai esperar por algum tipo de resposta. Você precisará de algum tipo de sistema secundário rodando na máquina local para conseguir isso (google para "fila de trabalho php")


1
Há um hack aqui: stackoverflow.com/questions/124462/asynchronous-php-calls (resposta de Christian Davén), mas concordo que uma fila seria a maneira certa de fazer isso.
Chris Cinelli,

Acho que essa resposta de 2009 agora está desatualizada. A biblioteca Guzzle PHP agora tem suporte para fazer solicitações simultâneas e assíncronas.
Simon East

6

Eu recomendaria a você uma biblioteca PHP bem testada: 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
}

A biblioteca Guzzle PHP também tem suporte para fazer solicitações simultâneas e assíncronas.
Simon East

Guzzle afirma que tem suporte, mas testar seu método postAsync parece que faz 150 ms de forma síncrona e 2 ms de forma assíncrona. Passei mais de uma hora tentando consertá-lo, sem sucesso - não recomendo.
Velizar Hristov

4

Se você estiver usando um ambiente Linux, poderá usar o comando exec do PHP para invocar o linux curl. Aqui está um código de amostra, que fará uma postagem HTTP assíncrona.

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 não precisa de libs PHP extras e pode completar a postagem http em menos de 10 milissegundos.


1
isso é uma ideia muito ruim: exec falha muito: imagine que 6/200 clientes não receberão sua confirmação por e-mail para uma reserva paga ...
HellBaby

Isso funcionou para mim, já que só preciso de um ping para iniciar outro script em outro servidor. Eu apenas usei assim: _async_http_post ($ url, ''); E isto está a funcionar nos servidores mutualizados da OVH ... O que é excelente.
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);
}

Você pode fazer com que ele retorne um objeto que permite chamar getstatus()ou waitSend()ou waitResult(). Dessa forma, o chamador pode obter um comportamento totalmente assíncrono chamando um loop para verificar se há resultados e, se não houver, continuar em qualquer outra tarefa que esteja sendo executada. Hmm, agora eu quero transferir Taskde .net para php ...
binki

3

Problema interessante. Suponho que você deseja apenas acionar algum processo ou ação no outro servidor, mas não se preocupe com quais são os resultados e deseja que seu script continue. Provavelmente, há algo em cURL que pode fazer isso acontecer, mas você pode querer considerar o uso exec()para executar outro script no servidor que faz a chamada, se cURL não puder fazer isso. (Normalmente as pessoas querem os resultados da chamada do script, então não tenho certeza se o PHP tem a capacidade de apenas acionar o processo.) Com exec()você pode executar um wgetou até mesmo outro script PHP que faça a solicitação com file_get_conents().


2

É melhor você considerar o uso de filas de mensagens em vez de métodos recomendados. Tenho certeza de que essa será a solução melhor, embora exija um pouco mais de trabalho do que apenas enviar uma solicitação.


2

deixe-me mostrar o meu caminho :)

precisa de nodejs instalado no servidor

(meu servidor envia 1000 https solicitação get leva apenas 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 não é uma solução PHP pura.
binki de

2

Para mim, a pergunta sobre a solicitação GET assíncrona surgiu devido a uma situação em que preciso fazer centenas de solicitações , obter e lidar com dados de resultado em cada solicitação e cada solicitação leva milissegundos significativos de execução, o que leva a minutos (!) De execução total com simples file_get_contents.

Neste caso, foi muito útil o comentário de w_haigh em php.net sobre a função http://php.net/manual/en/function.curl-multi-init.php

Então, aqui está minha versão atualizada e limpa de fazer muitas solicitações simultaneamente. No meu caso, é equivalente à forma "assíncrona". Pode ser que ajude alguém!

// 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

É fácil reescrever isso para lidar com POST ou outros tipos de solicitações HTTP (S) ou qualquer combinação deles. E suporte a cookies, redirecionamentos, http-auth, etc.


Ohh .. eu vejo a pergunta criada em 2009, e escrevo minha resposta em 2016 :) Mas muitos de nós, google php, ficaram assíncronos e vieram aqui.
FlameStorm

Sim, também vim aqui quando pesquisava. Alguns programadores também podem querer dar uma olhada na biblioteca Guzzle PHP, que tem suporte para fazer solicitações simultâneas e assíncronas.
Simon East

1

Experimentar:

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

Isso NÃO funcionará como um módulo apache, você precisa usar CGI.


1

Achei este link interessante para fazer processamento assíncrono (obter solicitação).

Askapache

Além disso, você pode fazer processamento assíncrono usando uma fila de mensagens como, por exemplo, beanstalkd.


1

Aqui está uma adaptação da resposta aceita para realizar uma solicitação GET simples.

Uma coisa a se observar se o servidor reescrever qualquer URL, isso não funcionará. Você precisará usar um cliente http com mais recursos.

  /**
   * 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

Apenas algumas correções nos scripts postados acima. O seguinte está funcionando para mim

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);
    }

Estou tendo um problema, onde o fwrite retorna um número positivo de bytes, mas o endpoint de script não é chamado (não está registrando) .. ele só funciona quando eu uso: while (! Feof ($ fp)) {fgets ($ fp , 128); }
Miguel

1

Ninguém parece mencionar o Guzzle , que é um cliente PHP HTTP que facilita o envio de solicitações HTTP. Pode funcionar com ou sem Curl. Ele pode enviar solicitações síncronas e assíncronas.

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

Sim, muitas das respostas neste tópico são bastante antigas, mas Guzzle é definitivamente a melhor opção que encontrei em 2018, obrigado por postar.
Simon East

0

Com base neste tópico, fiz isso para meu projeto codeigniter. Funciona muito bem. Você pode ter qualquer função processada em segundo plano.

Um controlador que aceita as chamadas assíncronas.

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

E uma biblioteca que faz as chamadas assíncronas

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 pode ser chamado para processar qualquer model :: method () no 'background'. Ele usa argumentos variáveis.

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

0

Sugestão: formate uma página HTML FRAMESET que contenha, digamos, 9 frames dentro. Cada quadro OBTERÁ uma "instância" diferente de sua página myapp.php. Haverá 9 threads diferentes em execução no servidor Web, em paralelo.


0

Para PHP5.5 +, mpyw / co é a solução definitiva. Funciona como se fosse tj / co em JavaScript.

Exemplo

Suponha que você deseja baixar os avatares de vários usuários do GitHub especificados. As etapas a seguir são necessárias para cada usuário.

  1. Obtenha conteúdo de http://github.com/mpyw (GET HTML)
  2. Encontre <img class="avatar" src="...">e solicite (OBTER IMAGEM)

---: Esperando minha resposta
...: Esperando outra resposta em fluxos paralelos

Muitos curl_multiscripts baseados em famosos já nos fornecem os seguintes fluxos.

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

No entanto, isso não é eficiente o suficiente. Você deseja reduzir tempos de espera inúteis ...?

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

Sim, é muito fácil com mpyw / co. Para mais detalhes, visite a página do repositório.


-1

Aqui está minha própria função PHP quando faço POST em uma URL específica de qualquer página ....

Exemplo: * uso da minha função ...

<?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

Experimente 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);

Não se esqueça de habilitar a extensão CURL php.


Você pode definir, CURLOPT_TIMEOUT_MSpor exemplo, 100 milissegundos em vez de CURLOPT_TIMEOUTsegundos e um mínimo de 1 segundo - para uma execução mais rápida.
Jason Silver

-5

Isso funciona bem para mim, infelizmente você não pode recuperar a resposta de sua solicitação:

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

Funciona muito rápido, sem necessidade de soquetes tcp brutos :)


Esta função adiciona um cabeçalho à resposta ... não está enviando uma solicitação de cabeçalho. php.net/manual/bg/function.header.php
Lachezar Todorov
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.