<?php
/**
* Libs_Multihttp
*
* @access public
*/
abstract
class
Libs_Multihttp {
/**
* Фабрика
*
* @access public
* @var object
*/
public
static
function factory(array $uris) {
return
new
Multihttp($uris);
}
/**
* Конструктор Multihttp
*
* @access public
* @return void
*/
public
function __construct($uris) {
$
this
->_uris = $uris;
}
/**
* URIs
*
* @access protected
* @var array
*/
protected
$_uris = array();
/**
* Ожидание ответа от сервера в сек
*
* @access protected
* @var int
*/
protected
$_request_timeout =
5
;
/**
* Число попыток сединения
*
* @access protected
* @var int
*/
protected
$_request_attempts =
5
;
/**
* Задержка между соединениями в сек
*
* @access protected
* @var int
*/
protected
$_request_delay =
1
;
/**
* Полученные ответы
*
* @access protected
* @var array
*/
protected
$_responses = array();
/**
* Установка настроек запроса
*
* @access public
* @param array
* @return object
*/
public
function setRequestSettings($settings) {
if
( isset($settings[
'timeout'
]) && is_int($settings[
'timeout'
]) ) {
$
this
->_request_timeout = $settings[
'timeout'
];
}
if
( isset($settings[
'attempts'
]) && is_int($settings[
'attempts'
]) ) {
$
this
->_request_attempts = $settings[
'timeout'
];
}
if
( isset($settings[
'delay'
]) && is_int($settings[
'delay'
]) ) {
$
this
->_request_delay = $settings[
'delay'
];
}
return
$
this
;
}
/**
* Получение настроек запроса
*
* @access public
* @return array
*/
public
function getRequestSettings() {
return
array(
'timeout'
=> $
this
->_request_timeout,
'attempts'
=> $
this
->_request_attempts,
'delay'
=> $
this
->_request_delay
);
}
/**
* Запуск роутера
*
* @access public
* @param string $route
* @return object
*/
public
function sendRequests() {
$cmh = curl_multi_init();
$tasks = array();
foreach ( $
this
->_uris as $uri ) {
$uri_parts = parse_url($uri);
$scheme = isset($uri_parts[
'scheme'
]) ? $uri_parts[
'scheme'
] : NULL;
$host = isset($uri_parts[
'host'
]) ? $uri_parts[
'host'
] : NULL;
$port = isset($uri_parts[
'port'
]) ? $uri_parts[
'port'
] : NULL;
$user = isset($uri_parts[
'user'
]) ? $uri_parts[
'user'
] : NULL;
$pass = isset($uri_parts[
'pass'
]) ? $uri_parts[
'pass'
] : NULL;
$path = isset($uri_parts[
'path'
]) ? $uri_parts[
'path'
] : NULL;
$query = isset($uri_parts[
'query'
]) ? $uri_parts[
'query'
] : NULL;
$fragment = isset($uri_parts[
'fragment'
]) ? $uri_parts[
'fragment'
] : NULL;
$ch = curl_init($scheme .
'://'
. $host .
':'
. $port . $path . ($query ?
'?'
.$query :
''
));
curl_setopt($ch, CURLOPT_PORT, $port);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_TIMEOUT, $
this
->_request_timeout);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
$tasks[$uri] = $ch;
curl_multi_add_handle($cmh, $ch);
}
$active =
null
;
do
{
$mrc = curl_multi_exec($cmh, $active);
}
while
( $mrc == CURLM_CALL_MULTI_PERFORM );
while
( $active && ($mrc == CURLM_OK) ) {
if
( curl_multi_select($cmh) != -
1
) {
do
{
$mrc = curl_multi_exec($cmh, $active);
$msgs_in_queue =
1
;
while
( $msgs_in_queue ) {
$msgs_in_queue = $
this
->_setResponses($tasks, $cmh);
}
}
while
( $mrc == CURLM_CALL_MULTI_PERFORM );
}
}
curl_multi_close($cmh);
return
$
this
;
}
/**
* Сохранение результатов ответа
*
* @access private
* @param array $tasks
* @param object $cmh
* @return int
*/
private
function _setResponses($tasks, $cmh) {
$returnValue =
0
;
$info = curl_multi_info_read($cmh, $returnValue);
if
( $info[
'msg'
] == CURLMSG_DONE ) {
$ch = $info[
'handle'
];
$uri = array_search($ch, $tasks);
$
this
->_responses[$uri] = curl_multi_getcontent($ch);
curl_multi_remove_handle($cmh, $ch);
curl_close($ch);
}
return
$returnValue;
}
/**
* Получение ответа с преобразованием данных в массив
*
* @access public
* @param string $route
* @return mixed
*/
public
function getResponses(array $formats, array $params=array()) {
$returnValue = NULL;
foreach( $
this
->_uris as $key=>$uri ) {
if
( !empty($
this
->_responses[$uri]) ) {
switch
( strtolower($formats[$key]) ) {
case
'xml'
:
$returnValue[$key] = simplexml_load_string($
this
->_responses[$uri]);
break
;
case
'json'
:
$returnValue[$key] = Json::decode($
this
->_responses[$uri], TRUE);
break
;
case
'csv'
:
$csv = array();
$results = explode(
"\n"
, $
this
->_responses[$uri]);
foreach ( $results as $result ) {
$csv[] = str_getcsv($result, $params[$key][
'delimiter'
], $params[$key][
'enclosure'
], $params[$key][
'escape'
]);
}
$returnValue[$key] = $csv;
break
;
default
:
$returnValue[$key] = $
this
->_responses[$uri];
break
;
}
}
}
return
$returnValue;
}
}
?>