0

我创建了一个网站,其中包含使用 XML 来驱动其一些内容,例如,如下所示的当前汇率。

在此处输入图像描述 该网站比较了三种汇率,我目前对每个执行相同目标的城市使用单独的函数,例如返回当前汇率。

这些函数之间的唯一区别是我从中请求数据的 XML 文档中 item 标记的位置。

  $exchange['rate'] = $xml->channel->item[15]->description;

注意 上面数组中的item[15],它提供了对欧元货币的访问。在下文中,美国货币是项目[56],如下所示。

  $exchange['rate'] = $xml->channel->item[56]->description;

如果可以将三个功能组合成一个功能以增加凝聚力,有什么想法吗?

我用于访问欧元货币的功能是:

<?php

function get_rate1(SimpleXMLElement $xml) {

    // Match numeric values before and after decimal place
    $exchange['rate'] = $xml->channel->item[15]->description;
    preg_match('/([0-9]+\.[0-9]+)/', $exchange['rate'], $matches);
    $rate = $matches[0];

    // Get currency type from title
    $title['rate'] = $xml->channel->item[15]->title;
    $title = explode('/', $title['rate']);
    $title = $title[0];

    echo $rate . ' ' . $title . '<br />';

    return $rate;
}

?>

提要 URL 设置在另一个名为 cityConfig.php 的配置脚本中

<?php

// City 1 //
$city1 = 'Paris';
$exchangeRate1 = '1 Euro';
$exchangeRate1RssUrl = 'http://themoneyconverter.com/rss-feed/EUR/rss.xml';

?>

提前致谢

4

3 回答 3

2

试试这个大小 - 它使用三个字母的货币代码,并使用 XPath 来查找它们,完全消除了那些讨厌的索引。您只需要提供源货币的三字母代码和目的地的三字母代码,或者如果您想一次获得多个目的地,则需要提供一组目的地。

已修改,因此$dest现在是可选的。如果仅$source提供,则返回所有汇率的数组。

function get_rate ($source, $dest = NULL) {

  // Make sure source currency is upper case
  $source = strtoupper($source);

  // Construct the source URL
  $url = "http://themoneyconverter.com/rss-feed/$source/rss.xml";

  // This will hold the results
  $result = array();

  // Fetch and parse the data
  if (!$xml = simplexml_load_file($url)) {
    return FALSE;
  }

  if ($dest === NULL) {

    // Get all <item> nodes and loop them
    foreach ($xml->xpath("//item") as $item) {

      // Find the code of this currency
      $currencyParts = explode('/', $item->title);

      // Get the value of this currency
      $result[$currencyParts[0]] = (preg_match('/([0-9]+\.[0-9]+)/', $item->description, $matches)) ? (float) $matches[0] : FALSE;

    }

  } else {

    // Loop the destination currencies
    foreach ((array) $dest as $currency) {

      // Make sure destination currencies are upper case
      $currency = strtoupper($currency);

      // Perform an XPath search for this currency
      $nodes = $xml->xpath("//item[title='$currency/$source']/description");

      // If we found the currency and could extract the value, add it to the
      // result array as a float
      $result[$currency] = (count($nodes) === 1 && preg_match('/([0-9]+\.[0-9]+)/', $nodes[0], $matches)) ? (float) $matches[0] : FALSE;

    }

  }

  // If only a single value was requested return it, otherwise return the array
  return (count($result) === 1) ? array_shift($result) : $result;

}

示例用法:

$result = get_rate('GBP', 'USD');
var_dump($result);
/*
  float(1.58014)
*/

$result = get_rate('GBP', array('USD', 'EUR'));
var_dump($result);
/*
  array(2) {
    ["USD"]=>
    float(1.58014)
    ["EUR"]=>
    float(1.20236)
  }
*/

$result = get_rate('GBP');
var_dump($result);
/*
  array(64) {
    ["AED"]=>
    float(5.80445)
    ["ARS"]=>
    float(6.85316)
    ["AUD"]=>
    float(1.47589)
    ["BBD"]=>
    float(3.16103)
    ["BHD"]=>
    float(0.59427)
    ["BOB"]=>
    float(10.92135)
    ["BRL"]=>
    float(2.72171)
    ["CAD"]=>
    float(1.57968)
    ["CHF"]=>
    float(1.44883)
    ["CLP"]=>
    float(759.35947)
    ["CNY"]=>
    float(9.96753)
    ["COP"]=>
    float(2840.97943)
    ["CZK"]=>
    float(30.15863)
    ["DKK"]=>
    float(8.97219)
    ["EGP"]=>
    float(9.53446)
    ["EUR"]=>
    float(1.20265)
    ["HKD"]=>
    float(12.24901)
    ["HUF"]=>
    float(350.91425)
    ["IDR"]=>
    float(14121.92063)
    ["ILS"]=>
    float(5.87877)
    ["INR"]=>
    float(77.48491)
    ["ISK"]=>
    float(194.46687)
    ["JMD"]=>
    float(136.31954)
    ["JOD"]=>
    float(1.12059)
    ["JPY"]=>
    float(120.36272)
    ["KES"]=>
    float(132.28924)
    ["KRW"]=>
    float(1763.3828)
    ["KWD"]=>
    float(0.43897)
    ["LBP"]=>
    float(2382.62959)
    ["LKR"]=>
    float(180.02093)
    ["LTL"]=>
    float(4.1525)
    ["LVL"]=>
    float(0.84522)
    ["MAD"]=>
    float(13.39206)
    ["MXN"]=>
    float(20.24582)
    ["MYR"]=>
    float(4.77078)
    ["NAD"]=>
    float(12.10631)
    ["NGN"]=>
    float(253.27781)
    ["NOK"]=>
    float(9.21948)
    ["NPR"]=>
    float(123.97585)
    ["NZD"]=>
    float(1.89597)
    ["OMR"]=>
    float(0.6077)
    ["PAB"]=>
    float(1.58052)
    ["PEN"]=>
    float(4.25316)
    ["PHP"]=>
    float(67.48803)
    ["PKR"]=>
    float(142.95779)
    ["PLN"]=>
    float(5.03909)
    ["QAR"]=>
    float(5.75308)
    ["RON"]=>
    float(5.23271)
    ["RUB"]=>
    float(47.73085)
    ["SAR"]=>
    float(5.92694)
    ["SEK"]=>
    float(10.66422)
    ["SGD"]=>
    float(1.96993)
    ["THB"]=>
    float(48.79218)
    ["TRY"]=>
    float(2.77931)
    ["TWD"]=>
    float(46.6742)
    ["UAH"]=>
    float(12.71293)
    ["USD"]=>
    float(1.58052)
    ["UYU"]=>
    float(30.74107)
    ["VEF"]=>
    float(6.79622)
    ["VND"]=>
    float(33119.73602)
    ["XAF"]=>
    float(788.88394)
    ["XCD"]=>
    float(4.2674)
    ["XOF"]=>
    float(788.88394)
    ["ZAR"]=>
    float(12.10631)
  }
*/
于 2012-02-02T18:38:00.487 回答
1

您如何将 rate 函数更改为:

<?php

function get_rate(SimpleXMLElement $xml, $id) {

    // Match numeric values before and after decimal place
    $exchange['rate'] = $xml->channel->item[$id]->description;
    preg_match('/([0-9]+\.[0-9]+)/', $exchange['rate'], $matches);
    $rate = $matches[0];

    // Get currency type from title
    $title['rate'] = $xml->channel->item[$id]->title;
    $title = explode('/', $title['rate']);
    $title = $title[0];

    echo $rate . ' ' . $title . '<br />';

    return $rate;
}

?>

然后你可以这样称呼它:

$rate1 = get_rate($xml,15);
$rate2 = get_rate($xml,56);
于 2012-02-02T17:37:01.780 回答
1

由于我还不能发表评论...... helk 的答案是完美的 - 你可以更进一步并定义一些类常量或定义()的常量,这样你就不会在你的代码中处理难以记住的数字(记住,你可能不是唯一一个看过这段代码的人——你知道 15 是什么,但 Jr. Dev Newguy 不知道):

<?php

define('CURRENCY_USA', 56);
define('CURRENCY_EURO', 15);

// OR something like:
class CurrencyHelper
{
    const CURRENCY_USA = 56;
    const CURRENCY_EURO = 15;

    // of course, you could also define get_rate here too...
    public function __construct(SimpleXmlElement $xml)
    {
        $this->xml = $xml;
    }  

    public function get_rate($id)
    {
      // ... your code here
    }
}

// Or, define your get_rate as originally intended:

function get_rate(SimpleXMLElement $xml, $id) {

    // Match numeric values before and after decimal place
    $exchange['rate'] = $xml->channel->item[$id]->description;
    preg_match('/([0-9]+\.[0-9]+)/', $exchange['rate'], $matches);
    $rate = $matches[0];

    // Get currency type from title
    $title['rate'] = $xml->channel->item[$id]->title;
    $title = explode('/', $title['rate']);
    $title = $title[0];

    echo $rate . ' ' . $title . '<br />';

    return $rate;
}

// Finally:
echo get_rate($xml, CURRENCY_EURO); // define
echo get_rate($xml, CurrencyHelper::CURRENCY_USA; // class constant
$myCurr = new CurrencyHelper($xml);
$myCurr->get_rate(CurrencyHelper::CURRENCY_USA); // Over-oop'd solution : P

?>
于 2012-02-02T17:55:18.437 回答