Come si effettua una richiesta GET asincrona in PHP?


97

Desidero fare una semplice richiesta GET a un altro script su un server diverso. Come faccio a fare questo?

In un caso, ho solo bisogno di richiedere uno script esterno senza la necessità di alcun output.

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

Nel secondo caso, ho bisogno di ottenere l'output di testo.

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

Ad essere onesto, non voglio scherzare con CURL perché questo non è proprio il lavoro di CURL. Inoltre, non voglio utilizzare http_get poiché non ho le estensioni PECL.

Fsockopen funzionerebbe? In tal caso, come posso farlo senza leggere il contenuto del file? Non c'è altro modo?

Ringrazia tutti

Aggiornare

Dovrei aggiungere, nel primo caso, non voglio aspettare che lo script restituisca qualcosa. Da quanto ho capito, file_get_contents () aspetterà che la pagina venga caricata completamente, ecc.?


6
@ William: Sì, la maggior parte delle domande può essere considerata un duplicato esatto di se stessa. Cool Penso che tu abbia postato il link sbagliato ...
RichieHindle


1
Volevo pubblicare il link musicfreak pubblicato, confuso le mie schede ;-)
William Brendel,

2
@Richie: la maggior parte delle domande? ;)
Sasha Chedygov

1
Ho rinominato la domanda per differenziarla dall'altra, poiché sembra che tu voglia fare una richiesta non preoccuparti dell'utilizzo della risposta (quindi può accadere mentre il resto dello script viene eseguito). Ripristinalo se mi sbaglio!
dbr

Risposte:


52

file_get_contents farà quello che vuoi

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

Modifica: un modo per attivare una richiesta GET e tornare immediatamente.

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

Ciò che fa è aprire un socket, attivare una richiesta get e chiudere immediatamente il socket e restituire.


6
curl_post_async invia una richiesta POST, non un GET.
Vinko Vrsalovic

13
Ho ragione nel dire che questa funzione è denominata in modo improprio? Non ha davvero nulla a che fare con la libreria curl. È fsock_post_async () più simile
MikeMurko

61
Questo NON è asincrono! In particolare, se il server dall'altra parte è inattivo, questo pezzo di codice si bloccherà per 30 secondi (il quinto parametro in fsockopen). Inoltre fwrite impiegherà il suo tempo per eseguire (che puoi limitare con stream_set_timeout ($ fp, $ my_timeout). Il meglio che puoi fare è impostare un timeout basso su fsockopen a 0.1 (100ms) e $ my_timeout a 100ms Rischi però che la richiesta scada
Chris Cinelli

4
Questo non ha nulla a che fare con async. Questa è la sincronizzazione che si ottiene ... Asincrona significa eseguire altre attività mentre questa attività viene completata. È un'esecuzione parallela.
CodeAngry

17
Questo non è né asincrono né utilizza curl, come osi chiamarlo curl_post_asynce ottenere anche voti positivi ...
Daniel W.

33

Ecco come far funzionare la risposta di Marquis con le richieste 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
Questo è un pratico frammento di codice e l'ho usato qua e là, ma ora scopro che devo fare la stessa cosa, ma con un sito SSL. C'è qualcosa che devo cambiare oltre al tipo HTTP / 1.1 e alla porta?
Kevin Jhangiani

2
In risposta alla domanda sull'utilizzo di questo per SSL, puoi renderlo SSL cambiando la porta in 443 e aggiungendo ssl: // al nome della porta in fsockopen: $ fp = fsockopen ("ssl: //". $ Parts ['host '],
Michael Dogger

1
"C'è qualcosa che devo cambiare oltre al tipo HTTP / 1.1 e alla porta?" - Sì, dovresti chiamare fsockopen () con il nome host as ssl://hostnameinvece che solo hostname.
Cowlby

22
Questo NON è asincrono! In particolare, se il server dall'altra parte è inattivo, questo pezzo di codice si bloccherà per 30 secondi (il quinto parametro in fsockopen). Inoltre fwrite impiegherà il suo tempo per eseguire (che puoi limitare con stream_set_timeout ($ fp, $ my_timeout). Il meglio che puoi fare è impostare un timeout basso su fsockopen a 0.1 (100ms) e $ my_timeout a 100ms Rischi però che la richiesta scada
Chris Cinelli

1
Content-Length non dovrebbe essere impostato per GET. Forse in alcuni scenari non causa errori, ma nel mio caso la richiesta non è stata elaborata dallo script php chiamato.
user3285954

13

Per quanto riguarda il tuo aggiornamento, sul non voler aspettare il caricamento della pagina intera - penso che una HEADrichiesta HTTP sia quello che stai cercando ..

get_headers dovrebbe farlo - penso che richieda solo le intestazioni, quindi non verrà inviato l'intero contenuto della pagina.

"PHP / Curl: la richiesta HEAD richiede molto tempo su alcuni siti" descrive come eseguire una HEADrichiesta utilizzando PHP / Curl

Se vuoi attivare la richiesta e non bloccare affatto lo script, ci sono alcuni modi, di varia complessità.

  • Esegui la richiesta HTTP come processo in background, php esegue un processo in background - in pratica eseguiresti qualcosa di simile "wget -O /dev/null $carefully_escaped_url"- questo sarà specifico della piattaforma e devi stare molto attento all'escape dei parametri al comando
  • Esecuzione di uno script PHP in background : sostanzialmente uguale al metodo di elaborazione UNIX, ma esecuzione di uno script PHP anziché di un comando di shell
  • Avere una "coda di lavoro", utilizzando un database (o qualcosa come beanstalkd che è probabilmente eccessivo). Aggiungi un URL alla coda e un processo in background o un cron-job verifica regolarmente la presenza di nuovi lavori ed esegue richieste sull'URL

+1 per varie opzioni interessanti a cui non avevo pensato prima
Jasdeep Khalsa

"Penso che richieda solo le intestazioni" - Forse, ma non c'è nulla che impedisca a un documento di inviare un corpo di risposta completo in risposta a una richiesta HEAD. E presumo che questo metodo userebbe fsock sotto il cofano e lo costringerebbe ad aspettare (e leggere) la risposta completa.
hiburn8

6

Non lo fai. Sebbene PHP offra molti modi per chiamare un URL, non offre supporto immediato per eseguire alcun tipo di elaborazione asincrona / threaded per ciclo di richiesta / esecuzione. Qualsiasi metodo per inviare una richiesta per un URL (o un'istruzione SQL o un ecc.) Aspetterà un qualche tipo di risposta. Avrai bisogno di un qualche tipo di sistema secondario in esecuzione sulla macchina locale per ottenere ciò (google in giro per "coda di lavoro php")


1
C'è un trucco qui: stackoverflow.com/questions/124462/asynchronous-php-calls (risposta di Christian Davén) ma sono d'accordo che una coda sarebbe il modo giusto per farlo.
Chris Cinelli

Penso che questa risposta del 2009 sia ormai obsoleta. La libreria Guzzle PHP ora ha il supporto per eseguire richieste simultanee e asincrone.
Simon East

6

Ti consiglierei una libreria PHP ben testata: 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 libreria Guzzle PHP ha anche il supporto per eseguire richieste simultanee e asincrone.
Simon East

Guzzle afferma di avere il supporto, ma testando il suo metodo postAsync sembra che esegua 150 ms in modo sincrono e quindi 2 ms in modo asincrono. Ho passato più di un'ora a cercare di risolverlo senza successo, non lo consiglierei.
Velizar Hristov

4

Se stai usando un ambiente Linux, puoi usare il comando exec di PHP per invocare il curl di linux. Ecco un codice di esempio, che creerà un post HTTP asincrono.

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

Questo codice non necessita di librerie PHP aggiuntive e può completare il post http in meno di 10 millisecondi.


1
questa è una pessima idea: l'executive fallisce molto: immagina che 6/200 clienti non riceveranno la loro email di conferma per una prenotazione pagata ...
HellBaby

Questo ha funzionato per me, dato che ho solo bisogno di un ping per avviare un altro script su un altro server. L'ho appena usato in questo modo: _async_http_post ($ url, ''); E questo funziona sui server OVH mutualizzati ... Il che è fantastico.
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);
}

Potresti fargli restituire un oggetto che ti consente di chiamare getstatus()o waitSend()o waitResult(). In questo modo, il chiamante può ottenere un comportamento completamente asincrono chiamando un ciclo per verificare se ci sono risultati e, in caso contrario, continuare su qualsiasi altra attività in esecuzione. Hmm, ora voglio portare Taskda .net a php ...
binki

3

Problema interessante. Immagino che tu voglia solo attivare un processo o un'azione sull'altro server, ma non importa quali sono i risultati e vuoi che il tuo script continui. Probabilmente c'è qualcosa in cURL che può farlo accadere, ma potresti prendere in considerazione l'utilizzo exec()per eseguire un altro script sul server che esegue la chiamata se cURL non può farlo. (In genere le persone vogliono i risultati della chiamata allo script, quindi non sono sicuro che PHP abbia la capacità di attivare semplicemente il processo.) Con exec()potresti eseguire uno wgeto anche un altro script PHP che fa la richiesta con file_get_conents().


2

È meglio considerare l'utilizzo di code di messaggi invece dei metodi consigliati. Sono sicuro che questa sarà una soluzione migliore, anche se richiede un po 'più di lavoro rispetto al semplice invio di una richiesta.


2

lascia che ti mostri la mia strada :)

richiede che nodejs sia installato sul server

(il mio server invia 1000 richieste get https richiede solo 2 secondi)

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
Questa non è una soluzione PHP pura.
binki

2

Per me la domanda sulla richiesta GET asincrona è apparsa perché ho incontrato una situazione in cui ho bisogno di fare centinaia di richieste , ottenere e gestire i dati dei risultati su ogni richiesta e ogni richiesta richiede significativi millisecondi di esecuzione che portano a minuti (!) Di esecuzione totale con simple file_get_contents.

In questo caso è stato molto utile il commento di w_haigh su php.net sulla funzione http://php.net/manual/en/function.curl-multi-init.php

Quindi, ecco la mia versione aggiornata e pulita di fare molte richieste contemporaneamente. Per il mio caso è equivalente al modo "asincrono". Può essere d'aiuto per qualcuno!

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

È facile riscriverlo per gestire POST o altri tipi di richieste HTTP (S) o qualsiasi loro combinazione. E supporto per cookie, reindirizzamenti, http-auth, ecc.


Ohh .. vedo la domanda creata nel 2009 e scrivo la mia risposta nel 2016 :) Ma molti di noi google php diventano asincroni e sono venuti qui.
FlameStorm

Sì, sono venuto qui anche quando cercavo su Google. Alcuni programmatori potrebbero anche voler esaminare la libreria PHP Guzzle che ha il supporto per eseguire richieste simultanee e asincrone.
Simon East

1

Provare:

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

Questo NON funzionerà come un modulo Apache, devi usare CGI.


1

Ho trovato questo collegamento interessante per eseguire l'elaborazione asincrona (ottenere la richiesta).

askapache

Inoltre è possibile eseguire un'elaborazione asincrona utilizzando una coda di messaggi come ad esempio beanstalkd.


1

Ecco un adattamento della risposta accettata per l'esecuzione di una semplice richiesta GET.

Una cosa da notare se il server esegue una riscrittura dell'URL, questo non funzionerà. Dovrai utilizzare un client http più completo.

  /**
   * 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 poche correzioni sugli script pubblicati sopra. Quanto segue sta funzionando per me

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

Ho un problema, dove fwrite restituisce un numero positivo di byte, ma l'endpoint dello script non viene chiamato (non sta registrando) .. funziona solo quando uso: while (! Feof ($ fp)) {fgets ($ fp , 128); }
Miguel

1

Nessuno sembra menzionare Guzzle , che è un client HTTP PHP che semplifica l'invio di richieste HTTP. Può funzionare con o senza Curl. Può inviare richieste sia sincrone che asincrone.

$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ì, molte delle risposte in questo thread sono piuttosto vecchie, ma Guzzle è sicuramente l'opzione migliore che ho incontrato nel 2018, grazie per la pubblicazione.
Simon East

0

Sulla base di questo thread l'ho creato per il mio progetto di codeigniter. Funziona benissimo. È possibile elaborare qualsiasi funzione in background.

Un controller che accetta le chiamate asincrone.

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 una libreria che esegue le chiamate asincrone

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

Questo metodo può essere chiamato per elaborare qualsiasi model :: method () in "background". Utilizza argomenti variabili.

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

0

Suggerimento: formatta una pagina HTML FRAMESET che contiene, diciamo, 9 frame al suo interno. Ogni frame OTTERRÀ una diversa "istanza" della tua pagina myapp.php. Ci saranno 9 diversi thread in esecuzione sul server Web, in parallelo.


0

Per PHP5.5 +, mpyw / co è la soluzione definitiva. Funziona come se fosse tj / co in JavaScript.

Esempio

Supponi di voler scaricare gli avatar di più utenti GitHub specificati. I seguenti passaggi sono necessari per ogni utente.

  1. Ottieni il contenuto di http://github.com/mpyw (GET HTML)
  2. Trovalo <img class="avatar" src="...">e richiedilo (OTTIENI IMMAGINE)

---: Aspettando la mia risposta
... : In attesa di altra risposta in flussi paralleli

Molti famosi curl_multiscript basati ci forniscono già i seguenti flussi.

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

Tuttavia, questo non è abbastanza efficiente. Vuoi ridurre i tempi di attesa inutili ...?

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

Sì, è molto semplice con mpyw / co. Per maggiori dettagli, visita la pagina del repository.


-1

Ecco la mia funzione PHP quando eseguo il POST a un URL specifico di qualsiasi pagina ....

Esempio: * utilizzo della mia funzione ...

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

Prova questo codice ...

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

Non dimenticare di abilitare l'estensione php CURL.


È possibile impostare CURLOPT_TIMEOUT_MSad esempio 100 millisecondi invece dei CURLOPT_TIMEOUTsecondi e ha un minimo di 1 secondo - per un'esecuzione più rapida.
Jason Silver

-5

Questo funziona bene per me, purtroppo non puoi recuperare la risposta dalla tua richiesta:

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

Funziona molto velocemente, non c'è bisogno di socket TCP non elaborati :)


Questa funzione aggiunge un'intestazione alla risposta ... non invia una richiesta di intestazione. php.net/manual/bg/function.header.php
Lachezar Todorov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.