복붙노트

PHP로 비동기 HTTP 요청을하는 법

PHP

PHP로 비동기 HTTP 요청을하는 법

PHP에서 비동기 HTTP 호출을 수행하는 방법이 있습니까? 응답에 관심이 없으며 file_get_contents ()와 같은 작업을 수행하려고하지만 나머지 코드를 실행하기 전에 요청이 완료 될 때까지 기다리지 않습니다. 이것은 내 응용 프로그램에서 정렬의 "이벤트"를 설정하거나 긴 프로세스를 트리거하는 데 매우 유용합니다.

어떤 아이디어?

해결법

  1. ==============================

    1.내가 이전에 받아 들였던 대답은 효과가 없었습니다. 그것은 여전히 ​​응답을 기다렸다. PHP에서 비동기 GET 요청을하는 방법은 무엇입니까?

    내가 이전에 받아 들였던 대답은 효과가 없었습니다. 그것은 여전히 ​​응답을 기다렸다. PHP에서 비동기 GET 요청을하는 방법은 무엇입니까?

    function post_without_wait($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);
    }
    
  2. ==============================

    2.이것은 php5가 필요합니다. 나는 docs.php.net에서 그것을 훔쳐서 끝을 편집했다.

    이것은 php5가 필요합니다. 나는 docs.php.net에서 그것을 훔쳐서 끝을 편집했다.

    클라이언트 사이트에서 오류가 발생하면 모니터링에 사용하고, 출력을 보류하지 않고 데이터를 전송합니다.

    function do_post_request($url, $data, $optional_headers = null,$getresponse = false) {
        $params = array(
            'http' => array(
                'method' => 'POST',
                'content' => $data
            )
        );
        if ($optional_headers !== null) {
             $params['http']['header'] = $optional_headers;
        }
        $ctx = stream_context_create($params);
        $fp = @fopen($url, 'rb', false, $ctx);
    
        if (!$fp) {
            return false;
        }
    
        if ($getresponse) {
            $response = stream_get_contents($fp);
            return $response;
        }
        return true;
    }
    
  3. ==============================

    3.비동기 적으로 호출하려는 대상 (예 : 자신의 "longtask.php")을 제어하는 ​​경우 해당 끝에서 연결을 닫을 수 있으며 두 스크립트가 동시에 실행됩니다. 그것은 다음과 같이 작동합니다 :

    비동기 적으로 호출하려는 대상 (예 : 자신의 "longtask.php")을 제어하는 ​​경우 해당 끝에서 연결을 닫을 수 있으며 두 스크립트가 동시에 실행됩니다. 그것은 다음과 같이 작동합니다 :

    나는 이것을 시도하고 잘 작동한다. 하지만 quick.php는 프로세스 간 의사 소통 수단을 만들지 않는 한 longtask.php가 수행하는 작업에 대해서는 알지 못합니다.

    다른 것을하기 전에 longtask.php에서이 코드를 사용해보십시오. 연결을 닫지 만 계속 실행합니다 (그리고 출력을 억제합니다).

    while(ob_get_level()) ob_end_clean();
    header('Connection: close');
    ignore_user_abort();
    ob_start();
    echo('Connection Closed');
    $size = ob_get_length();
    header("Content-Length: $size");
    ob_end_flush();
    flush();
    

    이 코드는 PHP 매뉴얼의 사용자가 작성한 노트에서 복사되어 다소 개선되었습니다.

  4. ==============================

    4.exec ()를 사용하여 wget과 같은 HTTP 요청을 처리 할 수있는 무언가를 호출하여 속임수를 쓸 수는 있지만 프로그램의 모든 출력을 파일이나 / dev / null과 같은 어딘가에 보내야합니다. 그렇지 않으면 PHP 프로세스가 기다립니다 산출.

    exec ()를 사용하여 wget과 같은 HTTP 요청을 처리 할 수있는 무언가를 호출하여 속임수를 쓸 수는 있지만 프로그램의 모든 출력을 파일이나 / dev / null과 같은 어딘가에 보내야합니다. 그렇지 않으면 PHP 프로세스가 기다립니다 산출.

    프로세스를 아파치 스레드와 완전히 분리하고 싶다면 다음과 같은 것을 시도해보십시오. (이것에 대해서는 잘 모르겠지만 아이디어를 얻길 바랍니다.)

    exec('bash -c "wget -O (url goes here) > /dev/null 2>&1 &"');
    

    멋진 비즈니스는 아니므로 실제로 비동기 이벤트를 수행하기 위해 실제 데이터베이스 이벤트 대기열을 폴링하는 하트 비트 스크립트를 호출하는 cron 작업과 같은 것이 필요할 것입니다.

  5. ==============================

    5.

    /**
     * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere. 
     *
     * @param string $filename              file to execute, relative to calling script
     * @param string $options               (optional) arguments to pass to file via the command line
     */ 
    function asyncInclude($filename, $options = '') {
        exec("/path/to/php -f {$filename} {$options} >> /dev/null &");
    }
    
  6. ==============================

    6.이 방법을 사용하면 헤더, 버퍼를 통해 연결 처리를 구현할 필요가 없습니다. OS, 브라우저 및 PHP 버전에 너무 의존합니다.

    이 방법을 사용하면 헤더, 버퍼를 통해 연결 처리를 구현할 필요가 없습니다. OS, 브라우저 및 PHP 버전에 너무 의존합니다.

    마스터 프로세스

    function async_curl($background_process=''){
    
        //-------------get curl contents----------------
    
        $ch = curl_init($background_process);
        curl_setopt_array($ch, array(
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER =>true,
            CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms
            CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute
            CURLOPT_VERBOSE => 1,
            CURLOPT_HEADER => 1
        ));
        $out = curl_exec($ch);
    
        //-------------parse curl contents----------------
    
        //$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        //$header = substr($out, 0, $header_size);
        //$body = substr($out, $header_size);
    
        curl_close($ch);
    
        return true;
    }
    
    async_curl('http://example.com/background_process_1.php');
    

    백그라운드 프로세스

    ignore_user_abort(true);
    
    //do something...
    

    주의

    자원

  7. ==============================

    7.내가 너에게 내 방식을 보여줄 게 ​​:)

    내가 너에게 내 방식을 보여줄 게 ​​:)

    서버에 nodejs가 설치되어 있어야합니다.

    (내 서버가 1000 초 요청을받는 데 2 ​​초 밖에 걸리지 않습니다.)

    우 rl. 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);
    }
    
  8. ==============================

    8.이 라이브러리를 사용할 수 있습니다 : https://github.com/stil/curl-easy

    이 라이브러리를 사용할 수 있습니다 : https://github.com/stil/curl-easy

    다음은 꽤 간단합니다.

    <?php
    $request = new cURL\Request('http://yahoo.com/');
    $request->getOptions()->set(CURLOPT_RETURNTRANSFER, true);
    
    // Specify function to be called when your request is complete
    $request->addListener('complete', function (cURL\Event $event) {
        $response = $event->response;
        $httpCode = $response->getInfo(CURLINFO_HTTP_CODE);
        $html = $response->getContent();
        echo "\nDone.\n";
    });
    
    // Loop below will run as long as request is processed
    $timeStart = microtime(true);
    while ($request->socketPerform()) {
        printf("Running time: %dms    \r", (microtime(true) - $timeStart)*1000);
        // Here you can do anything else, while your request is in progress
    }
    

    아래에서 위의 예에서 콘솔 출력을 볼 수 있습니다. 요청이 실행되는 시간을 나타내는 간단한 라이브 시계가 표시됩니다.

  9. ==============================

    9.비 블로킹 소켓과 PHP 확장 기능 중 하나를 사용할 수 있습니다 :

    비 블로킹 소켓과 PHP 확장 기능 중 하나를 사용할 수 있습니다 :

    코드와 pecl 확장 사이에 추상화 레이어를 제공하는 라이브러리를 사용할 수 있습니다 : https://github.com/reactphp/event-loop

    이전 라이브러리를 기반으로 async http-client를 사용할 수도 있습니다. https://github.com/reactphp/http-client

    ReactPHP의 다른 라이브러리보기 : http://reactphp.org

    비동기 모델에주의하십시오. YouTube에서이 동영상을 볼 것을 권장합니다. http://www.youtube.com/watch?v=MWNcItWuKpI

  10. ==============================

    10.

    class async_file_get_contents extends Thread{
        public $ret;
        public $url;
        public $finished;
            public function __construct($url) {
            $this->finished=false;
            $this->url=$url;
        }
            public function run() {
            $this->ret=file_get_contents($this->url);
            $this->finished=true;
        }
    }
    $afgc=new async_file_get_contents("http://example.org/file.ext");
    
  11. ==============================

    11.스풀 확장자. https://github.com/matyhtf/swoole PHP를위한 비동기 및 동시 네트워킹 프레임 워크.

    스풀 확장자. https://github.com/matyhtf/swoole PHP를위한 비동기 및 동시 네트워킹 프레임 워크.

    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
    
    $client->on("connect", function($cli) {
        $cli->send("hello world\n");
    });
    
    $client->on("receive", function($cli, $data){
        echo "Receive: $data\n";
    });
    
    $client->on("error", function($cli){
        echo "connect fail\n";
    });
    
    $client->on("close", function($cli){
        echo "close\n";
    });
    
    $client->connect('127.0.0.1', 9501, 0.5);
    
  12. ==============================

    12.이벤트 확장은 매우 적합합니다. 주로 네트워킹 용 이벤트 구동 I / O 용으로 설계된 Libevent 라이브러리 포트입니다.

    이벤트 확장은 매우 적합합니다. 주로 네트워킹 용 이벤트 구동 I / O 용으로 설계된 Libevent 라이브러리 포트입니다.

    몇 가지를 예약 할 수있는 샘플 HTTP 클라이언트를 작성했습니다. HTTP 요청을 처리하고 비동기 적으로 실행합니다.

    이것은 이벤트 확장을 기반으로하는 샘플 HTTP 클라이언트 클래스입니다.

    이 클래스는 많은 수의 HTTP 요청을 스케줄링 한 다음 비동기로 실행합니다.

    <?php
    class MyHttpClient {
      /// @var EventBase
      protected $base;
      /// @var array Instances of EventHttpConnection
      protected $connections = [];
    
      public function __construct() {
        $this->base = new EventBase();
      }
    
      /**
       * Dispatches all pending requests (events)
       *
       * @return void
       */
      public function run() {
        $this->base->dispatch();
      }
    
      public function __destruct() {
        // Destroy connection objects explicitly, don't wait for GC.
        // Otherwise, EventBase may be free'd earlier.
        $this->connections = null;
      }
    
      /**
       * @brief Adds a pending HTTP request
       *
       * @param string $address Hostname, or IP
       * @param int $port Port number
       * @param array $headers Extra HTTP headers
       * @param int $cmd A EventHttpRequest::CMD_* constant
       * @param string $resource HTTP request resource, e.g. '/page?a=b&c=d'
       *
       * @return EventHttpRequest|false
       */
      public function addRequest($address, $port, array $headers,
        $cmd = EventHttpRequest::CMD_GET, $resource = '/')
      {
        $conn = new EventHttpConnection($this->base, null, $address, $port);
        $conn->setTimeout(5);
    
        $req = new EventHttpRequest([$this, '_requestHandler'], $this->base);
    
        foreach ($headers as $k => $v) {
          $req->addHeader($k, $v, EventHttpRequest::OUTPUT_HEADER);
        }
        $req->addHeader('Host', $address, EventHttpRequest::OUTPUT_HEADER);
        $req->addHeader('Connection', 'close', EventHttpRequest::OUTPUT_HEADER);
        if ($conn->makeRequest($req, $cmd, $resource)) {
          $this->connections []= $conn;
          return $req;
        }
    
        return false;
      }
    
    
      /**
       * @brief Handles an HTTP request
       *
       * @param EventHttpRequest $req
       * @param mixed $unused
       *
       * @return void
       */
      public function _requestHandler($req, $unused) {
        if (is_null($req)) {
          echo "Timed out\n";
        } else {
          $response_code = $req->getResponseCode();
    
          if ($response_code == 0) {
            echo "Connection refused\n";
          } elseif ($response_code != 200) {
            echo "Unexpected response: $response_code\n";
          } else {
            echo "Success: $response_code\n";
            $buf = $req->getInputBuffer();
            echo "Body:\n";
            while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {
              echo $s, PHP_EOL;
            }
          }
        }
      }
    }
    
    
    $address = "my-host.local";
    $port = 80;
    $headers = [ 'User-Agent' => 'My-User-Agent/1.0', ];
    
    $client = new MyHttpClient();
    
    // Add pending requests
    for ($i = 0; $i < 10; $i++) {
      $client->addRequest($address, $port, $headers,
        EventHttpRequest::CMD_GET, '/test.php?a=' . $i);
    }
    
    // Dispatch pending requests
    $client->run();
    

    이것은 서버 측의 샘플 스크립트입니다.

    <?php
    echo 'GET: ', var_export($_GET, true), PHP_EOL;
    echo 'User-Agent: ', $_SERVER['HTTP_USER_AGENT'] ?? '(none)', PHP_EOL;
    
    php http-client.php
    

    샘플 출력

    Success: 200
    Body:
    GET: array (
      'a' => '1',
    )
    User-Agent: My-User-Agent/1.0
    Success: 200
    Body:
    GET: array (
      'a' => '0',
    )
    User-Agent: My-User-Agent/1.0
    Success: 200
    Body:
    GET: array (
      'a' => '3',
    )
    ...
    

    (잘라 내기.)

    이 코드는 CLI SAPI에서 장기적인 처리를 위해 설계된 것입니다.

    맞춤 프로토콜의 경우 하위 수준 API, 즉 버퍼 이벤트, 버퍼를 사용하는 것이 좋습니다. SSL / TLS 통신의 경우 저급 API를 Event의 SSL 컨텍스트와 함께 사용하는 것이 좋습니다. 예 :

    Libevent의 HTTP API는 간단하지만 버퍼 이벤트만큼 유연하지는 않습니다. 예를 들어, HTTP API는 현재 사용자 정의 HTTP 메소드를 지원하지 않습니다. 그러나 저수준 API를 사용하여 거의 모든 프로토콜을 구현할 수 있습니다.

    또한 비 차단 모드의 소켓이있는 Ev 확장을 사용하여 다른 HTTP 클라이언트의 샘플을 작성했습니다. Ev는 범용 이벤트 루프이기 때문에 코드는 Event를 기반으로하는 샘플보다 약간 자세한 정보입니다. 네트워크 관련 기능은 제공하지 않지만 EvIo 관측자는 특히 소켓 리소스에 캡슐화 된 파일 설명자를 청취 할 수 있습니다.

    Ev 확장자를 기반으로 한 샘플 HTTP 클라이언트입니다.

    Ev 확장은 간단하면서도 강력한 범용 이벤트 루프를 구현합니다. 네트워크 관련 관찰자는 제공하지 않지만 I / O 감시자는 소켓의 비동기 처리에 사용할 수 있습니다.

    다음 코드는 HTTP 요청을 병렬 처리하도록 예약하는 방법을 보여줍니다.

    <?php
    class MyHttpRequest {
      /// @var MyHttpClient
      private $http_client;
      /// @var string
      private $address;
      /// @var string HTTP resource such as /page?get=param
      private $resource;
      /// @var string HTTP method such as GET, POST etc.
      private $method;
      /// @var int
      private $service_port;
      /// @var resource Socket
      private $socket;
      /// @var double Connection timeout in seconds.
      private $timeout = 10.;
      /// @var int Chunk size in bytes for socket_recv()
      private $chunk_size = 20;
      /// @var EvTimer
      private $timeout_watcher;
      /// @var EvIo
      private $write_watcher;
      /// @var EvIo
      private $read_watcher;
      /// @var EvTimer
      private $conn_watcher;
      /// @var string buffer for incoming data
      private $buffer;
      /// @var array errors reported by sockets extension in non-blocking mode.
      private static $e_nonblocking = [
        11, // EAGAIN or EWOULDBLOCK
        115, // EINPROGRESS
      ];
    
      /**
       * @param MyHttpClient $client
       * @param string $host Hostname, e.g. google.co.uk
       * @param string $resource HTTP resource, e.g. /page?a=b&c=d
       * @param string $method HTTP method: GET, HEAD, POST, PUT etc.
       * @throws RuntimeException
       */
      public function __construct(MyHttpClient $client, $host, $resource, $method) {
        $this->http_client = $client;
        $this->host        = $host;
        $this->resource    = $resource;
        $this->method      = $method;
    
        // Get the port for the WWW service
        $this->service_port = getservbyname('www', 'tcp');
    
        // Get the IP address for the target host
        $this->address = gethostbyname($this->host);
    
        // Create a TCP/IP socket
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if (!$this->socket) {
          throw new RuntimeException("socket_create() failed: reason: " .
            socket_strerror(socket_last_error()));
        }
    
        // Set O_NONBLOCK flag
        socket_set_nonblock($this->socket);
    
        $this->conn_watcher = $this->http_client->getLoop()
          ->timer(0, 0., [$this, 'connect']);
      }
    
      public function __destruct() {
        $this->close();
      }
    
      private function freeWatcher(&$w) {
        if ($w) {
          $w->stop();
          $w = null;
        }
      }
    
      /**
       * Deallocates all resources of the request
       */
      private function close() {
        if ($this->socket) {
          socket_close($this->socket);
          $this->socket = null;
        }
    
        $this->freeWatcher($this->timeout_watcher);
        $this->freeWatcher($this->read_watcher);
        $this->freeWatcher($this->write_watcher);
        $this->freeWatcher($this->conn_watcher);
      }
    
      /**
       * Initializes a connection on socket
       * @return bool
       */
      public function connect() {
        $loop = $this->http_client->getLoop();
    
        $this->timeout_watcher = $loop->timer($this->timeout, 0., [$this, '_onTimeout']);
        $this->write_watcher = $loop->io($this->socket, Ev::WRITE, [$this, '_onWritable']);
    
        return socket_connect($this->socket, $this->address, $this->service_port);
      }
    
      /**
       * Callback for timeout (EvTimer) watcher
       */
      public function _onTimeout(EvTimer $w) {
        $w->stop();
        $this->close();
      }
    
      /**
       * Callback which is called when the socket becomes wriable
       */
      public function _onWritable(EvIo $w) {
        $this->timeout_watcher->stop();
        $w->stop();
    
        $in = implode("\r\n", [
          "{$this->method} {$this->resource} HTTP/1.1",
          "Host: {$this->host}",
          'Connection: Close',
        ]) . "\r\n\r\n";
    
        if (!socket_write($this->socket, $in, strlen($in))) {
          trigger_error("Failed writing $in to socket", E_USER_ERROR);
          return;
        }
    
        $loop = $this->http_client->getLoop();
        $this->read_watcher = $loop->io($this->socket,
          Ev::READ, [$this, '_onReadable']);
    
        // Continue running the loop
        $loop->run();
      }
    
      /**
       * Callback which is called when the socket becomes readable
       */
      public function _onReadable(EvIo $w) {
        // recv() 20 bytes in non-blocking mode
        $ret = socket_recv($this->socket, $out, 20, MSG_DONTWAIT);
    
        if ($ret) {
          // Still have data to read. Append the read chunk to the buffer.
          $this->buffer .= $out;
        } elseif ($ret === 0) {
          // All is read
          printf("\n<<<<\n%s\n>>>>", rtrim($this->buffer));
          fflush(STDOUT);
          $w->stop();
          $this->close();
          return;
        }
    
        // Caught EINPROGRESS, EAGAIN, or EWOULDBLOCK
        if (in_array(socket_last_error(), static::$e_nonblocking)) {
          return;
        }
    
        $w->stop();
        $this->close();
      }
    }
    
    /////////////////////////////////////
    class MyHttpClient {
      /// @var array Instances of MyHttpRequest
      private $requests = [];
      /// @var EvLoop
      private $loop;
    
      public function __construct() {
        // Each HTTP client runs its own event loop
        $this->loop = new EvLoop();
      }
    
      public function __destruct() {
        $this->loop->stop();
      }
    
      /**
       * @return EvLoop
       */
      public function getLoop() {
        return $this->loop;
      }
    
      /**
       * Adds a pending request
       */
      public function addRequest(MyHttpRequest $r) {
        $this->requests []= $r;
      }
    
      /**
       * Dispatches all pending requests
       */
      public function run() {
        $this->loop->run();
      }
    }
    
    
    /////////////////////////////////////
    // Usage
    $client = new MyHttpClient();
    foreach (range(1, 10) as $i) {
      $client->addRequest(new MyHttpRequest($client, 'my-host.local', '/test.php?a=' . $i, 'GET'));
    }
    $client->run();
    

    http : //my-host.local/test.php 스크립트가 $ _GET의 덤프를 인쇄하고 있다고 가정합니다.

    <?php
    echo 'GET: ', var_export($_GET, true), PHP_EOL;
    

    그러면 php http-client.php 명령의 출력은 다음과 유사합니다.

    <<<<
    HTTP/1.1 200 OK
    Server: nginx/1.10.1
    Date: Fri, 02 Dec 2016 12:39:54 GMT
    Content-Type: text/html; charset=UTF-8
    Transfer-Encoding: chunked
    Connection: close
    X-Powered-By: PHP/7.0.13-pl0-gentoo
    
    1d
    GET: array (
      'a' => '3',
    )
    
    0
    >>>>
    <<<<
    HTTP/1.1 200 OK
    Server: nginx/1.10.1
    Date: Fri, 02 Dec 2016 12:39:54 GMT
    Content-Type: text/html; charset=UTF-8
    Transfer-Encoding: chunked
    Connection: close
    X-Powered-By: PHP/7.0.13-pl0-gentoo
    
    1d
    GET: array (
      'a' => '2',
    )
    
    0
    >>>>
    ...
    

    (손질 된)

    PHP 5에서 소켓 확장은 EINPROGRESS, EAGAIN 및 EWOULDBLOCK errno 값에 대한 경고를 기록 할 수 있습니다. 로그를 해제 할 수 있습니다.

    error_reporting(E_ERROR);
    

    네트워크 요청과 병렬로 실행해야하는 코드는 예를 들어 이벤트 타이머 또는 Ev의 유휴 감시자의 콜백 내에서 실행할 수 있습니다. 위에서 언급 한 샘플을보고 쉽게 알아낼 수 있습니다. 그렇지 않으면 또 다른 예제를 추가 할 것입니다 :)

  13. ==============================

    13.2018 년 현재 Guzzle은 여러 현대 프레임 워크에서 사용되는 HTTP 요청에 대한 표준 표준 라이브러리가되었습니다. 순수한 PHP로 작성되었으며 사용자 정의 확장을 설치할 필요가 없습니다.

    2018 년 현재 Guzzle은 여러 현대 프레임 워크에서 사용되는 HTTP 요청에 대한 표준 표준 라이브러리가되었습니다. 순수한 PHP로 작성되었으며 사용자 정의 확장을 설치할 필요가 없습니다.

    비동기 HTTP 호출을 매우 잘 처리 할 수 ​​있으며 100 회의 HTTP 호출을해야 할 때처럼 풀링 할 수 있지만 한 번에 5 개를 초과하여 실행하지는 않습니다.

    use GuzzleHttp\Client;
    use GuzzleHttp\Promise;
    
    $client = new Client(['base_uri' => 'http://httpbin.org/']);
    
    // Initiate each request but do not block
    $promises = [
        'image' => $client->getAsync('/image'),
        'png'   => $client->getAsync('/image/png'),
        'jpeg'  => $client->getAsync('/image/jpeg'),
        'webp'  => $client->getAsync('/image/webp')
    ];
    
    // Wait on all of the requests to complete. Throws a ConnectException
    // if any of the requests fail
    $results = Promise\unwrap($promises);
    
    // Wait for the requests to complete, even if some of them fail
    $results = Promise\settle($promises)->wait();
    
    // You can access each result using the key provided to the unwrap
    // function.
    echo $results['image']['value']->getHeader('Content-Length')[0]
    echo $results['png']['value']->getHeader('Content-Length')[0]
    

    http://docs.guzzlephp.org/en/stable/quickstart.html#concurrent-requests를 참조하십시오.

  14. ==============================

    14.다음은 작동 예제입니다. 실행 한 후 storage.txt를 열고 마법의 결과를 확인하십시오.

    다음은 작동 예제입니다. 실행 한 후 storage.txt를 열고 마법의 결과를 확인하십시오.

    <?php
        function curlGet($target){
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $target);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $result = curl_exec ($ch);
            curl_close ($ch);
            return $result;
        }
    
        // Its the next 3 lines that do the magic
        ignore_user_abort(true);
        header("Connection: close"); header("Content-Length: 0");
        echo str_repeat("s", 100000); flush();
    
        $i = $_GET['i'];
        if(!is_numeric($i)) $i = 1;
        if($i > 4) exit;
        if($i == 1) file_put_contents('storage.txt', '');
    
        file_put_contents('storage.txt', file_get_contents('storage.txt') . time() . "\n");
    
        sleep(5);
        curlGet($_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '?i=' . ($i + 1));
        curlGet($_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '?i=' . ($i + 1));
    
  15. ==============================

    15.어떤 페이지의 특정 URL에 POST 할 때 내 자신의 PHP 함수는 다음과 같습니다 .... 샘플 : *** 내 기능의 사용법 ...

    어떤 페이지의 특정 URL에 POST 할 때 내 자신의 PHP 함수는 다음과 같습니다 .... 샘플 : *** 내 기능의 사용법 ...

        <?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>
    
  16. ==============================

    16.시간 제한은 밀리 초 단위로 설정할 수 있습니다. http://www.php.net/manual/en/function.curl-setopt의 "CURLOPT_CONNECTTIMEOUT_MS"를 참조하십시오.

    시간 제한은 밀리 초 단위로 설정할 수 있습니다. http://www.php.net/manual/en/function.curl-setopt의 "CURLOPT_CONNECTTIMEOUT_MS"를 참조하십시오.

  17. from https://stackoverflow.com/questions/124462/how-to-make-asynchronous-http-requests-in-php by cc-by-sa and MIT license