আমি কীভাবে পিএইচপি-তে একটি অ্যাসিঙ্ক্রোনাস জিইটি অনুরোধ করব?


98

আমি অন্য একটি সার্ভারের অন্য স্ক্রিপ্টে একটি সাধারণ জিইটি অনুরোধ করতে চাই। আমি এটা কিভাবে করবো?

একটি ক্ষেত্রে, আমাকে কেবল কোনও আউটপুটের প্রয়োজন ছাড়াই একটি বাহ্যিক স্ক্রিপ্টের জন্য অনুরোধ করতে হবে।

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

সত্যি কথা বলতে, আমি সিআরএল-এর সাথে গোলযোগ করতে চাই না কারণ এটি সত্যই সিআরএল এর কাজ নয়। আমি পিইসিএল এক্সটেনশন না থাকায় আমি http_get ব্যবহার করতে চাই না।

Fsockopen কাজ করবে? যদি তা হয় তবে আমি ফাইলটির বিষয়বস্তু না পড়ে কীভাবে এটি করব? অন্য কোন উপায় আছে কি?

সবাইকে ধন্যবাদ

হালনাগাদ

আমার যুক্ত হওয়া উচিত, প্রথম ক্ষেত্রে, আমি স্ক্রিপ্টটি কিছু ফেরত পাওয়ার জন্য অপেক্ষা করতে চাই না। আমি যেমন বুঝতে পেরেছি file_get_contents () পৃষ্ঠাটি পুরোপুরি লোড হওয়ার জন্য অপেক্ষা করবে?


6
@ উইলিয়াম: হ্যাঁ, বেশিরভাগ প্রশ্ন তাদের নিজের সঠিক সদৃশ হিসাবে বিবেচনা করা যেতে পারে। 8-) আমার মনে হয় আপনি ভুল লিঙ্কটি পোস্ট করেছেন ...
রিচিহাইন্ডল


4
আমি মিউজিকফ্রাইক লিঙ্কটি পোস্ট করেছি, আমার ট্যাবগুলি মিশ্রিত করেছি ;-)
উইলিয়াম ব্রেন্ডেল

4
@ রিচি: বেশিরভাগ প্রশ্ন? ;)
সাশা চেদিগোভ

4
এটিকে অন্যের থেকে আলাদা করার জন্য আমি প্রশ্নটি পুনঃপ্রবিষ্ট করেছিলাম, কারণ মনে হচ্ছে আপনি কোনও অনুরোধ তৈরি করতে চান প্রতিক্রিয়াটি ব্যবহার করার বিষয়ে চিন্তা করবেন না (যাতে এটি স্ক্রিপ্টের বাকী অংশটি চলতে পারে) can ভুল হলে আমি তা ফিরিয়ে দাও!
ডিবিআর

উত্তর:


52

file_get_contents আপনি যা চান তা করবে

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

সম্পাদনা করুন: একটি জিইটি অনুরোধ বন্ধ করে অবিলম্বে ফিরে আসার এক উপায়।

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 একটি জিইটি নয়, একটি পোষ্ট অনুরোধ প্রেরণ করে।
ভিঙ্কো ভার্সালোভিক

13
আমি কি ঠিক বলছি যে এই ফাংশনটির নাম দেওয়া হয়নি? কার্ল লাইব্রেরির সাথে এটির আসলে কোনও সম্পর্ক নেই। এটি fsock_post_async () এর মতো আরও
মাইকমুরকো

62
এটি async না! বিশেষত যদি অন্য পাশের সার্ভারটি নীচে থাকে তবে এই কোডের এই অংশটি 30 সেকেন্ডের জন্য স্তব্ধ হয়ে থাকবে (fsockopen এর 5 ম প্যারামিটার)। এছাড়াও লেখকটি কার্যকর করতে তার মিষ্টি সময় নিতে চলেছে (যে আপনি স্ট্রিম_সেটটাইমআউট ($ এফপি, $ মাই টাইমআউটআউট) দিয়ে সীমাবদ্ধ করতে পারবেন you আপনি সর্বোত্তম যেটি করতে পারেন তা হ'ল fsockopen এ 0.1 (100 মিমি) এবং time my_টাইমআউটআউটকে 100 মিমি সেট করুন আপনি যদিও ঝুঁকিপূর্ণ, অনুরোধের সময়সীমা শেষ হয়ে গেল।
ক্রিস সিনেল্লি

4
এ্যাসিঙ্কের সাথে এর কোনও যোগসূত্র নেই। এটি যতটা সিঙ্ক হয় ততই ... অ্যাসিঙ্ক মানে এই টাস্কটি সম্পন্ন হওয়ার সময় অন্যান্য কাজগুলি করুন। এটি সমান্তরাল বাস্তবায়ন।
CodeAngry

17
এটি অ্যাসিঙ্ক বা এটি কার্ল ব্যবহার করছে না, আপনি কীভাবে এটি কল করার curl_post_asyncএবং এমনকি উচ্চতর উন্নতি করার সাহস করছেন ...
ড্যানিয়েল ডাব্লু।

33

পোষ্ট এবং জিইটি উভয় অনুরোধের মাধ্যমে এভাবেই মারকুইসের উত্তরটি তৈরি করা যায়:

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

4
এটি একটি সহজ কোড স্নিপেট, এবং আমি এটি এখানে এবং সেখানে ব্যবহার করছি, তবে আমি এখন দেখতে পাচ্ছি যে একই জিনিসটি করা আমার প্রয়োজন, তবে একটি এসএসএল সাইট সহ। HTTP / 1.1 টাইপ এবং বন্দর ছাড়াও আমার কি পরিবর্তন করার দরকার আছে?
কেভিন জাঙ্গিয়ানী

4
এসএসএলের জন্য এটি ব্যবহার সম্পর্কে প্রশ্নের জবাবে আপনি বন্দরটি 443 এ পরিবর্তন করে এবং এসএসএল: // এফএসকোপেনের বন্দরের নাম: can এফপি = fsockopen ("এসএসএল: //" যোগ করে এটি SSL তৈরি করতে পারেন $ অংশগুলি ['হোস্ট '],
মাইকেল ডগার

4
"এইচটিটিপি / ১.১ টাইপ এবং বন্দর ছাড়াও আমার কি পরিবর্তন করার দরকার আছে?" - হ্যাঁ, আপনার ssl://hostnameঠিক ঠিক পরিবর্তে হোস্টনামের সাথে fsockopen () কল করা উচিত hostname
কাউলি পাঁচ

22
এটি async না! বিশেষত যদি অন্য পাশের সার্ভারটি নীচে থাকে তবে এই কোডের এই অংশটি 30 সেকেন্ডের জন্য স্তব্ধ হয়ে থাকবে (fsockopen এর 5 ম প্যারামিটার)। এছাড়াও লেখকটি কার্যকর করতে তার মিষ্টি সময় নিতে চলেছে (যে আপনি স্ট্রিম_সেটটাইমআউট ($ এফপি, $ মাই টাইমআউটআউট) দিয়ে সীমাবদ্ধ করতে পারবেন you আপনি সর্বোত্তম যেটি করতে পারেন তা হ'ল fsockopen এ 0.1 (100 মিমি) এবং time my_টাইমআউটআউটকে 100 মিমি সেট করুন আপনি যদিও ঝুঁকিপূর্ণ, অনুরোধের সময়সীমা শেষ হয়ে গেল।
ক্রিস সিনেল্লি

4
সামগ্রীর দৈর্ঘ্য জিইটির জন্য নির্ধারণ করা উচিত নয়। হয়তো কিছু পরিস্থিতিতে ত্রুটির কারণ না ঘটায় কিন্তু আমার ক্ষেত্রে পিএইচপি স্ক্রিপ্ট দ্বারা অনুরোধটি প্রক্রিয়া না করার ফলস্বরূপ।
ব্যবহারকারীর 3285954

13

আপনার আপডেটটি সম্পর্কে, পুরো পৃষ্ঠাটি লোড হওয়ার জন্য অপেক্ষা না করার বিষয়ে - আমার মনে হয় একটি HTTP HEADঅনুরোধ আপনি যা খুঁজছেন তা হল ..

get_headers এটি করা উচিত - আমি মনে করি এটি কেবল শিরোনামগুলির জন্য অনুরোধ করে, তাই পুরো পৃষ্ঠার সামগ্রী পাঠানো হবে না।

"পিএইচপি / কার্ল: HEAD অনুরোধ কিছু সাইটে দীর্ঘ সময় নেয়"HEAD পিএইচপি / কার্ল ব্যবহার করে কীভাবে অনুরোধ করবেন তা বর্ণনা করে

আপনি যদি অনুরোধটি ট্রিগার করতে এবং স্ক্রিপ্টটি একেবারেই ধরে না রাখতে চান তবে বিভিন্ন জটিলতার কয়েকটি উপায় রয়েছে ..

  • এইচটিটিপি অনুরোধটিকে ব্যাকগ্রাউন্ড প্রক্রিয়া হিসাবে কার্যকর করুন , পিএইচপি একটি ব্যাকগ্রাউন্ড প্রক্রিয়া সম্পাদন করুন - মূলত আপনি এমন কিছু কার্যকর করতে চান "wget -O /dev/null $carefully_escaped_url"- এটি প্ল্যাটফর্ম নির্দিষ্ট হবে, এবং কমান্ডের পরামিতিগুলি অবলম্বন সম্পর্কে আপনাকে সত্যই সতর্ক থাকতে হবে
  • ব্যাকগ্রাউন্ডে পিএইচপি স্ক্রিপ্ট সম্পাদন করা হচ্ছে - মূলত ইউনিক্স প্রক্রিয়া পদ্ধতির মতো তবে শেল কমান্ডের পরিবর্তে পিএইচপি স্ক্রিপ্ট সম্পাদন করা হচ্ছে
  • একটি ডেটাবেস ব্যবহার করে (বা বেনস্টালকের মতো এমন কিছু যা সম্ভবত ওভারকিল হতে পারে) ব্যবহার করে একটি "কাজের সারি" রাখুন । আপনি সারিতে একটি ইউআরএল যুক্ত করেন এবং একটি পটভূমি প্রক্রিয়া বা ক্রোন-জব নিয়মিতভাবে নতুন কাজের জন্য পরীক্ষা করে URL এ অনুরোধগুলি সম্পাদন করে

বিভিন্ন আকর্ষণীয় বিকল্পের জন্য +1 যা আমি এর আগে ভাবি নি
জসদীপ খালসা

"আমি মনে করি এটি কেবল শিরোনামদের জন্য অনুরোধ করে" - সম্ভবত, তবে কোনও শিরোনাম অনুরোধের প্রতিক্রিয়া হিসাবে একটি দস্তাবেজ একটি পূর্ণ প্রতিক্রিয়া সংস্থা পাঠানো থেকে বিরত করার কিছুই নেই nothing এবং আমি ধরে নিই যে এই পদ্ধতিটি হুডের নীচে fsock ব্যবহার করবে এবং সম্পূর্ণ প্রতিক্রিয়ার জন্য অপেক্ষা করতে (এবং পড়তে) বাধ্য করবে।
hiburn8

6

আপনি না। পিএইচপি কোনও ইউআরএল কল করার জন্য প্রচুর উপায়ে অফার করার সময়, এটি অনুরোধ / সম্পাদন চক্রের জন্য কোনও ধরণের অ্যাসিনক্রোনাস / থ্রেডযুক্ত প্রক্রিয়াজাতকরণ করার জন্য বাক্স সমর্থন ছাড়াই সরবরাহ করে না। কোনও ইউআরএল (বা একটি এসকিউএল স্টেটমেন্ট, বা একটি ইত্যাদি) এর জন্য একটি অনুরোধ প্রেরণের যে কোনও পদ্ধতি কোনও ধরণের প্রতিক্রিয়ার জন্য অপেক্ষা করতে চলেছে । এটি অর্জনের জন্য আপনার স্থানীয় মেশিনে চলমান এক ধরণের মাধ্যমিক সিস্টেমের প্রয়োজন হবে ("পিএইচপি জব সারির জন্য গুগল")


4
আছে: এখানে একটি হ্যাক হয় stackoverflow.com/questions/124462/asynchronous-php-calls (খৃস্টান Daven দ্বারা উত্তর) কিন্তু সে ব্যাপারে আমি সম্মত একটি সারিতে এটা করতে সঠিক ভাবে হবে।
ক্রিস সিনেলি

আমি মনে করি ২০০৯ সালের এই উত্তরটি এখন পুরানো। মদ্যপানোত্সব পিএইচপি গ্রন্থাগার এখন সমবর্তী এবং অ্যাসিঙ্ক্রোনাস অনুরোধ করছেন জন্য সমর্থন আছে।
সাইমন পূর্ব

6

আমি আপনাকে ভালভাবে পরীক্ষিত পিএইচপি লাইব্রেরির পরামর্শ দিচ্ছি: কার্ল-সহজ

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

মদ্যপানোত্সব পিএইচপি গ্রন্থাগার এছাড়াও সমবর্তী এবং অ্যাসিঙ্ক্রোনাস অনুরোধ করছেন জন্য সমর্থন আছে।
সাইমন পূর্ব

গুজল দাবি করেছেন যে এটির সমর্থন রয়েছে তবে এটির পোস্টঅ্যাসিঙ্ক পদ্ধতিটি পরীক্ষা করে দেখে মনে হচ্ছে এটি 150 মাইল সিঙ্ক্রোনজ করে এবং তারপরে 2 এমএস অবিচ্ছিন্নভাবে হয়। আমি সাফল্য ছাড়াই এটি ঠিক করার চেষ্টা করতে এক ঘন্টা বেশি সময় ব্যয় করেছি - এটির প্রস্তাব দেয় না।
ভেলিজার হরিস্টভ

4

আপনি যদি লিনাক্স এনভায়রনমেন্ট ব্যবহার করে থাকেন তবে লিনাক্স কার্লের জন্য আপনি পিএইচপি-র এক্সিকিউট কমান্ডটি ব্যবহার করতে পারেন। এখানে একটি নমুনা কোড রয়েছে যা একটি অ্যাসিঙ্ক্রোনাস এইচটিটিপি পোস্ট করবে।

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

এই কোডটির জন্য কোনও অতিরিক্ত পিএইচপি লিব্সের প্রয়োজন নেই এবং এটি 10 ​​মিলিসেকেন্ডেরও কম সময়ে http পোস্টটি সম্পূর্ণ করতে পারে।


4
এটি একটি খুব খারাপ ধারণা: এক্সিকিউটিটি অনেক ব্যর্থ: কল্পনা করুন যে 6/200 ক্লায়েন্টগুলি প্রদত্ত বুকিংয়ের জন্য তাদের ইমেল নিশ্চিতকরণ পাবেন না ...
হেলবাবি

এটি আমার পক্ষে কাজ করেছে, অন্য সার্ভারে অন্য স্ক্রিপ্ট শুরু করার জন্য আমার কেবল পিং দরকার। আমি কেবল এটির মতো ব্যবহার করেছি: _ync_http_post ($ url, ''); এবং এটি ওভিএইচ মিউচুয়ালাইজড সার্ভারগুলিতে কাজ করছে ... যা দুর্দান্ত।
কিলোভ

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()। এইভাবে, কলকারী ফলাফল রয়েছে কিনা তা যাচাই করার জন্য একটি লুপে কল করে সম্পূর্ণ অসম্পূর্ণ আচরণ পেতে পারে এবং যদি তা না হয় তবে অন্য যে কোনও কাজ চলছে তা চালিয়ে যান। হুম, এখন আমি। Taskনেট থেকে পিএইচপি পর্যন্ত পোর্ট করতে চাই ...
বিনকি

3

আকর্ষণীয় সমস্যা। আমি অনুমান করছি যে আপনি কেবল অন্য সার্ভারে কিছু প্রক্রিয়া বা ক্রিয়াকলাপ ঘটাতে চান, তবে ফলাফল কী তা বিবেচনা করবেন না এবং আপনার স্ক্রিপ্টটি চালিয়ে যেতে চান। সিআরএল-তে সম্ভবত এমন কিছু আছে যা এটি ঘটতে পারে তবে আপনি exec()সার্ভারে অন্য কোনও স্ক্রিপ্ট চালানোর জন্য বিবেচনা করতে চাইতে পারেন যা সিআরএল এটি না করতে পারলে কল করে। (সাধারণত লোকেরা স্ক্রিপ্ট কলের ফলাফল চায় তাই পিএইচপি কেবল প্রসেস ট্রিগার করার ক্ষমতা রাখে কিনা তা আমি নিশ্চিত নই।) আপনার সাথে অনুরোধটি তৈরি করে এমন exec()একটি wgetবা আরও একটি পিএইচপি স্ক্রিপ্ট চালানো যেতে পারে 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);
}

4
এটি খাঁটি পিএইচপি সমাধান নয়।
বিনকি

2

আমার জন্য অ্যাসিঙ্ক্রোনাস জিইটি অনুরোধ সম্পর্কে প্রশ্নটি উপস্থিত হয়েছে কারণ আমি যখন পরিস্থিতিগুলির সাথে দেখা করেছি যখন আমাকে কয়েক শত অনুরোধ করা দরকার , প্রতিটি অনুরোধের ফলাফলের ডেটা পেতে এবং ডিল করতে হয় এবং প্রতিটি অনুরোধ কার্যকর হওয়ার ক্ষেত্রে মিলিসেকেন্ডে কয়েক মিনিট (!) লাগে সহজ সঙ্গে মোট নির্বাহক file_get_contents

এই ক্ষেত্রে এটি খুব সহায়ক মন্তব্য ছিল w_haigh ফাংশন উপর php.net এ http://php.net/manual/en/function.curl-multi-init.php

সুতরাং, এখানে একসাথে প্রচুর অনুরোধ করার জন্য আমার আপগ্রেড করা এবং পরিষ্কার সংস্করণ। আমার ক্ষেত্রে এটি "অ্যাসিনক্রোনাস" উপায়ে সমান। এটি কারওর জন্য সহায়ক হতে পারে!

// 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) অনুরোধ বা সেগুলির কোনও সংমিশ্রণ পরিচালনা করতে এটি পুনরায় লেখা সহজ rite এবং কুকি সমর্থন, পুনঃনির্দেশ, HT-auth, ইত্যাদি


ওহ .. আমি ২০০৯-এ তৈরি প্রশ্নটি দেখি, এবং আমি আমার উত্তরটি ২০১ 2016 সালে লিখি :) তবে আমাদের মধ্যে অনেকগুলি গুগল পিএইচপি অ্যাসিঙ্ক্রোনাস হয়ে এখানে এসেছিলেন।
ফ্লেমস্টোরম

হ্যাঁ আমিও এখানে এসেছি গুগলিংয়ের সময়। কিছু কোডার গুজল পিএইচপি লাইব্রেরিটিও সন্ধান করতে চাইতে পারে যা সমবর্তী এবং অ্যাসিনক্রোনাস অনুরোধ করার জন্য সমর্থন করে।
সাইমন পূর্ব

1

চেষ্টা করুন:

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

এটি অ্যাপাচি মডিউল হিসাবে কাজ করবে না, আপনার সিজিআই ব্যবহার করা দরকার।


1

অ্যাসিক্রোনাস প্রসেসিং করতে অনুরোধ পেয়েছি (অনুরোধটি পান) (

জিজ্ঞাসা

এছাড়াও আপনি উদাহরণস্বরূপ বিনস্টালকের মতো একটি বার্তা সারি ব্যবহার করে অ্যাসিক্রোনাস প্রসেসিং করতে পারেন।


1

একটি সাধারণ জিইটি অনুরোধ সম্পাদন করার জন্য গৃহীত উত্তরের একটি রূপান্তর।

একটি জিনিস লক্ষ্য করুন যে সার্ভারটি যদি কোনও url পুনর্লিখন করে তবে এটি কার্যকর হবে না not আপনার আরও একটি পূর্ণ বৈশিষ্ট্যযুক্ত 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);
    }

আমার একটি সমস্যা হচ্ছে, যেখানে লেখকগুলি বাইটের ধনাত্মক সংখ্যক ফিরিয়ে দেয় তবে স্ক্রিপ্টের শেষ পয়েন্টটি কল করা হয় না (লগিং হয় না) .. এটি কেবল তখনই কাজ করে যখন আমি ব্যবহার করি: যখন (! Feof ($ fp)) {fgets ($ fp) , 128); }
মিগুয়েল

1

গুজলের কথা কেউ উল্লেখ করতে পারে বলে মনে হয় না, এটি এইচএইচটিপি অনুরোধ প্রেরণ সহজ করে তোলে এমন একটি পিএইচপি এইচটিটিপি ক্লায়েন্ট। এটি সাথে বা বাইরে কাজ করতে পারে 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

পরামর্শ: একটি ফ্রেমসেট এইচটিএমএল পৃষ্ঠা ফর্ম্যাট করুন যা এর ভিতরে 9 ফ্রেম বলে say প্রতিটি ফ্রেম আপনার myapp.php পৃষ্ঠার একটি পৃথক "উদাহরণ" পাবেন। সমান্তরালে ওয়েব সার্ভারে 9 টি বিভিন্ন থ্রেড চলবে।


0

পিএইচপি 5.5 + এর জন্য এমপিআইউউ / কো হ'ল চূড়ান্ত সমাধান। এটি জাভাস্ক্রিপ্টে tj / co এ যেন কাজ করে।

উদাহরণ

ধরে নিন যে আপনি নির্দিষ্ট একাধিক গিটহাব ব্যবহারকারীর অবতার ডাউনলোড করতে চান। প্রতিটি ব্যবহারকারীর জন্য নিম্নলিখিত পদক্ষেপগুলি প্রয়োজনীয়।

  1. Http://github.com/mpyw (জিইটি এইচটিএমএল) এর সামগ্রী পান
  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.../

হ্যাঁ, এমপিইউউ / কো সহ এটি খুব সহজ। আরও তথ্যের জন্য, ভান্ডার পৃষ্ঠাটি দেখুন।


-1

আমি যখন কোনও পৃষ্ঠার নির্দিষ্ট ইউআরএল পোস্ট করি তখন এখানে আমার নিজস্ব পিএইচপি ফাংশন ....

নমুনা: * আমার ফাংশনের ব্যবহার ...

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

দয়া করে সিআরএল পিএইচপি এক্সটেনশন সক্ষম করতে ভুলবেন না।


দ্রুত নির্বাহের জন্য আপনি CURLOPT_TIMEOUT_MSউদাহরণস্বরূপ 100 মিলিসেকেন্ড সেট করতে পারেন CURLOPT_TIMEOUTযার পরিবর্তে সেকেন্ডে এবং এতে একটি মিনিট 1 সেকেন্ড থাকে।
জেসন সিলভার

-5

এটি আমার পক্ষে ভাল কাজ করে, দুঃখজনকভাবে আপনি আপনার অনুরোধ থেকে প্রতিক্রিয়া পুনরুদ্ধার করতে পারবেন না:

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

এটি খুব দ্রুত কাজ করে, কাঁচা টিসিপি সকেটের প্রয়োজন নেই :)


এই ফাংশনটি প্রতিক্রিয়ায় একটি শিরোনাম যুক্ত করেছে ... এটি শিরোনামের অনুরোধ প্রেরণ করছে না। php.net/manual/bg/function.header.php
লাচেজার তোদোরভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.