使用 XML 提取 XML 中的 ECB 汇率时遇到一些问题..有问题的完整源代码
我需要获取内部会计系统的历史汇率参考率列表。
这个问题仅涉及以下代码,如果您发现它有用,请随意使用此代码(当然,一旦我们得到解决最终“问题”的答案。我在代码中包含了数据库结构转储,所有数据库例程已被注释掉,目前仅回显调试数据
数据取自欧洲中央银行 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€= ".$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 您会发现日期是正确的,它可以很好地处理缺少的周末和银行假日日期,但汇率值仅引用 XML 中的最新汇率,即今天的值。
$_rate),如果您尝试运行该脚本, 从 XML 中的相关区域提取数据,即给定日期的费率...但事实并非如此。这是 simplexml_load_file 中的问题还是我在代码中错过了一些愚蠢的东西?现在头开始疼了,先休息一下。新鲜的眼睛是最受欢迎的!
I need to grab a list of historic Exchange rate reference rates for an internal accounting system.
This question is about the following code only, feel free to use this code if you find it useful (and of course once we get an answer to fix the final "niggle". i have included a DB structure dump in the code, all DB routines are commented out, just echoing debug data for now.
Data is taken from the European Central Bank XML found at http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml
FIXED! Feel free to use this code if you need to pull a list of historic exchange rate values into a DB.. make sure to remove echo debugging and sort out the DB queries
<?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€= ".$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>";
?>
So..... the problem is in the 2nd foreach loop: foreach($XML->Cube->Cube->Cube as $_rate), if you try running the script you will notice that the dates are right, it handles missing weekend and bank holiday dates well, but the rate values only ever reference the latest rates in the XML, ie todays values.
It should be pulling data from the relevant area in the XML, ie the rates for the given date... but its not. Is this a problem in simplexml_load_file or have I missed somthing stupid in my code? Head starting to hurt now so gonna take a break. Fresh eyes are most welcome!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第二个循环中的
$XML->Cube->Cube->Cube
:$XML->Cube->Cube
始终引用第一个第二个 -第一个第一级多维数据集
中的级别多维数据集
。因此,您正在迭代同一元素中的第三级多维数据集
。因此,您只能获得今天的费率。有道理吗?试试这个吧。我已将您的代码修改为命令行输出而不是 html。唯一的主要变化是第二个
foreach
语句......$XML->Cube->Cube->Cube
in your second loop:$XML->Cube->Cube
always refers to the first second-levelcube
in the first first-levelcube
. So you were iterating over the third levelcubes
in that same element. Thus, you got only today's rates. Make sense?Try this instead. I've modified your code for command-line output rather than html. The only major change is in the second
foreach
statement...