Асинхронные вызовы в переполнении стека

У меня есть несколько провайдеров удаленного контента, чьи API запрашиваются для ответа на запрос пользователя. Предполагая, что каждый поставщик контента должен быть запрошен, как бы я отправлял запросы API асинхронно и собирал результаты? На данный момент я просто перебираю свою коллекцию контент-провайдеров и вызываю их API по одному так:

/**
* A wrapper method that delegates requests to content providers.
*/
public function __call($name, $args) {

// do stuff before

$results = array();
foreach ($contentProviders as $contentProvider) {
$callback = array($contentProvider, $name), $args);
$results[get_class($contentProvider)] = call_user_func_array($callback);
}

// do stuff after

// build final result from individual calls

return $result;
}

Это, однако, заставляет меня ждать, пока запрос не будет завершен, прежде чем начинать следующий. Есть ли способ сделать это асинхронно в PHP?

1

Решение

Вероятно, если вы используете PHP5, этот пост Wez Furlong поможет вам:
http://wezfurlong.org/blog/2005/may/guru-multiplexing/

Пример кода с указанной страницы:

<?php
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");
$timeout = 15;
$status = array();
$sockets = array();
/* Initiate connections to all the hosts simultaneously */
foreach ($hosts as $id => $host) {
$s = stream_socket_client("$host:80", $errno, $errstr, $timeout,
STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
if ($s) {
$sockets[$id] = $s;
$status[$id] = "in progress";
} else {
$status[$id] = "failed, $errno $errstr";
}
}
/* Now, wait for the results to come back in */
while (count($sockets)) {
$read = $write = $sockets;
/* This is the magic function - explained below */
$n = stream_select($read, $write, $e = null, $timeout);
if ($n > 0) {
/* readable sockets either have data for us, or are failed
* connection attempts */
foreach ($read as $r) {
$id = array_search($r, $sockets);
$data = fread($r, 8192);
if (strlen($data) == 0) {
if ($status[$id] == "in progress") {
$status[$id] = "failed to connect";
}
fclose($r);
unset($sockets[$id]);
} else {
$status[$id] .= $data;
}
}
/* writeable sockets can accept an HTTP request */
foreach ($write as $w) {
$id = array_search($w, $sockets);
fwrite($w, "HEAD / HTTP/1.0\\r\\nHost: ". $hosts[$id] .  "\\r\\n\\r\\n");
$status[$id] = "waiting for response";
}
} else {
/* timed out waiting; assume that all hosts associated
* with $sockets are faulty */
foreach ($sockets as $id => $s) {
$status[$id] = "timed out " . $status[$id];
}
break;
}
}
foreach ($hosts as $id => $host) {
echo "Host: $host\\n";
echo "Status: " . $status[$id] . "\\n\\n";
}
?>
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector