Як зробити асинхронний 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? Якщо так, то як це зробити, не читаючи вміст файлу? Хіба іншого шляху немає?

Дякую усім

Оновлення

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


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


1
Я мав на увазі розмістити посилання musicfreak, розміщений, переплутав мої вкладки ;-)
Вільям Брендель

2
@Richie: Більшість питань? ;)
Саша Чедигов

1
Я переписав це питання, щоб відрізнити його від іншого, оскільки, здається, ви хочете зробити запит, не хвилюйтеся щодо використання відповіді (так це може статися під час запуску решти сценарію). Поверніть його, якщо я помиляюся!
дбр

Відповіді:


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

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і отримувати рівне оновлення ...
Daniel W.

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 () з ім'ям хоста як ssl://hostnameзамість просто hostname.
Cowlby

22
Це НЕ асинхронізація! Зокрема, якщо сервер на іншій стороні не працює, цей фрагмент коду буде зависати протягом 30 секунд (5-й параметр у fsockopen). Крім того, fwrite буде витрачати час на виконання файлу (який ви можете обмежити за допомогою stream_set_timeout ($ fp, $ my_timeout). Найкраще, що ви можете зробити, це встановити низький час очікування на fsockopen до 0,1 (100 мс) і $ my_timeout до 100 мс Ви все ж ризикуєте тимчасовим затримкою запиту
Кріс Сінеллі,

1
Не слід встановлювати довжину вмісту для GET. Можливо, в деяких сценаріях не виникає помилок, але в моєму випадку запит не обробляється за допомогою викликаного php-скрипту.
користувач3285954

13

Щодо вашого оновлення, про те, щоб не хотіти чекати завантаження повної сторінки - я думаю HEAD, що ви шукаєте HTTP- запит.

get_headers повинен це зробити - я думаю, що він запитує лише заголовки, тому не буде надісланий повний вміст сторінки.

"PHP / Curl: HEAD-запит займає багато часу на деяких сайтах" описує, як зробити HEADзапит за допомогою PHP / Curl

Якщо ви хочете запустити запит і взагалі не затримувати сценарій, є кілька способів різної складності.

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

+1 для різних цікавих варіантів, про які я не замислювався раніше
Jasdeep Khalsa

"Я думаю, що це вимагає лише заголовків" - Можливо, але немає нічого, що не зупиняє документ від надсилання повноцінного органу відповіді у відповідь на запит HEAD. І я припускаю, що цей метод використовує fsock під кришкою і змушує його чекати (і читати) повну відповідь.
hiburn8

6

Ви цього не робите. Хоча PHP пропонує безліч способів зателефонувати за URL-адресою, він не пропонує поза скринькою підтримки для виконання будь-якого типу асинхронної / потокової обробки за запитом / циклом виконання. Будь-який спосіб надсилання запиту за URL-адресою (або SQL-заявою, і т. Д.) Буде чекати певної відповіді. Для досягнення цього вам знадобиться якась вторинна система, що працює на локальній машині (google навколо "php черги завдань")


1
Тут є злом: stackoverflow.com/questions/124462/asynchronous-php-calls (відповідь Крістіана Давена), але я погоджуюся, що черга була б правильним способом це зробити.
Кріс Сінеллі

Я думаю, що ця відповідь з 2009 року застаріла. Бібліотека жерти 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, тоді ви можете скористатися командою exec PHP для виклику скручування linux. Ось зразок коду, який створить асинхронний 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 не отримають підтвердження електронною поштою про
оплачене

Це працювало для мене, оскільки мені просто потрібен пінг, щоб запустити інший сценарій на іншому сервері. Я просто використовував це так: _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
перенести

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.
binki

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

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

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

Я знайшов це цікаве посилання для асинхронної обробки (отримати запит).

аскапаче

Крім того, ви можете зробити асинхронну обробку, використовуючи чергу повідомлень, наприклад, 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 , який є 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();
    }
);

Так, багато відповідей у ​​цій темі досить давні, але Guzzle, безумовно, найкращий варіант, з яким я зіткнувся у 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 );
    }
}

Цей метод можна викликати для обробки будь-якої моделі :: method () у фоновому режимі. Він використовує змінні аргументи.

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

0

Пропозиція: відформатуйте HTML-сторінку FRAMESET, яка містить, скажімо, 9 кадрів усередині. Кожен кадр отримає інший "екземпляр" вашої сторінки myapp.php. Паралельно буде працювати 9 різних потоків на веб-сервері.


0

Для PHP5.5 + mpyw / co є найкращим рішенням. Він працює так, ніби це JavaScript / JavaScript в JavaScript.

Приклад

Припустимо, що ви хочете завантажити вказані кілька аватарів користувачів 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 / 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);

Не забудьте ввімкнути розширення php CURL.


Ви можете встановити, CURLOPT_TIMEOUT_MSнаприклад, 100 мілісекунд, замість CURLOPT_TIMEOUTяких - за секунди і має хвилину 1 секунду - для швидшого виконання.
Джейсон Сілвер

-5

Для мене це добре працює, на жаль, ви не можете отримати відповідь зі свого запиту:

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

Працює дуже швидко, немає необхідності в сирих розетках tcp :)


Ця функція додає заголовок до відповіді ... це не надсилання запиту заголовка. php.net/manual/bg/function.header.php
Лачезар Тодоров
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.