Comment faire une requête GET asynchrone en PHP?

97

Je souhaite faire une simple requête GET à un autre script sur un serveur différent. Comment puis-je faire cela?

Dans un cas, j'ai juste besoin de demander un script externe sans avoir besoin d'aucune sortie.

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

Dans le second cas, j'ai besoin d'obtenir la sortie texte.

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

Pour être honnête, je ne veux pas jouer avec CURL car ce n'est pas vraiment le travail de CURL. Je ne veux pas non plus utiliser http_get car je n'ai pas les extensions PECL.

Fsockopen fonctionnerait-il? Si tel est le cas, comment faire cela sans lire le contenu du fichier? N'y a-t-il pas d'autre moyen?

Merci a tous

Mettre à jour

J'aurais dû ajouter, dans le premier cas, je ne veux pas attendre que le script retourne quoi que ce soit. Si je comprends bien, file_get_contents () attendra que la page se charge complètement, etc.?

Abdos
la source
6
@William: Oui, la plupart des questions peuvent être considérées comme des doubles d'elles-mêmes. 8-) Je pense que vous avez posté le mauvais lien ...
RichieHindle
Dupliquer: stackoverflow.com/questions/959063/…
Sasha Chedygov
1
Je voulais poster le lien posté par musicfreak, mélangé mes onglets ;-)
William Brendel
2
@Richie: La plupart des questions? ;)
Sasha Chedygov
1
J'ai renommé la question pour la différencier de l'autre, car il semble que vous vouliez faire une demande, ne vous souciez pas de l'utilisation de la réponse (cela peut donc se produire pendant que le reste du script s'exécute). Revenez-le si je me trompe!
dbr

Réponses:

52

file_get_contents fera ce que tu veux

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

Edit: Une façon de déclencher une demande GET et de revenir immédiatement.

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

Ce que cela fait est d'ouvrir un socket, de lancer une requête get, et de fermer immédiatement le socket et de revenir.

Marquis Wang
la source
6
curl_post_async envoie une requête POST, pas un GET.
Vinko Vrsalovic
13
Ai-je raison de dire que cette fonction est mal nommée? Cela n'a vraiment rien à voir avec la bibliothèque curl. C'est fsock_post_async () plus comme ça
MikeMurko
61
Ce n'est PAS asynchrone! En particulier, si le serveur de l'autre côté est en panne, ce morceau de code restera suspendu pendant 30 secondes (le 5ème paramètre dans le fsockopen). De plus, le fwrite va prendre son temps pour s'exécuter (que vous pouvez limiter avec stream_set_timeout ($ fp, $ my_timeout). Le mieux que vous puissiez faire est de définir un délai d'expiration bas sur fsockopen à 0,1 (100 ms) et $ my_timeout à 100 ms . Vous risquez cependant que la demande expire.
Chris Cinelli
4
Cela n'a rien à voir avec async. C'est aussi synchronisé que possible ... Async signifie faire d'autres tâches pendant que cette tâche est en cours d'exécution. C'est une exécution parallèle.
CodeAngry
17
Ce n'est ni asynchrone ni n'utilise curl, comment vous osez l'appeler curl_post_asyncet obtenir même des votes positifs ...
Daniel W.
33

Voici comment faire fonctionner la réponse de Marquis avec les requêtes POST et 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);
  }
catgofire
la source
2
C'est un extrait de code pratique, et je l'utilise ici et là, mais je trouve maintenant que je dois faire la même chose, mais avec un site SSL. Dois-je changer quelque chose en plus du type HTTP / 1.1 et du port?
Kevin Jhangiani
2
En réponse à une question sur l'utilisation de ceci pour SSL, vous pouvez le rendre SSL en changeant le port en 443 et en ajoutant ssl: // au nom du port dans fsockopen: $ fp = fsockopen ("ssl: //". $ Parts ['host '],
Michael Dogger
1
"Y a-t-il quelque chose que je dois changer en plus du type HTTP / 1.1 et du port?" - Oui, vous devriez appeler fsockopen () avec le nom d'hôte au ssl://hostnamelieu de juste hostname.
Cowlby
22
Ce n'est PAS asynchrone! En particulier, si le serveur de l'autre côté est en panne, ce morceau de code restera suspendu pendant 30 secondes (le 5ème paramètre dans le fsockopen). De plus, le fwrite va prendre son temps pour s'exécuter (que vous pouvez limiter avec stream_set_timeout ($ fp, $ my_timeout). Le mieux que vous puissiez faire est de définir un délai d'expiration bas sur fsockopen à 0,1 (100 ms) et $ my_timeout à 100 ms . Vous risquez cependant que la demande expire.
Chris Cinelli
1
Content-Length ne doit pas être défini pour GET. Peut-être que dans certains scénarios, cela ne provoque pas d'erreur, mais dans mon cas, la demande n'a pas été traitée par le script PHP appelé.
user3285954
13

En ce qui concerne votre mise à jour, ne pas vouloir attendre le chargement de la page complète - je pense qu'une HEADrequête HTTP est ce que vous recherchez.

get_headers devrait le faire - je pense qu'il ne demande que les en-têtes, donc ne sera pas envoyé le contenu de la page complète.

"PHP / Curl: HEAD Request prend beaucoup de temps sur certains sites" décrit comment faire une HEADrequête en utilisant PHP / Curl

Si vous souhaitez déclencher la requête et ne pas retarder du tout le script, il existe plusieurs moyens, de complexité variable.

  • Exécutez la requête HTTP en tant que processus d'arrière-plan, php exécutez un processus d'arrière-plan - en gros, vous exécuteriez quelque chose comme "wget -O /dev/null $carefully_escaped_url"- ce sera spécifique à la plate-forme, et vous devez faire très attention à échapper les paramètres à la commande
  • Exécuter un script PHP en arrière-plan - - essentiellement la même que la méthode de processus UNIX, mais exécuter un script PHP plutôt qu'une commande shell
  • Avoir une "file d'attente de travaux", en utilisant une base de données (ou quelque chose comme beanstalkd qui est probablement exagéré). Vous ajoutez une URL à la file d'attente, et un processus d'arrière-plan ou cron-job vérifie régulièrement les nouveaux travaux et exécute des demandes sur l'URL
dbr
la source
+1 pour diverses options intéressantes auxquelles je n'avais pas pensé auparavant
Jasdeep Khalsa
"Je pense qu'il ne demande que les en-têtes" - Peut-être, mais rien n'empêche un document d'envoyer un corps de réponse complet en réponse à une demande HEAD. Et je suppose que cette méthode utiliserait fsock sous le capot et le forcerait à attendre (et à lire) la réponse complète.
hiburn8
6

Vous ne le faites pas. Bien que PHP offre de nombreuses façons d'appeler une URL, il n'offre pas de support prêt à l'emploi pour effectuer tout type de traitement asynchrone / threadé par cycle de requête / exécution. Toute méthode d'envoi d'une requête pour une URL (ou une instruction SQL, ou un etc.) va attendre une sorte de réponse. Vous aurez besoin d'une sorte de système secondaire fonctionnant sur la machine locale pour y parvenir (google around for "php job queue")

Alan Storm
la source
1
Il y a un hack ici: stackoverflow.com/questions/124462/asynchronous-php-calls (réponse de Christian Davén) mais je suis d'accord qu'une file d'attente serait la bonne façon de le faire.
Chris Cinelli
Je pense que cette réponse de 2009 est désormais dépassée. La bibliothèque PHP Guzzle prend désormais en charge les requêtes simultanées et asynchrones.
Simon East
6

Je vous recommanderais une bibliothèque PHP bien testée: 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
}
encore
la source
La bibliothèque PHP Guzzle prend également en charge les requêtes simultanées et asynchrones.
Simon East
Guzzle prétend qu'il dispose d'un support, mais tester sa méthode postAsync semble faire 150 ms de manière synchrone, puis 2 ms de manière asynchrone. J'ai passé plus d'une heure à essayer de le réparer sans succès - je ne le recommanderais pas.
Velizar Hristov
4

Si vous utilisez un environnement Linux, vous pouvez utiliser la commande exec de PHP pour invoquer linux curl. Voici un exemple de code, qui fera une publication HTTP asynchrone.

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

Ce code n'a pas besoin de bibliothèques PHP supplémentaires et il peut terminer la publication http en moins de 10 millisecondes.

Étranger
la source
1
c'est une très mauvaise idée: l'exécutif échoue beaucoup: imaginez que 6/200 clients ne recevront pas leur e-mail de confirmation pour une réservation
payée
Cela a fonctionné pour moi, dans la mesure où j'ai juste besoin d'un ping pour démarrer un autre script sur un autre serveur. Je l'ai juste utilisé comme ça: _async_http_post ($ url, ''); Et cela fonctionne sur des serveurs mutualisés OVH ... Ce qui est génial.
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);
}
Amez
la source
Vous pouvez lui faire renvoyer un objet qui vous permet d'appeler getstatus()ou waitSend()ou waitResult(). De cette façon, l'appelant peut obtenir un comportement totalement asynchrone en appelant dans une boucle pour vérifier s'il y a des résultats et, sinon, continuer sur toute autre tâche en cours d'exécution. Hmm, maintenant je veux porter Taskde .net à php…
binki
3

Problème intéressant. Je suppose que vous voulez simplement déclencher un processus ou une action sur l'autre serveur, mais ne vous souciez pas des résultats et que vous voulez que votre script continue. Il y a probablement quelque chose dans cURL qui peut rendre cela possible, mais vous pouvez envisager d'utiliser exec()pour exécuter un autre script sur le serveur qui effectue l'appel si cURL ne peut pas le faire. (En général, les gens veulent les résultats de l'appel de script, donc je ne suis pas sûr que PHP ait la capacité de simplement déclencher le processus.) Avec, exec()vous pouvez exécuter un wgetou même un autre script PHP qui fait la demande avec file_get_conents().

Darryl Hein
la source
2

Vous feriez mieux d'envisager d'utiliser Message Queues au lieu des méthodes conseillées. Je suis sûr que ce sera une meilleure solution, même si cela nécessite un peu plus de travail que l'envoi d'une simple demande.

mra214
la source
2

laissez-moi vous montrer mon chemin :)

nécessite que nodejs soit installé sur le serveur

(mon serveur envoie 1000 https get request ne prend que 2 secondes)

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);
}
user1031143
la source
1
Ce n'est pas une solution PHP pure.
binki
2

Pour moi, la question sur la demande GET asynchrone est apparue parce que j'ai rencontré une situation où je dois faire des centaines de demandes , obtenir et traiter des données de résultat à chaque demande et que chaque demande prend des millisecondes significatives d'exécution, ce qui conduit à des minutes (!) De exécution totale avec simplefile_get_contents .

Dans ce cas, c'était un commentaire très utile de w_haigh sur php.net sur la fonction http://php.net/manual/en/function.curl-multi-init.php

Alors, voici ma version améliorée et nettoyée de faire beaucoup de demandes simultanément. Pour mon cas, c'est équivalent à la manière "asynchrone". Peut-être que cela aide quelqu'un!

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

Il est facile de réécrire ceci pour gérer POST ou d'autres types de requêtes HTTP (S) ou toute combinaison de celles-ci. Et le support des cookies, les redirections, http-auth, etc.

FlameStorm
la source
Ohh .. Je vois la question créée en 2009, et j'écris ma réponse en 2016 :) Mais beaucoup d'entre nous google php deviennent asynchrones et sont venus ici.
FlameStorm
Oui, je suis également venu ici lorsque je faisais des recherches sur Google. Certains codeurs voudront peut-être également consulter la bibliothèque PHP Guzzle qui prend en charge les requêtes simultanées et asynchrones.
Simon East
1

Essayer:

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

Cela ne fonctionnera PAS comme un module Apache, vous devez utiliser CGI.

LM.
la source
1

J'ai trouvé ce lien intéressant pour faire un traitement asynchrone (get request).

askapache

De plus, vous pouvez effectuer un traitement asynchrone en utilisant une file d'attente de messages comme par exemple beanstalkd.

Alfred
la source
1

Voici une adaptation de la réponse acceptée pour effectuer une simple requête GET.

Une chose à noter si le serveur effectue une réécriture d'url, cela ne fonctionnera pas. Vous devrez utiliser un client http plus complet.

  /**
   * 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);
  }
blak3r
la source
1

Juste quelques corrections sur les scripts postés ci-dessus. Ce qui suit fonctionne pour moi

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);
    }
A23
la source
J'ai un problème, où le fwrite renvoie un nombre positif d'octets, mais le point de terminaison du script n'est pas appelé (n'est pas en cours de journalisation) .. cela ne fonctionne que lorsque j'utilise: while (! Feof ($ fp)) {fgets ($ fp , 128); }
Miguel
1

Personne ne semble mentionner Guzzle , qui est un client HTTP PHP qui facilite l'envoi de requêtes HTTP. Cela peut fonctionner avec ou sans Curl. Il peut envoyer des requêtes synchrones et asynchrones.

$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();
    }
);
zstate
la source
Oui, la plupart des réponses de ce fil sont assez anciennes, mais Guzzle est certainement la meilleure option que j'ai rencontrée en 2018, merci d'avoir posté.
Simon East
0

Sur la base de ce fil, j'ai fait ceci pour mon projet codeigniter. Cela fonctionne très bien. Vous pouvez faire traiter n'importe quelle fonction en arrière-plan.

Un contrôleur qui accepte les appels asynchrones.

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

Et une bibliothèque qui fait les appels asynchrones

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

Cette méthode peut être appelée pour traiter n'importe quel model :: method () dans le 'background'. Il utilise des arguments variables.

$this->load->library('daemon');
$this->daemon->execute_background( 'model', 'method', $arg1, $arg2, ... );
Patrick Savalle
la source
0

Suggestion: formatez une page HTML FRAMESET qui contient, disons, 9 cadres à l'intérieur. Chaque cadre obtiendra une "instance" différente de votre page myapp.php. Il y aura 9 threads différents en cours d'exécution sur le serveur Web, en parallèle.

newbie_dude
la source
0

Pour PHP5.5 +, mpyw / co est la solution ultime. Cela fonctionne comme si c'était tj / co en JavaScript.

Exemple

Supposons que vous souhaitiez télécharger les avatars de plusieurs utilisateurs GitHub spécifiés. Les étapes suivantes sont requises pour chaque utilisateur.

  1. Obtenez le contenu de http://github.com/mpyw (GET HTML)
  2. Trouvez <img class="avatar" src="...">et demandez (GET IMAGE)

---: En attente de ma réponse
... : En attente d'une autre réponse dans des flux parallèles

De nombreux curl_multiscripts basés célèbres nous fournissent déjà les flux suivants.

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

Cependant, ce n'est pas assez efficace. Voulez-vous réduire les temps d'attente inutiles ...?

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

Oui, c'est très simple avec mpyw / co. Pour plus de détails, visitez la page du référentiel.

mpyw
la source
-1

Voici ma propre fonction PHP lorsque je fais un POST sur une URL spécifique de n'importe quelle page ...

Exemple: * utilisation de ma fonction ...

<?php
    parse_str("[email protected]&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>
je suis ArbZ
la source
-2

Essayez ce code ...

$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'oubliez pas d'activer l'extension php CURL.

Mukesh
la source
Vous pouvez définir CURLOPT_TIMEOUT_MSpar exemple 100 millisecondes au lieu de CURLOPT_TIMEOUTce qui est en secondes et a un min de 1 seconde - pour une exécution plus rapide.
Jason Silver
-5

Cela fonctionne bien pour moi, malheureusement, vous ne pouvez pas récupérer la réponse de votre demande:

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

Cela fonctionne très vite, pas besoin de sockets TCP bruts :)

D4zk1tty
la source
Cette fonction ajoute un en-tête à la réponse ... elle n'envoie pas de demande d'en-tête. php.net/manual/bg/function.header.php
Lachezar Todorov