Возникли проблемы с извлечением курсов обмена ECB в XML с XML. Полный исходный код

Мне нужно взять список исторических справочных курсов валют для внутренней системы бухгалтерского учета.

Этот вопрос касается только следующего кода, не стесняйтесь использовать этот код, если он окажется для вас полезным (и, конечно же, как только мы получим ответ, чтобы исправить последнее "недоразумение". Я включил в код дамп структуры БД, все БД подпрограммы закомментированы, пока только повторяя данные отладки.

Данные взяты из XML Европейского центрального банка, который можно найти по адресу http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml

ФИКСИРОВАННЫЙ! Не стесняйтесь использовать этот код, если вам нужно вытащить список исторических значений обменного курса в БД. Убедитесь, что вы удалили отладку эха и отсортировали запросы к БД.

<?php

/* DB structure:
 CREATE TABLE IF NOT EXISTS `currency_rates_history` (
  `id` int(4) NOT NULL auto_increment,
  `currency` char(3) character set utf8 collate utf8_unicode_ci NOT NULL default '',
  `rate` float NOT NULL default '0',
  `date` int(4) NOT NULL default '0',
  `est` tinyint(1) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8_unicode_ci AUTO_INCREMENT=1 ;

*/

error_reporting(E_ALL);

$table = "currency_rates_history";

$secs = '86400';

$prev_date = time();

$days = "0";

$XML=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml");    // European Central Bank xml only contains business days! oh well....


foreach($XML->Cube->Cube as $time)                                                          // run first loop for each date section
{

    echo "<h1>".$time["time"].'</h1>';

    list($dy,$dm,$dd) = explode("-", $time["time"]);

    $date = mktime(8,0,0,$dm,$dd,$dy);

    echo ($prev_date - $date)."<br />";

    if(($prev_date - $date) > $secs)                                                        // detect missing weekend and bank holiday values.
    {

        echo "ooh";                                                                         // for debug to search the output for missing days

        $days =(round((($prev_date - $date)/$secs),0)-1);                                   // got to remove 1 from the count....

        echo $days;                                                                         // debug, will output the number of missing days

    }
    foreach($time->Cube as $_rate)                                              // That fixed it! run the 2nd loop and ad enter the new exchange values....
    {

        $rate = floatval(str_replace(",", ".", $_rate["rate"]));


        if($days > 0)                                                                       // add the missing dates using the last known value, coul dbe more accurate but at least there is some reference data to work with
        {
            $days_cc = $days;                                                               // need to keep $days in mem for the next currency

            while($days_cc > 0)
            {
                echo $rate;
                echo date('D',$date+($days_cc*$secs))."<br />";
                /*
                mysql_query("LOCK TABLES {$table} WRITE");

                mysql_query("INSERT INTO {$table}(rate,date,currency,est) VALUES('{$rate}','".($date+($days_cc*$secs))."','{$currency}','1')");

                mysql_query("UNLOCK TABLES");
                */
                $days_cc = ($days_cc - 1);  // count down
            }
        }

        $currency = addslashes(strtolower($_rate["currency"]));
        /*
        mysql_query("LOCK TABLES {$table} WRITE");
//      mysql_query("UPDATE {$table} SET rate='{$rate}',date='{$date}' WHERE currency='{$currency}' AND date='{$date}'");   // all this double checking was crashing the script
//      if (mysql_affected_rows() == 0)
//      {
            mysql_query("INSERT INTO {$table}(rate,date,currency) VALUES('{$rate}','{$date}','{$currency}')");              // so just insert, its only going to be run once anyway!
//      }

        mysql_query("UNLOCK TABLES");
        */

        echo "1&euro;=  ".$currency."   ".$rate.", date:   ".date('D d m Y',$date)."<br/>";
    }
          $days="";                                                                         // clear days value
    $prev_date = $date;                                                                     // store the previous date
}

echo "<h1>Currencies Saved!</h1>";
?>

Итак..... проблема во втором цикле foreach: foreach($XML->Cube->Cube->Cube as $_rate), если вы попытаетесь запустить скрипт, вы заметите, что даты правильные, он обрабатывает Отсутствуют выходные и праздничные дни, но значения ставок относятся только к последним ставкам в XML, т. е. сегодняшним значениям.

Он должен извлекать данные из соответствующей области в XML, то есть ставки на данную дату... но это не так. Это проблема в файле simplexml_load_file или я пропустил что-то глупое в своем коде? Голова начинает болеть, так что собираюсь сделать перерыв. Свежие глаза приветствуются!

1 ответ

Решение

$XML->Cube->Cube->Cube в вашем втором цикле: $XML->Cube->Cube всегда относится к первому второму уровню cube в первом первом уровне cube, Итак, вы перебираете третий уровень cubes в том же элементе. Таким образом, вы получили только сегодняшние тарифы. Есть смысл?

Попробуйте это вместо этого. Я изменил ваш код для вывода из командной строки, а не HTML. Единственное серьезное изменение во втором foreach заявление...

$XML=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml");
foreach($XML->Cube->Cube as $time){
    echo "----".$time["time"]. "----\n";
    foreach($time->Cube as $_rate){
        $rate = floatval(str_replace(",", ".", $_rate["rate"]));
        $currency = addslashes(strtolower($_rate["currency"]));
        echo "1 euro =  ".$currency."   ".$rate . "\n";
    }
    echo "------------------\n\n";
}
echo "Done!";
Другие вопросы по тегам