在使用 str_getcsv() 创建的数组上获取“未定义索引”;但 var_dump() 显示键存在

Getting "Undefined Index" on array created with str_getcsv(); but var_dump() shows key exists

提问人:Stefan Dunn 提问时间:2/19/2019 最后编辑:yiviStefan Dunn 更新时间:2/20/2019 访问量:610

问:

我使用以下方法创建了一个数组:str_getcsv()

$array = array_map('str_getcsv', file($file['tmp_name']));
array_walk($array, function(&$a) use ($array) {
    $a = array_combine($array[0], $a);
});
array_shift($array);

返回的输出为 。$arrayvar_dump($array)

array(18) {
  ["fund"]=>
  string(6) "Fund 1"
  ["name"]=>
  string(13) "Property Name"
  ["investment"]=>
  string(13) "Investment Name"
  ["region"]=>
  string(6) "London"
  ["sector"]=>
  string(6) "Office"
  ["status"]=>
  string(8) "Published"
  ["description"]=>
  string(0) ""
  ["acquisition_date"]=>
  string(0) ""
  ["size"]=>
  string(0) ""
  ["address_line_1"]=>
  string(0) ""
  ["address_line_2"]=>
  string(0) ""
  ["city"]=>
  string(6) "London"
  ["county"]=>
  string(0) ""
  ["postcode"]=>
  string(0) ""
  ["longitude"]=>
  string(0) ""
  ["latitude"]=>
  string(0) ""
  ["featured"]=>
  string(0) ""
  ["external_link"]=>
  string(0) ""
}

当我尝试访问时,我得到.我的第一个想法是 CSV 标头的键名称中有一个隐藏字符,因为有效,但我已经检查过,唯一隐藏的字符是 .$array['fund'];Notice: Undefined index: fundfund$array['name']CRLF

我在 StackOverflow 上看到过多维数组的类似问题,但单维数组没有。

任何帮助将不胜感激。我什至尝试转换为 StdClass,并收到关于属性不存在的类似错误。$array->fund

我尝试将第一个标题列名称重命名为任何名称,但它仍然有问题,所以我想知道访问第一个键是否有问题。

php 数组 undefined-index

评论

1赞 M. Eriksson 2/19/2019
do: before 并检查它是否适用于新数组。它应该删除任何不可见的空白(包括 CR LF)$new = []; foreach ($array as $k => $v) { $new[trim($k)] = $v; }
0赞 Stefan Dunn 2/19/2019
我试过了,但没有用。但是,我只是在Excel中打开了CSV文件,然后使用菜单中的选项而不是选项重新保存,并且它起作用了。我会尝试为遇到这种情况的其他人更新答案。Comma Separated Vales (.csv)CSV UTF-8 (Comma Delimited) (.csv)file > save as
0赞 Nigel Ren 2/19/2019
您的文件中可能有一个 BOM - 阅读 stackoverflow.com/questions/45240387/...
0赞 yivi 2/19/2019
你需要添加你实际使用的代码,以及有问题的输入文件,至少是那一行。否则,我们只能猜测。

答:

2赞 yivi 2/19/2019 #1

顶级域名;

您正在尝试在应该访问 时进行访问。您将其视为一维数组,但它是一个多维数组(维度 1,索引;维度 2,关联)。$array['fund']$array[0]['fund']


解释:

您没有显示您尝试访问的特定代码,也没有显示您的特定输入,但问题似乎是您误解了用于解析 CSV 的代码的结果数组的结构。$array['fund']

array_map() + array_walk() + array_combine() + array_shift()似乎是一种有点令人困惑的方式来获得你想要的东西,结果正在显示。这是“聪明”代码提高生产力的一个明显例子。双衬里阵列结构比某些替代方案更难解析。

我将假设此输入,因为您没有提供任何输入,并且读取外部文件超出了此问题的范围(本身并不是真正的问题):

// input

$lines = <<<EOF
fund,name,investment,region,sector,status,description,acquisition_date,size,address_line_1,address_line_2,city,county,postcode,longitude,latitude,featured,external_link
"Fund 1","Property Name","Investment Name","London","Office","Published","","","","","","London","","","","","",""
EOF;

这与您在问题中显示的数组匹配。

让我们试着剖析一下接下来的代码:

$array = array_map('str_getcsv', explode(PHP_EOL, $lines));

这留下了一个由两个元素组成的数组。在索引 0 处,您有标头,在索引 1 处,您有值。

array_walk($array, function(&$a) use ($array) {
    $a = array_combine($array[0], $a);
});

在这里,您将遍历这两个数组中的每一个,每个数组的索引处都有 0 的数组。您可以创建数组,其中键是包含标头 () 的数组中的值。array_combine()$array[0]

注意:这应该可以清楚地表明$array在索引数组中,因为您已经在尝试访问位置 0 处的元素。

显然,你最终会得到一个额外的数组(header array 与 header array 组合),但你稍后会处理它。

array_shift($array);

在这里,您摆脱了标头数组(值为 )。删除两个元素数组的第一个元素。同样,此操作仅在开始时是索引数组时才有意义。$element['fund'] = 'fund'$array

此时,您有一个元素的数组,该元素是一个具有 18 个 keys=>values 的数组。

如果在这一点上你试图访问它,它自然会失败。因为是索引数组,而不是关联数组$array['fund']$array

您需要访问此索引数组的元素,然后尝试访问 .fund

例如:$array[$i]['fund'];

你可以在这里看到它的工作。

评论

0赞 Stefan Dunn 2/20/2019
那么,如果你建议它显示多维数组(而是一个 assoc 数组),为什么不显示它呢?var_dump($array)
0赞 yivi 2/20/2019
Stefan,我看不到您在生成数组后使用的代码,也看不到您正在使用的输入。但是,如果你去看我链接的示例,你会清楚地看到,该特定循环的结果是一个包含 N 个关联数组的索引数组。
0赞 yivi 2/20/2019
@Stefan,我在这里所做的唯一更改是从多行字符串而不是多行文件中读取。您必须同意没有实际区别。结果显然是一个 N 维数组(这是有道理的,因为这将允许您处理具有 2 条以上记录的 CSV;我收集的是目标)。
0赞 yivi 2/20/2019
为了更明显,在您自己的代码的循环中,您正在访问 .因此,在您自己的代码中,您知道它是索引的,而不是关联的。$array[0]$array
0赞 yivi 2/20/2019
@StefanDunn 现在明白了吗?我进一步编辑了我的答案,使其更加清晰。