У меня есть этот XML-файл с именем flight-itinerary.xml. Уменьшенная версия показана ниже.
<itin line="1" dep="LOS" arr="ABV">
<flt>
<fltav>
<cb>1</cb>
<id>C</id>
<av>10</av>
<cur>NGN</cur>
<CurInf>2,0.01,0.01</CurInf>
<pri>15000.00</pri>
<tax>30800.00</tax>
<fav>1</fav>
<miles></miles>
<fid>11</fid>
<finf>0,0,1</finf>
<cb>2</cb>
<id>J</id>
<av>10</av>
<cur>NGN</cur>
<CurInf>2,0.01,0.01</CurInf>
<pri>13000.00</pri>
<tax>26110.00</tax>
<fav>1</fav>
<miles></miles>
<fid>12</fid>
<finf>0,0,0</finf>
</fltav>
</flt>
</itin>
Полный файл содержит 8 маршрутов <itin>
элементы. <fltav>
элемент каждого из <itin>
элементы содержит 11 из <cb>1</cb>
в <finf>0,0,1</finf>
групп.
И ниже код, который я использую для обработки файла:
<?php
function processFlightsData()
{
$data = array();
$dom= new DOMDocument();
$dom->load('flight-itinerary.xml');
$classbands = $dom->getElementsByTagName('classbands')->item(0);
$bands = $classbands->getElementsByTagName('band');
$itineraries = $dom->getElementsByTagName('itin');
$counter = 0;
foreach($itineraries AS $itinerary)
{
$flt = $itinerary->getElementsByTagName('flt')->item(0);
$dep = $flt->getElementsByTagName('dep')->item(0)->nodeValue;
$arr = $flt->getElementsByTagName('arr')->item(0)->nodeValue;
$time_data = $flt->getElementsByTagName('time')->item(0);
$departure_day = $time_data->getElementsByTagName('ddaylcl')->item(0)->nodeValue;
$departure_time = $time_data->getElementsByTagName('dtimlcl')->item(0)->nodeValue;
$departure_date = $departure_day. ' '. $departure_time;
$arrival_day = $time_data->getElementsByTagName('adaylcl')->item(0)->nodeValue;
$arrival_time = $time_data->getElementsByTagName('atimlcl')->item(0)->nodeValue;
$arrival_date = $arrival_day. ' '. $arrival_time;
$flight_duration = $time_data->getElementsByTagName('duration')->item(0)->nodeValue;
$flt_det = $flt->getElementsByTagName('fltdet')->item(0);
$airline_id = $flt_det->getElementsByTagName('airid')->item(0)->nodeValue;
$flt_no = $flt_det->getElementsByTagName('fltno')->item(0)->nodeValue;
$flight_number = $airline_id. $flt_no;
$airline_type = $flt_det->getElementsByTagName('eqp')->item(0)->nodeValue;
$stops = $flt_det->getElementsByTagName('stp')->item(0)->nodeValue;
$av_data = $flt->getElementsByTagName('fltav')->item(0);
$cbs = iterator_to_array($av_data->getElementsByTagName('cb')); //11 entries
$ids = iterator_to_array($av_data->getElementsByTagName('id')); //ditto
$seats = iterator_to_array($av_data->getElementsByTagName('av')); //ditto
$curr = iterator_to_array($av_data->getElementsByTagName('cur')); //ditto
$price = iterator_to_array($av_data->getElementsByTagName('pri')); //ditto
$tax = iterator_to_array($av_data->getElementsByTagName('tax')); //ditto
$miles = iterator_to_array($av_data->getElementsByTagName('miles')); //ditto
$fid = iterator_to_array($av_data->getElementsByTagName('fid')); //ditto
$inner_counter = 0;
for($i = 0; $i < count($ids); $i++)
{
$data[$counter][$inner_counter] = array
(
'flight_number' => $flight_number,
'flight_duration' => $flight_duration,
'departure_date' => $departure_date,
'departure_time' => substr($departure_time, 0, 5),
'arrival_date' => $arrival_date,
'arrival_time' => substr($arrival_time, 0, 5),
'departure_airport_code' => $dep,
'departure_airport_location_name' => get_airport_data($dep, $data_key='location'),
'arrival_airport_code' => $arr,
'arrival_airport_location_name' => get_airport_data($arr, $data_key='location'),
'stops' => $stops,
'cabin_class' => $ids[$i]->nodeValue,
'ticket_class' => $ids[$i]->nodeValue,
'ticket_class_nicename' => formate_ticket_class_name($ids[$i]->nodeValue),
'available_seats' => $seats[$i]->nodeValue,
'currency' => $curr[$i]->nodeValue,
'price' => $price[$i]->nodeValue,
'tax' => $tax[$i]->nodeValue,
'miles' => $miles[$i]->nodeValue,
);
++$inner_counter;
}
return $data;
}
?>
Теперь внешний цикл повторяется 8 раз для каждого <itin>
элемент, и во время каждой итерации внешнего цикла, внутренний цикл повторяется 11 раз, что приводит к 88 итерациям за проход и вызывает серьезные проблемы с производительностью. Что я ищу, так это более быстрый способ обработки файла. Любая помощь будет принята с благодарностью.
Я не думаю, что петля является узким местом. Вы должны проверить свои операции, которые вызываются в цикле, get_airport_data
а также formate_ticket_class_name
,
Опробовать свой код (без вспомогательных операций) на ряде itin
элементы занимает меньше секунды, проверьте эту скрипку: http://phpfiddle.org/main/code/7fpi-b3ka (Обратите внимание, что XML может не совпадать с вашим, я догадался, что многие элементы отсутствовали).
Если есть вызываемые операции, которые существенно увеличивают время обработки, попробуйте вызвать операцию с массивными данными или кэшировать ответы.
Других решений пока нет …