Answer the question
In order to leave comments, you need to log in
How to improve response handling from API via SOAP protocol?
There is a task to connect the Booking-Manager.com API to the site. The API uses the SOAP protocol.
I seem to have connected everything and wrote the search form, but the results are loading for a very long time
. The response from the server, when using the search, I receive in this form:
<root>
<resource resourceid="" companyid=”” reservationstatus="" baseprice=""
discountvalue="" price="" baseid=”” datefrom=”” dateto=””></resource>
…
</root>
function getSearchResults($dataConnect,$_xmlValues,$fieldsMain) {
$connectOptions = $dataConnect;
$struct = array($connectOptions['id'], $connectOptions['email'], $connectOptions['password'], $_xmlValues);
$result = soapClientResult($struct,'getSearchResultsFilter');
$resources_final = array();
if (!is_soap_fault($result)) {
try {
if(isset($result->out)) {
$resources = array();
$xml = $result->out;
$reader = new XMLReader();
$reader->xml($xml);
$dom = new DOMDocument();
$i = 0;
while($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == "resource") {
$node = simplexml_import_dom($dom->importNode($reader->expand(), true));
$resources[$i]['resourceid'] = $reader->getAttribute('resourceid');
$resources[$i]['baseprice'] = $reader->getAttribute('baseprice');
$resources[$i]['reservationstatus'] = $reader->getAttribute('reservationstatus');
$resources[$i]['baseid'] = $reader->getAttribute('baseid');
$i++;
}
}
$reader->close();
$i = 0;
foreach ($resources as $resource) {
$resources_final[$i] = get_xml_soap_single($connectOptions,$resource['resourceid'],false,$fieldsMain);
if($i == 50) {
break;
}
$i++;
}
}
}
catch (Exception $e) {
print_r($e->getMessage());
echo '<br>';
print_r($soapClient->__getLastRequest());
echo '<br>';
print_r($soapClient->__getLastResponse());
}
} else {
return 'error';
}
return $resources;
}
//SOAP CLIENT
function get_soapClient() {
$wsdl = 'https://www.booking-manager.com/cbm_web_service2/services/CBM?wsdl';
$arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));
$options = array(
'exceptions'=>false,
'trace'=>1,
'stream_context' => stream_context_create($arrContextOptions),
'keep_alive' => true,
);
$soapClient = new SoapClient($wsdl, $options);
return $soapClient;
}
//Cбор аттрибутов отдельных элементов XML по Name
function soapXMLReaderGetResult($dom,$reader,$resource,$result_final,$result_source,$array_name,$final,$count,$current_count) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == $resource) {
$node = simplexml_import_dom($dom->importNode($reader->expand(), true));
if($reader->hasAttributes) {
while($reader->moveToNextAttribute()) {
if($count == true) {
if($final == true) {
$result_final[$array_name][$current_count][$reader->name] = $reader->value;
} else {
$result_source[$array_name][$current_count][$reader->name] = $reader->value;
}
} else {
if($final == true) {
$result_final[$array_name][$reader->name] = $reader->value;
} else {
$result_source[$array_name][$reader->name] = $reader->value;
}
}
}
}
}
if($final == true) {
return $result_final[$array_name];
} else {
return $result_source[$array_name];
}
}
// Инициализация подключения к SOAP
function soapClientResult($struct_result, $struct_function) {
$soapClient = get_soapClient();
$struct = new MMKStruct($struct_result);
$result = $soapClient->__soapCall($struct_function,array($struct));
return $result;
}
// Собственно сама обработка ресурса
function get_xml_soap_single($dataConnect,$request_id,$single = bool,$fieldsSearch) {
$pathImages = $_SERVER['DOCUMENT_ROOT'] . '/tmp/images';
if(!file_exists($pathImages)) {
mkdir($pathImages,0755,true);
} else {
foreach (glob($pathImages.'/*') as $file) {
unlink($file);
}
}
$currentDate = date('Y-m-d');
$connectOptions = $dataConnect;
$struct = array($connectOptions['id'], $connectOptions['email'], $connectOptions['password'], $request_id);
$result = soapClientResult($struct,'getResourceDetails');
if (!is_soap_fault($result)) {
try {
$result_source = array();
$result_source['prices_source'] = array();
$result_source['images_source'] = array();
$result_source['locations_source'] = array();
$result_final = array();
$result_final['attributes'] = array();
$result_final['prices_current'] = array();
$result_final['images_final'] = array();
$result_final['locations_current'] = array();
$result_final['locations_current_base'] = array();
if(isset($result->out)) {
$xml = $result->out;
$reader = new XMLReader();
$reader->xml($xml);
$dom = new DOMDocument();
$resource_count = 0;
$prices_count = $images_count = $equipment_count = $extras_count = $discounts_count = $products_count = $locations_count = 0;
while($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT) {
if($reader->name == 'resource') {
$resource_count = 0;
}
if ($reader->name == 'price') {
++$prices_count;
}
if ($reader->name == 'image') {
++$images_count;
}
if ($reader->name == 'location') {
++$locations_count;
}
}
$result_final['attributes'] = soapXMLReaderGetResult($dom,$reader,'resource',$result_final,$result_source,'attributes',true,false,$resource_count);
$result_source['prices_source'] = soapXMLReaderGetResult($dom,$reader,'price',$result_final,$result_source,'prices_source',false,true,$prices_count);
$result_source['images_source'] = soapXMLReaderGetResult($dom,$reader,'image',$result_final,$result_source,'images_source',false,true,$images_count);
$result_source['locations_source'] = soapXMLReaderGetResult($dom,$reader,'location',$result_final,$result_source,'locations_source',false,true,$locations_count);
}
$reader->close();
usort($result_source['images_source'], "images_sort_main");
if(file_exists($_SERVER['DOCUMENT_ROOT'] . '/tmp/images')) {
$i = 0;
foreach ($result_source['images_source'] as $image) {
$fileBasename = basename($image['href']);
$result_final['images_final'][$i]['href'] = '/tmp/images/' . $fileBasename;
$result_final['images_final'][$i]['comment'] = $image['comment'];
$i++;
}
}
usort($result_source['prices_source'], "cmp_date");
$alignment_validate = false;
foreach ($result_source['prices_source'] as $price) {
if(strtotime($price['datefrom']) < strtotime($currentDate) && strtotime($price['dateto']) > strtotime($currentDate)) {
foreach($price as $key => $val) {
$result_final['prices_current'][$key] = $val;
}
$alignment_validate = true;
break;
}
}
if(!$alignment_validate) {
foreach ($result_source['prices_source'][0] as $key => $val) {
$result_final['prices_current'][$key] = $val;
}
}
if($result_source['locations_source'] != 0) {
usort($result_source['locations_source'], "cmp_date");
$alignment_validate = false;
foreach ($result_source['locations_source'] as $price) {
if(strtotime($price['datefrom']) < strtotime($currentDate) && strtotime($price['dateto']) > strtotime($currentDate)) {
foreach($price as $key => $val) {
$result_final['locations_current'][$key] = $val;
}
$alignment_validate = true;
break;
}
}
if(!$alignment_validate) {
foreach ($result_source['locations_source'][0] as $key => $val) {
$result_final['locations_current'][$key] = $val;
}
}
if($result_final['locations_current'] != 0) {
$baseCurrent = soapClientBasesCurrent($result_final['locations_current']['baseid'],$fieldsSearch);
if($baseCurrent != false) {
$result_final['locations_current_base'] = $baseCurrent;
}
}
}
if($result_final != 0) {
return $result_final;
}
}
}
catch (Exception $e) {
print_r($e->getMessage());
echo '<br>';
print_r($soapClient->__getLastRequest());
echo '<br>';
print_r($soapClient->__getLastResponse());
}
} else {
return false;
}
}
Answer the question
In order to leave comments, you need to log in
If there is no other possibility in the API for extended data retrieval, you need to either reduce the amount of output to a list (if the task allows), or generally output data retrieval to a separate process (daemon) that is not associated with issuing responses to the user, with the organization of a queue for processing and issuing results after a time longer than the web server's timeout settings.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question