मैं PHP में एसिंक्रोनस GET अनुरोध कैसे करूँ?


97

मैं एक अलग सर्वर पर अन्य स्क्रिप्ट के लिए एक सरल GET अनुरोध करना चाहता हूं। मैं यह कैसे करु?

एक मामले में, मुझे किसी भी आउटपुट की आवश्यकता के बिना एक बाहरी स्क्रिप्ट का अनुरोध करने की आवश्यकता है।

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

दूसरे मामले में, मुझे टेक्स्ट आउटपुट प्राप्त करने की आवश्यकता है।

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

सच कहूं, तो मैं CURL के साथ खिलवाड़ नहीं करना चाहता क्योंकि यह वास्तव में CURL का काम नहीं है। मैं भी http_get का उपयोग नहीं करना चाहता क्योंकि मेरे पास PECL एक्सटेंशन नहीं है।

क्या फोसकॉपेन काम करेगा? यदि हां, तो मैं फ़ाइल की सामग्री में पढ़े बिना यह कैसे करूं? क्या कोई और रास्ता नहीं है?

सबको शुक्रीया

अपडेट करें

मुझे जोड़ा जाना चाहिए, पहले मामले में, मैं कुछ भी वापस करने के लिए स्क्रिप्ट का इंतजार नहीं करना चाहता। जैसा कि मैं समझता हूं कि file_get_contents () पृष्ठ का पूरी तरह से लोड होने का इंतजार करेगा आदि?


6
@William: हाँ, अधिकांश प्रश्नों को स्वयं के सटीक डुप्लिकेट माना जा सकता है। 8-) मुझे लगता है कि आपने गलत लिंक पोस्ट किया है ...
रिचीहिन्डल


1
मैं लिंक Musicfreak पोस्ट करने का मतलब है, मेरे टैब मिलाया ;-)
विलियम ब्रेंडल

2
@ रीची: अधिकांश प्रश्न? ;)
साशा चेदिगोव

1
मैंने प्रश्न को दूसरे से अलग करने के लिए इसे वापस लिया, क्योंकि ऐसा लगता है कि आप एक अनुरोध करना चाहते हैं जो प्रतिक्रिया का उपयोग करने के बारे में परवाह नहीं करता है (इसलिए यह बाकी स्क्रिप्ट के रूप में हो सकता है)। अगर मैं गलत हूँ तो इसे वापस कर दें!
dbr

जवाबों:


52

file_get_contents जो चाहोगे, करोगे

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

संपादित करें: GET अनुरोध को बंद करने और तुरंत लौटने का एक तरीका।

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

यह क्या करता है एक सॉकेट खुला है, एक अनुरोध प्राप्त करें, और तुरंत सॉकेट बंद करें और वापस लौटें।


6
curl_post_async एक पोस्ट अनुरोध भेजता है, एक GET नहीं।
विंको वर्सालोविच

13
क्या मैं यह कहने में सही हूं कि इस समारोह का नाम अनुचित है? यह वास्तव में कर्ल पुस्तकालय के साथ कुछ नहीं करना है। यह fsock_post_async () इसे अधिक पसंद करता है
मीकमको

61
यह async नहीं है! विशेष रूप से अगर दूसरी तरफ सर्वर कोड के इस टुकड़े को 30 सेकंड के लिए लटकाएगा (फॉक्सोपोपेन में 5 वां पैरामीटर)। इसके अलावा फाइटाइट को निष्पादित करने के लिए आपका मीठा समय लेने वाला है (कि आप stream_set_timeout ($ fp, $ my_timeout) के साथ सीमित कर सकते हैं। सबसे अच्छा आप जो कर सकते हैं वह है fsockopen पर कम मध्यांतर को 0.1 (100ms) और $ my_timeout को 100ms में सेट करना। । आप हालांकि जोखिम, कि अनुरोध का समय समाप्त।
क्रिस Cinelli

4
यह async के साथ कुछ नहीं करना है। यह उतना ही सिंक है जितना कि यह हो जाता है ... Async का अर्थ है अन्य कार्य करना जबकि यह कार्य पूरा हो रहा है। यह समानांतर निष्पादन है।
कोडएन्ज्री

17
यह न तो async है और न ही यह कर्ल का उपयोग कर रहा है, आप इसे कॉल करने की हिम्मत कैसे करते हैं curl_post_asyncऔर यहां तक ​​कि उठते हैं ...
डैनियल डब्ल्यू।

33

इस तरह से POST और 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
यह एक आसान कोड स्निपेट है, और मैं इसे इधर-उधर इस्तेमाल कर रहा हूं, लेकिन अब मुझे पता चला है कि मुझे एक ही काम करने की जरूरत है, लेकिन एक एसएसएल साइट के साथ। क्या मुझे HTTP / 1.1 प्रकार और पोर्ट के अलावा कुछ भी बदलने की आवश्यकता है?
केविन झंगियानी

2
SSL के लिए इसका उपयोग करने के बारे में सवाल करने के लिए प्रतिक्रिया में आप पोर्ट को 443 में और ssl को जोड़कर SSL बना सकते हैं: // fsockopen में पोर्ट नाम के लिए: $ fp = fsockopen ("ssl:" "। $ Parts ['host) '],
माइकल डॉगर

1
"क्या मुझे HTTP / 1.1 प्रकार और पोर्ट के अलावा कुछ भी बदलने की आवश्यकता है?" - हाँ, आपको होस्टनाम के साथ fsockopen () को कॉल करना चाहिए ssl://hostnameबजाय इसके कि hostname
काउलबी

22
यह async नहीं है! विशेष रूप से अगर दूसरी तरफ सर्वर कोड के इस टुकड़े को 30 सेकंड के लिए लटकाएगा (फॉक्सोपोपेन में 5 वां पैरामीटर)। इसके अलावा फाइटाइट को निष्पादित करने के लिए आपका मीठा समय लेने वाला है (कि आप stream_set_timeout ($ fp, $ my_timeout) के साथ सीमित कर सकते हैं। सबसे अच्छा आप जो कर सकते हैं वह है fsockopen पर कम मध्यांतर को 0.1 (100ms) और $ my_timeout को 100ms में सेट करना। । आप हालांकि जोखिम, कि अनुरोध का समय समाप्त।
क्रिस Cinelli

1
GET के लिए सामग्री-लंबाई निर्धारित नहीं की जानी चाहिए। हो सकता है कि कुछ परिदृश्यों में त्रुटि का कारण न बने, लेकिन मेरे मामले में परिणामस्वरूप अनुरोध को php स्क्रिप्ट द्वारा संसाधित नहीं किया जा रहा है।
user3285954

13

आपके अपडेट के बारे में, लोड होने के लिए पूरे पृष्ठ की प्रतीक्षा नहीं करने के बारे में - मुझे लगता है कि एक HTTP HEADअनुरोध वह है जो आप खोज रहे हैं ..

get_headers को यह करना चाहिए - मुझे लगता है कि यह केवल हेडर का अनुरोध करता है, इसलिए पूर्ण पृष्ठ सामग्री नहीं भेजी जाएगी।

"PHP / कर्ल: HEAD अनुरोध कुछ साइटों पर एक लंबा समय लगता है"HEAD PHP / कर्ल का उपयोग करके अनुरोध करने का तरीका बताता है

यदि आप अनुरोध को ट्रिगर करना चाहते हैं, और स्क्रिप्ट को बिल्कुल भी नहीं पकड़ना चाहते हैं, तो कुछ तरीके हैं, अलग-अलग जटिलताएं ।।

  • HTTP अनुरोध को पृष्ठभूमि प्रक्रिया के रूप में निष्पादित करें, php एक पृष्ठभूमि प्रक्रिया निष्पादित करें - मूल रूप से आप कुछ ऐसा निष्पादित करेंगे"wget -O /dev/null $carefully_escaped_url" - यह प्लेटफ़ॉर्म विशिष्ट होगा, और आपको मापदंडों से बचने के लिए कमांड के बारे में वास्तव में सावधान रहना होगा
  • पृष्ठभूमि में एक PHP स्क्रिप्ट निष्पादित करना - मूल रूप से UNIX प्रक्रिया विधि के समान है, लेकिन शेल कमांड के बजाय PHP स्क्रिप्ट को निष्पादित करना
  • एक डेटाबेस (या बीनस्टॉकड की तरह कुछ जो संभावना अधिक है) का उपयोग करके एक "नौकरी कतार" है । आप कतार में एक URL जोड़ते हैं, और एक पृष्ठभूमि प्रक्रिया या क्रोन-नौकरी नियमित रूप से नई नौकरियों के लिए जाँच करता है और URL पर अनुरोध करता है

+1 विभिन्न दिलचस्प विकल्पों के लिए जो मैंने पहले नहीं सोचा है
जसदीप खालसा

"मुझे लगता है कि यह केवल हेडर का अनुरोध करता है" - शायद, लेकिन एक हेडा अनुरोध के जवाब में एक पूर्ण प्रतिक्रिया निकाय भेजने से दस्तावेज़ को रोकने के लिए कुछ भी नहीं है। और मुझे लगता है कि यह विधि हुड के नीचे फॉक का उपयोग करेगी और इसे पूर्ण प्रतिक्रिया के लिए प्रतीक्षा करने (और पढ़ने) के लिए मजबूर करेगी।
हिबर्न 8

6

तुम नहीं। जबकि PHP एक URL को कॉल करने के लिए बहुत सारे तरीके प्रदान करता है, यह किसी भी प्रकार के एसिंक्रोनस / थ्रेडेड प्रसंस्करण प्रति अनुरोध / निष्पादन चक्र को करने के लिए बॉक्स समर्थन से बाहर की पेशकश नहीं करता है। URL (या SQL स्टेटमेंट, या आदि) के लिए रिक्वेस्ट भेजने का कोई भी तरीका किसी तरह की प्रतिक्रिया का इंतजार करने वाला है । इसे प्राप्त करने के लिए आपको स्थानीय मशीन पर किसी प्रकार की द्वितीयक प्रणाली चलाने की आवश्यकता होगी ("php job queue" के लिए चारों ओर)


1
यहाँ एक हैक है: stackoverflow.com/questions/124462/asynchronous-php-calls (क्रिश्चियन डेवन द्वारा उत्तर) लेकिन मैं मानता हूं कि एक कतार इसे करने का सही तरीका होगा।
क्रिस सिनेली

मुझे लगता है कि 2009 से यह उत्तर अब पुराना हो चुका है। Guzzle पीएचपी पुस्तकालय अब समवर्ती और अतुल्यकालिक अनुरोध करने के लिए समर्थन हासिल है।
साइमन ईस्ट

6

मैं आपको अच्छी तरह से PHP लाइब्रेरी का परीक्षण करने की सलाह दूंगा : कर्ल-आसान

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

Guzzle पीएचपी पुस्तकालय भी समवर्ती और अतुल्यकालिक अनुरोध करने के लिए समर्थन हासिल है।
साइमन ईस्ट

गज़ल का दावा है कि इसका समर्थन है, लेकिन इसके पोस्टएस्क्यूनिक विधि का परीक्षण ऐसा लगता है कि यह 150 एमएस सिंक्रोनाइज़ करता है, और फिर 2 एमएस असिंक्रोनस रूप से। मैंने एक घंटे से अधिक समय बिताया है कि इसे सफलता के बिना ठीक करने की कोशिश कर रहा हूं - यह अनुशंसा नहीं करेगा।
वेलिज़र हिस्ट्रोव

4

यदि आप लिनक्स वातावरण का उपयोग कर रहे हैं तो आप लिनक्स कर्ल को लागू करने के लिए PHP के निष्पादन कमांड का उपयोग कर सकते हैं। यहाँ एक नमूना कोड है, जो एक एसिंक्रोनस HTTP पोस्ट बना देगा।

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

इस कोड को किसी भी अतिरिक्त PHP कामों की आवश्यकता नहीं है और यह 10 मिलीसेकंड से भी कम समय में http पद को पूरा कर सकता है।


1
यह एक बहुत बुरा विचार है: निष्पादन बहुत विफल रहता है: कल्पना करें कि 6/200 ग्राहकों को एक भुगतान की गई बुकिंग के लिए अपना ईमेल पुष्टिकरण नहीं मिलेगा ...
हेलबैबी

यह मेरे लिए काम कर रहा था, जहाँ तक मुझे बस एक स्क्रिप्ट को दूसरे सर्वर पर शुरू करने के लिए एक पिंग की आवश्यकता है। मैंने इसे बस इस तरह इस्तेमाल किया: _async_http_post ($ url, ''); और यह OVH के म्यूचुअल सर्वर पर काम कर रहा है ... जो बहुत अच्छा है।
किलोगोग

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

आप इसे एक ऐसी वस्तु लौटा सकते हैं जिससे आप कॉल getstatus()कर सकते हैं या waitSend()या waitResult()। इस तरह, कॉल करने वाले को यह पता लगाने के लिए कि क्या परिणाम हैं और यदि कोई अन्य कार्य चल रहा है, तो जारी रखने के लिए लूप में कॉल करके पूरी तरह से async व्यवहार प्राप्त कर सकते हैं। हम्म, अब मैं Task.net से php ...
binki

3

दिलचस्प समस्या है। मैं आपको अनुमान लगा रहा हूं कि आप दूसरे सर्वर पर कुछ प्रक्रिया या कार्रवाई को ट्रिगर करना चाहते हैं, लेकिन परवाह नहीं करते कि परिणाम क्या हैं और आपकी स्क्रिप्ट जारी रखना चाहते हैं। CURL में शायद कुछ ऐसा है जो ऐसा कर सकता है, लेकिन आप exec()सर्वर पर एक और स्क्रिप्ट चलाने के लिए उपयोग करने पर विचार कर सकते हैं जो कॉल करता है अगर cURL ऐसा नहीं कर सकता है। (आमतौर पर लोग स्क्रिप्ट कॉल के परिणाम चाहते हैं इसलिए मुझे यकीन नहीं है कि अगर PHP में प्रक्रिया को ट्रिगर करने की क्षमता है।) exec()आप के साथ एक wgetया एक और PHP स्क्रिप्ट चला सकते हैं जो अनुरोध करता है file_get_conents()


2

आप सलाह दी गई विधियों के बजाय संदेश कतारों का उपयोग करने पर बेहतर विचार करेंगे। मुझे यकीन है कि यह बेहतर समाधान होगा, हालांकि इसे केवल अनुरोध भेजने की तुलना में थोड़ी अधिक नौकरी की आवश्यकता है।


2

मुझे अपना रास्ता दिखाने दो :)

सर्वर पर नोडज की जरूरत है

(मेरा सर्वर 1000 https भेजता है अनुरोध केवल 2 सेकंड लगते हैं)

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
यह एक शुद्ध PHP समाधान नहीं है।
बिंकी

2

मेरे लिए एसिंक्रोनस GET अनुरोध के बारे में प्रश्न इसलिए प्रकट होता है क्योंकि मैं उस स्थिति से मिला था जब मुझे सैकड़ों अनुरोध करने की आवश्यकता थी , प्राप्त करें और हर अनुरोध पर परिणाम डेटा के साथ व्यवहार करें और हर अनुरोध मिनटों (!) को निष्पादित करने के महत्वपूर्ण मिलीसेकंड लेता है । सरल के साथ कुल निष्पादनfile_get_contents

इस मामले में यह फ़ंक्शन पर http://pp.net/manual/en/function.curl-multi-init.php पर php.net पर w_haigh की बहुत उपयोगी टिप्पणी थी

तो, यहाँ एक साथ बहुत सारे अनुरोध करने का मेरा उन्नत और साफ संस्करण है। मेरे मामले के लिए यह "अतुल्यकालिक" तरीके के बराबर है। हो सकता है कि यह किसी के लिए मदद करे!

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

POST या अन्य प्रकार के HTTP (S) अनुरोधों या उनमें से किसी भी संयोजन को संभालने के लिए इसे फिर से लिखना आसान है। और कुकी समर्थन, पुनर्निर्देशन, http- स्थिति, आदि।


ओह .. मैं 2009 में बनाया गया प्रश्न देखता हूं, और मैं 2016 में अपना उत्तर लिखता हूं :) लेकिन हम में से बहुत से लोग Google एसिंक्रोनस प्राप्त करते हैं और यहां आए हैं।
फ्लेमस्टॉर्म

हाँ मैं भी यहाँ आया था जब Googling। कुछ कोडर भी गुज़ल PHP लाइब्रेरी में देखना चाहते हैं जिन्हें समवर्ती और अतुल्यकालिक अनुरोध करने के लिए समर्थन प्राप्त है।
साइमन ईस्ट

1

प्रयत्न:

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

यह अपाचे मॉड्यूल के रूप में काम नहीं करेगा, आपको सीजीआई का उपयोग करने की आवश्यकता है।


1

मुझे अतुल्यकालिक प्रसंस्करण (अनुरोध प्राप्त करें) करने के लिए यह दिलचस्प लिंक मिला।

askapache

इसके अलावा आप उदाहरण beanstalkd की तरह एक संदेश कतार का उपयोग करके अतुल्यकालिक प्रसंस्करण कर सकते हैं।


1

यहाँ एक सरल GET अनुरोध करने के लिए स्वीकृत उत्तर का अनुकूलन है।

एक बात ध्यान रखें कि यदि सर्वर कोई यूआरएल पुनः लिखना चाहता है, तो यह काम नहीं करेगा। आपको अधिक पूर्ण विशेषताओं वाले http क्लाइंट का उपयोग करना होगा।

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

ऊपर पोस्ट की गई स्क्रिप्ट पर बस कुछ सुधार। निम्नलिखित मेरे लिए काम कर रहा है

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

मुझे एक समस्या हो रही है, जहाँ फाइटाइट एक सकारात्मक संख्या में बाइट्स देता है, लेकिन स्क्रिप्ट एंडपॉइंट को नहीं बुलाया जाता है (लॉगिंग नहीं है) .. यह केवल तब काम करता है जब मैं उपयोग करता हूं: जबकि (! ($ Fp)) {फ़ोटोज़ ($ pp) , 128); }
मिगेल

1

किसी को भी गज़ल का उल्लेख नहीं लगता है , जो एक PHP HTTP क्लाइंट है जो HTTP अनुरोध भेजने में आसान बनाता है। यह साथ या बिना काम कर सकता है Curl। यह तुल्यकालिक और अतुल्यकालिक दोनों अनुरोध भेज सकता है।

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

हां, इस सूत्र में कई उत्तर काफी पुराने हैं, लेकिन गुज़ले निश्चित रूप से 2018 में सबसे अच्छा विकल्प है, जो पोस्ट करने के लिए धन्यवाद।
साइमन ईस्ट

0

इस धागे के आधार पर मैंने इसे अपने कोडिनिटर प्रोजेक्ट के लिए बनाया। यह ठीक काम करता है। आपके पास पृष्ठभूमि में संसाधित कोई भी फ़ंक्शन हो सकता है।

एक नियंत्रक जो एस्किंक कॉल को स्वीकार करता है।

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

और एक पुस्तकालय जो एसिंक्स कॉल करता है

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

इस पद्धति को 'पृष्ठभूमि' में किसी भी मॉडल :: विधि () को संसाधित करने के लिए कहा जा सकता है। यह परिवर्तनशील तर्कों का उपयोग करता है।

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

0

सुझाव: एक FRAMESET HTML पृष्ठ को प्रारूपित करें, जिसमें 9 फ्रेम अंदर हों। प्रत्येक फ्रेम आपके myapp.php पेज का एक अलग "उदाहरण" प्राप्त करेगा। समानांतर में वेब सर्वर पर 9 अलग-अलग थ्रेड चलेंगे।


0

PHP5.5 + के लिए, mpyw / co अंतिम समाधान है। यह काम करता है जैसे कि यह जावास्क्रिप्ट में tj / co है।

उदाहरण

मान लें कि आप कई GitHub उपयोगकर्ताओं के अवतार डाउनलोड करना चाहते हैं। प्रत्येक उपयोगकर्ता के लिए निम्न चरणों की आवश्यकता होती है।

  1. Http://github.com/mpyw की सामग्री प्राप्त करें (GET HTML) प्राप्त करें
  2. <img class="avatar" src="...">इसे ढूंढें और अनुरोध करें (प्राप्त करें)

---: मेरी प्रतिक्रिया की प्रतीक्षा है
... प्रतीक्षा: समानांतर प्रवाह में अन्य प्रतिक्रिया की प्रतीक्षा कर रहा है

कई प्रसिद्ध curl_multiआधारित स्क्रिप्ट पहले से ही हमें निम्न प्रवाह प्रदान करते हैं।

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

हालांकि, यह पर्याप्त कुशल नहीं है। क्या आप बेकार प्रतीक्षा समय को कम करना चाहते हैं ...?

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

हाँ, यह mpyw / सह के साथ बहुत आसान है। अधिक जानकारी के लिए, रिपॉजिटरी पेज पर जाएँ।


-1

यहाँ मेरा अपना PHP फंक्शन है जब मैं किसी भी पेज के एक विशिष्ट URL पर POST करता हूँ ...।

नमूना: * मेरे समारोह का उपयोग ...

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

इस कोड को आज़माएं…।

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

कृपया CURL php एक्सटेंशन को सक्षम करना न भूलें।


आप CURLOPT_TIMEOUT_MSउदाहरण के लिए 100 मिलिसेकंड सेट कर सकते हैं , CURLOPT_TIMEOUTजो सेकंड में है और तेजी से निष्पादन के लिए 1 सेकंड का एक मिनट है।
जेसन सिल्वर

-5

यह मेरे लिए ठीक काम करता है, दुख की बात है कि आप अपने अनुरोध से प्रतिक्रिया प्राप्त नहीं कर सकते हैं:

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

यह बहुत तेजी से काम करता है, कच्चे टीसीपी सॉकेट की कोई आवश्यकता नहीं है :)


यह फ़ंक्शन हेडर को प्रतिक्रिया में जोड़ता है ... यह हेडर अनुरोध नहीं भेज रहा है। php.net/manual/bg/function.header.php
लाचेज़र टोडोरोव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.