Оптимизация вложенных циклов foreach в PHP для парсинга XML

Рейтинг: 0Ответов: 1Опубликовано: 09.12.2014

Здравствуйте.

Возник вопрос по оптимизации вложенных циклов с целью парсинга в БД данных из XML.

<?php

// читаем XML с районами
$xmlFile = "http://путь-к-XML/Districts";
$xml = simplexml_load_file($xmlFile);
$districts = $xml->Districts->District;

foreach($districts as $val) {
    $districtId = $val['Id'];
    $districtName = $val['Name'];

    // пишем результаты в БД

    /* 
    Читаем XML с городами в каждом районе.
    Для чтения городов, необходимо передать ардесной строке с XML файлом Id района   
    */
    $xmlFile2 = "http://путь-к-XML/Cities".$districtId;
    $xml2 = simplexml_load_file($xmlFile2);
    $cities = $xml2->Cities->City;

    foreach($cities as $val) {
        $cityId = $val['Id'];
        $cityName = $val['Name'];

        // пишем результаты в БД

        /* 
        Читаем XML с улицами в каждом городе.
        Для чтения улиц, необходимо передать ардесной строке с XML файлом Id города   
        */
        $xmlFile3 = "http://путь-к-XML/Cities".$districtId;
        $xml3 = simplexml_load_file($xmlFile3);
        $streets = $xml3->Streets->Street;

        foreach($streets as $val) {
            $streetId = $val['Id'];
            $streetName = $val['Name'];

            // пишем результаты в БД

            // и т.д. вплоть до дома
        }
    }
}

?>

С каждым циклом увеличивается количество итераций, выполняется такой вариант крайне долго, и очевидно, что это неэффективное решение. "Коматозить" его начитает уже на 3-м цикле при попытке не то чтобы записать в базу, даже посчитать количество улиц.

Вопрос: как можно оптимизировать данный парсер?

Буду признателен за помощь.

Ответы

▲ 1

Ну так и разбейте все на три разных сервиса. Прочитали и записали сначала только дистрикты, потом погрузили их в базу, все отработало - и вы молодец. Далее запускаем импорт городов, делаем запрос в бд на выбор всех id дистриктов (если там много будет лишних id, то в первом сервисе сделайте пометку new = 1 в бд и выбирайте потом только их, а потом просто общим апдейтом сделаете new = 0), ну и тоже самое с улицами. Как-то так. )