Как мне сделать асинхронный запрос GET в PHP?


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.

Будет ли работать fsockopen? Если да, то как мне это сделать, не читая содержимое файла? Нет другого выхода?

Спасибо всем

Обновить

Я должен был добавить, что в первом случае я не хочу ждать, пока скрипт ничего не вернет. Насколько я понимаю, file_get_contents () будет ждать полной загрузки страницы и т. Д.?


6
@William: Да, большинство вопросов можно считать точными копиями самих себя. 8-) Я думаю, вы разместили не ту ссылку ...
RichieHindle,


1
Я хотел опубликовать ссылку, которую опубликовал musicfreak, перепутал мои вкладки ;-)
Уильям Брендель

2
@ Ричи: Больше всего вопросов? ;)
Саша Чедыгов 07

1
Я переименовал вопрос, чтобы отличить его от другого, поскольку кажется, что вы хотите сделать запрос, не заботясь об использовании ответа (так что это может произойти во время выполнения остальной части скрипта). Отмените, если я ошибаюсь!
dbr 07

Ответы:


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 отправляет запрос POST, а не GET.
Винко Врсалович

13
Правильно ли я говорю, что эта функция неправильно названа? Это действительно не имеет ничего общего с библиотекой curl. Это больше похоже на fsock_post_async ()
MikeMurko 08

61
Это НЕ асинхронно! В частности, если сервер на другой стороне не работает, этот фрагмент кода будет зависать на 30 секунд (5-й параметр в fsockopen). Также fwrite займет свое приятное время для выполнения (которое вы можете ограничить с помощью stream_set_timeout ($ fp, $ my_timeout). Лучшее, что вы можете сделать, это установить низкий тайм-аут для fsockopen на 0,1 (100 мс) и $ my_timeout на 100 мс Однако вы рискуете, что тайм-аут запроса истечет »,
Крис Чинелли,

4
Это не имеет ничего общего с async. Это настолько синхронно, насколько это возможно ... Асинхронный означает выполнение других задач, пока эта задача выполняется. Это параллельное исполнение.
CodeAngry

17
Это не асинхронный, и не использование curl, как вы осмеливаетесь называть это 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
Это удобный фрагмент кода, и я использовал его здесь и там, но теперь обнаружил, что мне нужно сделать то же самое, но с сайтом SSL. Что мне нужно изменить, кроме типа HTTP / 1.1 и порта?
Кевин Джангиани,

2
В ответ на вопрос об использовании этого для SSL вы можете сделать его SSL, изменив порт на 443 и добавив ssl: // к имени порта в fsockopen: $ fp = fsockopen ("ssl: //". $ Parts ['host '],
Майкл Доггер

1
«Есть ли что-нибудь, что мне нужно изменить, кроме типа HTTP / 1.1 и порта?» - Да, вы должны вызывать fsockopen () с именем хоста as ssl://hostnameвместо just hostname.
Коулби

22
Это НЕ асинхронно! В частности, если сервер на другой стороне не работает, этот фрагмент кода будет зависать на 30 секунд (5-й параметр в fsockopen). Также fwrite займет свое приятное время для выполнения (которое вы можете ограничить с помощью stream_set_timeout ($ fp, $ my_timeout). Лучшее, что вы можете сделать, это установить низкий тайм-аут для fsockopen на 0,1 (100 мс) и $ my_timeout на 100 мс Однако вы рискуете, что тайм-аут запроса истек.
Крис Чинелли

1
Content-Length не следует устанавливать для GET. Возможно, в некоторых сценариях это не вызывает ошибки, но в моем случае это привело к тому, что запрос не обрабатывается вызываемым скриптом php.
user3285954

13

Что касается вашего обновления, о том, что вы не хотите ждать загрузки полной страницы - я думаю, что HTTP- HEADзапрос - это то, что вы ищете ...

get_headers должен это сделать - я думаю, он запрашивает только заголовки, поэтому не будет отправлено полное содержимое страницы.

«PHP / Curl: HEAD Request занимает много времени на некоторых сайтах» описывает, как выполнить HEADзапрос с помощью PHP / Curl.

Если вы хотите инициировать запрос и вообще не задерживать скрипт, есть несколько способов различной сложности.

  • Выполнить HTTP-запрос как фоновый процесс, php выполнить фоновый процесс - в основном вы должны выполнить что-то вроде "wget -O /dev/null $carefully_escaped_url"- это будет зависеть от платформы, и вы должны быть очень осторожны с экранированием параметров в команде
  • Выполнение сценария PHP в фоновом режиме - в основном то же, что и метод процесса UNIX, но выполнение сценария PHP, а не команды оболочки
  • Создайте «очередь заданий», используя базу данных (или что-то вроде beanstalkd, что, вероятно, излишне). Вы добавляете URL-адрес в очередь, а фоновый процесс или задание cron регулярно проверяет наличие новых заданий и выполняет запросы по URL-адресу.

+1 за различные интересные варианты, о которых я раньше не думал
Джасдип Халса

«Я думаю, он запрашивает только заголовки» - возможно, но ничто не мешает документу отправить полное тело ответа в ответ на запрос HEAD. И я предполагаю, что этот метод будет использовать fsock под капотом и заставит его ждать (и читать) полный ответ.
hiburn8

6

Вы этого не сделаете. Хотя PHP предлагает множество способов вызова URL-адреса, он не предлагает готовую поддержку для выполнения любого вида асинхронной / поточной обработки для каждого цикла запроса / выполнения. Любой способ отправки запроса на URL (или SQL заявление или т.п.) будет ждать какого - то ответа. Для этого вам понадобится какая-то вторичная система, работающая на локальном компьютере (поиск в Google "очередь заданий php")


1
Здесь есть взлом: stackoverflow.com/questions/124462/asynchronous-php-calls (ответ Кристиана Дэвена), но я согласен, что очередь будет правильным способом сделать это.
Крис Чинелли

Я думаю, что этот ответ 2009 года уже устарел. Библиотека Guzzle PHP теперь поддерживает одновременные и асинхронные запросы.
Саймон Ист

6

Я бы порекомендовал вам хорошо протестированную библиотеку PHP: 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
}

Библиотека Guzzle PHP также поддерживает одновременные и асинхронные запросы.
Саймон Ист

Guzzle утверждает, что у него есть поддержка, но тестирование его метода postAsync выглядит так, как будто он выполняет 150 мс синхронно, а затем 2 мс асинхронно. Я потратил больше часа, пытаясь исправить это, но безуспешно - не рекомендую.
Велизар Христов

4

Если вы используете среду Linux, вы можете использовать команду PHP exec для вызова linux curl. Вот пример кода, который создаст асинхронный 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-библиотек, и он может завершить http-сообщение менее чем за 10 миллисекунд.


1
это очень плохая идея: exec часто терпит неудачу: представьте, что 6/200 клиентов не получат подтверждение по электронной почте для оплаченного бронирования ...
HellBaby

Это сработало для меня, поскольку мне просто нужен пинг, чтобы запустить другой скрипт на другом сервере. Я просто использовал это так: _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(). Таким образом, вызывающий может получить полностью асинхронное поведение, вызвав цикл, чтобы проверить, есть ли результаты, и, если нет, продолжить выполнение любой другой задачи. Хм, теперь я хочу портировать Taskс .net на php…
binki

3

Интересная проблема. Я предполагаю, что вы просто хотите запустить какой-то процесс или действие на другом сервере, но не заботитесь о результатах и ​​хотите, чтобы ваш скрипт продолжался. Вероятно, в cURL есть что-то, что может сделать это, но вы можете рассмотреть возможность использования exec()для запуска другого скрипта на сервере, который выполняет вызов, если cURL не может этого сделать. (Обычно людям нужны результаты вызова сценария, поэтому я не уверен, может ли PHP просто запускать процесс.) exec()Вы можете запустить wgetсценарий PHP или даже другой сценарий, который выполняет запрос с помощью file_get_conents().


2

Вам лучше рассмотреть возможность использования очередей сообщений вместо рекомендуемых методов. Я уверен, что это будет лучшее решение, хотя для этого потребуется немного больше работы, чем просто отправка запроса.


2

позволь мне показать тебе свой путь :)

требуется установка nodejs на сервере

(мой сервер отправляет 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 .

В данном случае это был очень полезный комментарий 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) запросов или любых их комбинаций. И поддержка файлов cookie, перенаправления, http-auth и т. Д.


Ох ... Я вижу вопрос, созданный в 2009 году, и я пишу свой ответ в 2016 году :) Но многие из нас, Google php стали асинхронными и пришли сюда.
FlameStorm

Да я тоже заходил сюда, когда гуглил. Некоторые программисты могут также захотеть изучить библиотеку Guzzle PHP, которая поддерживает одновременные и асинхронные запросы.
Саймон Ист

1

Пытаться:

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

Это НЕ будет работать как модуль apache, вам нужно использовать CGI.


1

Я нашел эту интересную ссылку для асинхронной обработки (получение запроса).

Askapache

Кроме того, вы можете выполнять асинхронную обработку с помощью очереди сообщений, например, beanstalkd.


1

Вот адаптация принятого ответа для выполнения простого запроса GET.

Следует отметить, что если сервер выполняет перезапись URL-адреса, это не сработает. Вам понадобится более полнофункциональный 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);
    }

У меня проблема, когда fwrite возвращает положительное количество байтов, но конечная точка скрипта не вызывается (не ведется журнал) .. она работает только тогда, когда я использую: while (! Feof ($ fp)) {fgets ($ fp , 128); }
Мигель

1

Кажется, никто не упоминает Guzzle , который является HTTP-клиентом PHP, который упрощает отправку 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();
    }
);

Да, многие ответы в этой теме довольно старые, но Guzzle определенно лучший вариант, с которым я столкнулся в 2018 году, спасибо за публикацию.
Саймон Ист

0

Основываясь на этой теме, я сделал это для своего проекта codeigniter. Работает отлично. Вы можете обрабатывать любую функцию в фоновом режиме.

Контроллер, который принимает асинхронные вызовы.

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

Этот метод можно вызвать для обработки любой модели :: method () в «фоне». Он использует переменные аргументы.

$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 в JavaScript.

пример

Предположим, вы хотите загрузить указанные несколько аватарок пользователей GitHub. Для каждого пользователя требуются следующие шаги.

  1. Получить содержимое http://github.com/mpyw (ПОЛУЧИТЬ 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 / co это очень просто. Для получения дополнительных сведений посетите страницу репозитория.


-1

Вот моя собственная функция PHP, когда я выполняю POST для определенного URL-адреса любой страницы ....

Пример: * использование моей функции ...

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

Работает очень быстро, не нужны сокеты raw tcp :)


Эта функция добавляет заголовок к ответу ... она не отправляет запрос заголовка. php.net/manual/bg/function.header.php
Тодоров
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.