PHP:未定义的索引,即使它存在

时间:2014-03-20 10:19:59

标签: php

它让我发疯...我试图解析一个csv文件并且有一种非常奇怪的行为。

这是csv

action;id;nom;sites;heures;jours
i;;"un nom a la con";1200|128;;1|1|1|1|1|1|1

现在的PHP代码

$required_fields = array('id','nom','sites','heures','jours');
if (($handle = fopen($filename, "r")) !== FALSE)
{
    $cols = 0;
    while (($row = fgetcsv($handle, 1000, ";")) !== FALSE)
    {
        $row = array_map('trim',$row);
        // Identify headers
        if(!isset($headers))
        {
            $cols = count($row);
            for($i=0;$i<$cols;$i++) $headers[strtolower($row[$i])] = $i;
            foreach($required_fields as $val) if(!isset($headers[$val])) break 2;
            $headers = array_flip($headers);
            print_r($headers);
        }
        elseif(count($row) >= 4)
        {
            $temp = array();
            for($i=0;$i<$cols;$i++)
            {
                if(isset($headers[$i]))
                {
                    $temp[$headers[$i]] = $row[$i];
                }
            }
            print_r($temp);
            print_r($temp['action']);
            var_dump(array_key_exists('action',$temp));
            die();
        }
    }
}

输出

Array
(
    [0] => action
    [1] => id
    [2] => nom
    [3] => sites
    [4] => heures
    [5] => jours
)
Array
(
    [action] => i
    [id] => 
    [nom] => un nom a la con
    [sites] => 1200|128
    [heures] => 
    [jours] => 1|1|1|1|1|1|1
)
<b>Notice</b>:  Undefined index: action in <b>index.php</b> on line <b>110</b>
bool(false)

关键字“操作”存在于$ temp $temp['action'] returns Undefinedarray_key_exists returns false中。我尝试过不同的密钥名称,但仍然是一样的。其他键完全没问题。

这有什么问题?

PS:line 110 is the print_r($temp['action']);

编辑1

如果我在每行开头的csv中添加另一个空字段,操作就会正确显示

;action;id;nom;sites;heures;jours
;i;;"un nom a la con";1200|128;;1|1|1|1|1|1|1

6 个答案:

答案 0 :(得分:10)

可能在第一行的开头有一些特殊字符,trim没有删除它。

尝试以这种方式删除每个非单词字符:

// Identify headers
if(!isset($headers))
{
    for($i=0;$i<$cols;$i++)
    {
        $headers[preg_replace("/[^\w\d]/","",strtolower($row[$i]))] = $i;
....

答案 1 :(得分:0)

对不起,我发帖在一个旧帖子上,但我想我的答案可能会添加到这里已提供的答案......

我正在使用来自Windows 10主机的Vagrant来宾VM(Ubuntu 16.04)。当我第一次遇到这个错误时(在我的情况下,使用Laravel和csv文件播种数据库表),@ ojovirtual的答案立即有意义,因为Windows和Linux之间可能存在格式化问题。

@ ojovirtual的答案对我来说不太有用,所以我最后通过Bash做touch new_csv_file.csv,并将'有问题'的CSV文件(最初在我的Windows 10主机上创建)中的内容粘贴到此新创建的。这肯定解决了我的问题 - 学习和调试更好,但我只想完成我的特定任务。

答案 2 :(得分:0)

我在这个问题上苦苦挣扎了几个小时,才意识到这个问题是由数组中的空键引起的。请确保所有键都不为空值。

答案 3 :(得分:0)

如果您的CSV文件采用UTF-8编码,

确保它是UTF-8,而不是UTF-8-BOM

(您可以在Notepad ++的“编码”菜单中进行检查)

答案 4 :(得分:0)

我对使用UTF-8编码的MS Excel中生成的CSV文件存在相同的问题。将以下代码添加到您读取CSV的位置即可解决此问题:

$handle = fopen($file, 'r');

// ...

$bom = pack('CCC', 0xef, 0xbb, 0xbf);

if (0 !== strcmp(fread($handle, 3), $bom)) {
    fseek($handle, 0);
}
// ...

它的作用是检查是否存在UTF-8 byte order mark。如果有一个,我们将指针移到BOM上方。这不是通用解决方案,因为还有其他类型的BOM,但是您可以根据需要进行调整。

答案 5 :(得分:0)

我一直在努力解决这个问题,直到我意识到我的代码块已运行两次。

第一次运行时存在索引并且正确打印了我的数组,第二次运行时不存在索引并且触发了通知错误。这让我感到奇怪:“为什么我明显存在且正确打印的数组会触发“未定义索引”通知”。 :)

也许这会对某人有所帮助。