【问题标题】:PHP foreach loop, how to use variables retrieved in another function between iterations?PHP foreach循环,如何在迭代之间使用在另一个函数中检索到的变量?
【发布时间】:2013-04-22 13:14:51
【问题描述】:

我是 PHP 新手,我正在学习从 xml 和 json 文件中检索一些动态数据。我制作了两个代码来做两件不同的事情。第一个是 xml 游戏列表数据,如下所示:

https://steamcommunity.com/id/aksn1p3r/games?tab=all&xml=1

我想做的是结合两种获取数据的方式,从那个 xml 获取数据,然后使用变量 $appid 从另一个 json 数据源获取更多信息,然后再迭代下一个 $gdata。

<?php

$glist = 'https://steamcommunity.com/id/aksn1p3r/games?tab=all&xml=1';
$gxml = simplexml_load_file($glist);

foreach($gxml->games->game as $game) {

$appid = $game->appID;
$glink = $game->storeLink;
$gname = $game->name;
$glogo = $game->logo;

echo '<p>'. $appid . ' <a href="'. $glink .'">'. $gname .'<br>';
echo '<img src="'. $glogo .'" /></a></p>';

}

?>

这是一个 json:[http://store.steampowered.com/api/appdetails/?appids=8870],它是使用名为 $appid 的变量构造的强>。

我希望它在上述循环中的下一次迭代之前构造一个新链接,然后从 json 源中获取 price aka $gprice,如下所示:

<?php

$appid = '8870';

$ht = 'http://store.steampowered.com/api/appdetails/?appids=' . $appid;

$fgc = file_get_contents($ht);
$jd = json_decode($fgc, true);

$gdata = $jd[$appid]['data'];

$gprice = $gdata['price_overview']['final'];
$price = number_format($gprice / 100, 2);

echo 'Price: $' .$price;

?>

这是我尝试组合它的方式,但它挂起或出错。

<?php

$glist = 'https://steamcommunity.com/id/aksn1p3r/games?tab=all&xml=1';
$gxml = simplexml_load_file($glist);

foreach($gxml->games->game as $game) {

$appid = $game->appID;
$glink = $game->storeLink;
$gname = $game->name;
$glogo = $game->logo;

echo '<p>'. $appid . ': <a href="'. $glink .'">'. $gname .'<br>';
echo '<img src="'. $glogo .'" /></a><br>';

$gjson = 'http://store.steampowered.com/api/appdetails/?appids=' . $appid;
$fgc = file_get_contents($gjson);
$jd = json_decode($fgc, true);

$gdata = $jd[$appid]['data'];

$gprice = $gdata['price_overview']['final'];
$price = number_format($gprice / 100, 2);

echo 'Price: $' .$price. '</p>';    
}

?>

我希望它使用 $appid 每个循环来构建到源的链接:$gjson,然后是 file_get_contents($gjson) ; 获取数据,然后在继续下一项之前回显该 $gprice。

我犯的任何指示或错误,请帮助我使其正常工作?

【问题讨论】:

  • it hangs or errors - 您是否收到任何错误消息?您可能需要检查是否配置了足够的错误报告 (php.net/manual/en/function.error-reporting.php)。另外,我通常发现print_r 在调试时非常有用(php.net/manual/en/function.print-r.php)。
  • error_reporting(E_ALL) 和 ini_set("display_errors",1); ...显示什么?还有 file_get_contents() 错误?
  • 警告:第 27 行 /steamgame.php 中的非法偏移类型在我的代码中,第 27 行是这一行:$jd = json_decode($fgc, true); $gdata = $jd[$appid]['data'];
  • 您会收到错误消息,因为 $appid 不是字符串。将其转换为字符串:(string) $appid(与您使用的 simplexmlelement 一起使用)。这是一个常见的错误,如果您知道如何解决,则很容易解决。积极处理错误报告和错误记录,因为 PHP 会告诉您在哪里可以找到(潜在)问题。

标签: php xml json variables foreach


【解决方案1】:

其实你的代码本身并没有错……唯一的错误是那行中的$appid应该是integer,而不是string。

$gdata = $jd[$appid]['data'];

您认为脚本挂起 - 好吧,它没有。它运行良好并完成其工作。 问题在于您检索数据的方式 - 它不是那么快。

您的列表包含 100 多个游戏。所以基本上你的脚本打开 appdetails 远程文件和json_decodes 超过 100 次。这需要一段时间,直到foreach 循环停止执行之前没有输出,因此您可以认为脚本挂起。

我稍微修改了您的代码,以便您了解它的内容。

<?php

$glist = 'https://steamcommunity.com/id/aksn1p3r/games?tab=all&xml=1';
$gxml = simplexml_load_file($glist);

$i = 0; //just used to exit loop after 5 executions
foreach($gxml->games->game as $game) {
    if($i >= 5) {
        break;
    }
    $appid = $game->appID;
    $glink = $game->storeLink;
    $gname = $game->name;
    $glogo = $game->logo;

    echo '<p>'. $appid . ': <a href="'. $glink .'">'. $gname .'<br>';
    echo '<img src="'. $glogo .'" /></a><br>';

    $gjson = 'http://store.steampowered.com/api/appdetails/?appids=' . $appid;
    $fgc = file_get_contents($gjson);
    $jd = json_decode($fgc, true);

    $gdata = $jd[intval($appid)]['data']; //$appid needs to be integer here, not string

    $gprice = $gdata['price_overview']['final'];
    $price = number_format($gprice / 100, 2);

    echo 'Price: $' .$price. '</p>';    

    $i++;
}

?>

运行它并等待几秒钟。它应该显示 5 个游戏及其价格(如果游戏可以免费玩,则显示错误......)。

现在,如果加载五个游戏的图像和价格大约需要 5 秒,则处理所有 100 多个游戏大约需要 2 分钟。如果你不想等那么久,你应该换个方式。

【讨论】:

  • 非常感谢您向我保证我的代码逻辑都很好,并且必须使用整数,虽然它必须是整数而不是简单的字符串,但很奇怪。我也不确定还有什么方法可以更快地获取信息,也许是第一次将它存储到 MySQL 中,然后再从 MySQL 中更快地访问?
  • 这可能是个好主意,但第一次操作仍然很耗时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 2012-08-02
  • 2021-12-22
  • 2013-03-23
  • 2020-08-15
  • 1970-01-01
  • 2021-01-26
相关资源
最近更新 更多