重用 PHP 函数从 XML 文档访问数组项标签

发布于 2025-01-02 02:24:26 字数 1329 浏览 0 评论 0原文

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

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

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

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

请注意上面数组中的 item[15],它提供了对欧元货币的访问。在下文中,美国货币为 item[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;
}

?>

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

<?php

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

?>

提前致谢

I have created a website that contains that uses XML to drive some of its contents, for example, the current exchange rates as shown below.

enter image description here
The website compares three exchange rates and I currently use a separate functions for each city that perform identical goals e.g. returning the current exchange rates.

The only difference between these functions are the positions of the item tag from the XML document that I request the data from.

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

Notice item[15] in the above array which provides access to the Euro currency. In the following, the USA currency is item[56] as below.

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

Any ideas if it is possible to combine the three functions into a single one to increase cohesion?

The function I use for accessing the Euro currency is:

<?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;
}

?>

The feed URL's are set in another configuration script called cityConfig.php

<?php

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

?>

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

皓月长歌 2025-01-09 02:24:26

尝试一下这个大小 - 它使用三个字母的货币代码,并使用 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)
  }
*/

Try this on for size - it uses the three letter currency codes, and uses XPath to find them, doing away with those nasty indexes altogether. All you need to supply is the three letter code of the source currency, and the three letter code of the destination, or an array of destinations if you want to get more than one at once.

MODIFIED so that $dest is now optional. If only $source is supplied, return an array of all exchange rates.

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;

}

Example usage:

$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)
  }
*/
生来就爱笑 2025-01-09 02:24:26

您可以将速率函数更改为这样:

<?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);

How about you change the rate function to this:

<?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;
}

?>

Then you can call it like this instead:

$rate1 = get_rate($xml,15);
$rate2 = get_rate($xml,56);
财迷小姐 2025-01-09 02:24:26

因为我还不能发表评论...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

?>

Since I can't comment yet...helk's answer is perfect - you could take it one step further and define some class constants or define()'d constants so you aren't dealing with hard to remember numbers in your code (remember, you may not be the only person who ever looks at this code - you know what 15 is, but Jr. Dev Newguy does not):

<?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

?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文