PHP foreach循环返回一个额外的不需要的数组(维基百科API)

时间:2017-01-05 05:45:08

标签: php arrays foreach wikipedia-api

我整天都在研究这个问题,但没有找到任何解决方案。我也是php的新手。

我的功能的目的是获取维基百科文章的用户输入(Category1)并返回其类别。下面的基本功能没有任何问题。

Array
(
[batchcomplete] => 
[query] => Array
    (
        [pages] => Array
            (
                [46212943] => Array
                    (
                        [pageid] => 46212943
                        [ns] => 0
                        [title] => Urban planning
                        [categories] => Array
                            (
                                [0] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:All Wikipedia articles written in American English
                                    )

                                [1] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Commons category with local link same as on Wikidata
                                    )

                                [2] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Pages using ISBN magic links
                                    )

                                [3] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Urban planning
                                    )

                                [4] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Use American English from April 2015
                                    )

                                [5] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Use dmy dates from April 2015
                                    )

                                [6] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Wikipedia articles needing clarification from June 2015
                                    )

                                [7] => Array
                                    (
                                        [ns] => 14
                                        [title] => Category:Wikipedia articles with GND identifiers
                                    )

                            )

                    )

            )

    )

)

城市规划的示例结果

$array1 = new RecursiveIteratorIterator(
        new RecursiveArrayIterator($array),
        RecursiveIteratorIterator::SELF_FIRST);

        foreach ($array1 as $key => $value) {
            if (is_array($value) && $key == 'categories') {
                $result = array_map(function($element){return $element['title'];}, $value);

                print_r($result);
                }               
        }

当我尝试从此数组中仅提取标题值时,我的问题就开始了。我试图用foreach循环来做到这一点,这是我在多维数组中找到的最简单的解决方案:

Array
(
[0] => Category:All Wikipedia articles written in American English
[1] => Category:Commons category with local link same as on Wikidata
[2] => Category:Pages using ISBN magic links
[3] => Category:Urban planning
[4] => Category:Use American English from April 2015
[5] => Category:Use dmy dates from April 2015
[6] => Category:Wikipedia articles needing clarification from June 2015
[7] => Category:Wikipedia articles with GND identifiers
)
Array
(
[ns] => 
[title] => C
)

我得到的代码是两个数组。一个数组只包含标题(我想要的),但也包含一个不需要的数组(有时包括第一个标题):

<span>

这个额外的数组是我不明白的。我认为这个问题是由foreach循环引起的。我尝试在循环之外取消设置$变量,但它没有帮助。如果我尝试将这些结果传递给另一个函数,额外的数组会变得特别麻烦。我怎样才能防止这种情况发生?

3 个答案:

答案 0 :(得分:1)

为简单起见,您可以手动遍历数组,而不是使用RecursiveIteratorIterator

对于大型数组,

RecursiveIteratorIterator kill performance

将提取逻辑更改为:

$result = array();
foreach($arr['batchcomplete']['query']['pages'] as $k => $v)
{
    foreach($v['categories'] as $cat)
    {
        $result[] = $cat['title'];
    }
}

Working Demo

答案 1 :(得分:1)

正如@samir所提到的,手动执行它会更快,但如果您需要一个遍历未知深度的搜索机制,您还可以使用基本的递归函数。它可能比OOP风格的RecursiveArrayIterator / RecursiveIteratorIterator快一点:

constructor(public events: Events) {}

// in now-playing
function createUser(user) {
  console.log('User created!')
  events.publish('user:created', user, Date.now());
}

// in channel inside
events.subscribe('user:created', (user, time) => {
  // user and time are the same arguments passed in `events.publish(user, time)`
  console.log('Welcome', user, 'at', time);
});

答案 2 :(得分:0)

这是PHP错误特征的有趣组合:

  • $key == 'categories'是非类型安全的比较;数组数组键是整数,并且为了将整数与字符串进行比较,PHP将字符串转换为整数:粗略地,它采用由数字组成的字符串的最长前缀。如果字符串根本不以数字开头,则字符串到整数转换的结果为0
    因此,您的条件将为真两次:对于categories子阵列及其第一个child(具有键0的那个)。提示:请始终使用===进行比较。
  • PHP允许在几乎任何不是数组的任何东西上使用[](数组索引)运算符(通常返回null)。因此,当array_map尝试获取$element['title'] $element = 14 ns子阵列的第一个子项的categories项时,这将成功并导致null(var_dump只显示空虚)。
  • 字符串略有不同:'foo'[$n]是获取字符串$n字符的有效遗留语法。当数组索引运算符用于具有非整数索引的字符串时,索引将转换为整数(正如我们所看到的那样,通常会导致零)。因此'Category:...'['title']将生成字符串'C'
    在结构未知或不可靠的数组上使用数组索引语法时,应始终不信任,并使用isset或类似的东西确保您尝试获取的数组字段存在。