Home » Php » PHP: Undefined index even if it exists

PHP: Undefined index even if it exists

Posted by: admin July 12, 2020 Leave a comment

Questions:

It drives me crazy … I try to parse a csv file and there is a very strange behavior.

Here is the csv

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

Now the php code

$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();
        }
    }
}

And the output

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)

The key “action” exists in $temp but $temp['action'] returns Undefined and array_key_exists returns false. I’ve tried with a different key name, but still the same. And absolutely no problem with the others keys.

What’s wrong with this ?

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

EDIT 1

If i add another empty field in the csv at the begining of each line, action display correctly

;action;id;nom;sites;heures;jours
;i;;"un nom a la con";1200|128;;1|1|1|1|1|1|1
How to&Answers:

Probably there is some special character at the beginning of the first line and trim isn’t removing it.

Try to remove every non-word character this way:

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

Answer:

Sorry I am posting on an old thread, but thought my answer could add to ones already provided here…

I’m working with a Vagrant guest VM (Ubuntu 16.04) from a Windows 10 host. When I first came across this bug (in my case, seeding a database table using Laravel and a csv file), @ojovirtual’s answer immediately made sense, since there can be formatting issues between Windows and Linux.

@ojovirtual’s answer didn’t quite work for me, so I ended up doing touch new_csv_file.csv through Bash, and pasting contents from the ‘problematic’ CSV file (which was originally created on my Windows 10 host) into this newly-created one. This definitely fixed my issues – it would have been good to learn and debug some more, but I just wanted to get my particular task completed.

Answer:

If your CSV file is in UTF-8 encoding,

make sure that it’s UTF-8 and not UTF-8-BOM.

(you can check that in Notepad++, Encoding menu)

Answer:

I struggled with this issue for a few hours only to realize that the issue was being caused by a null key in the array. Please ensure that none of the keys has a null value.

Answer:

I had the same problem with CSV files generated in MS Excel using UTF-8 encoding. Adding the following code to where you read the CSV solves the issue:

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

// ...

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

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

What it does, is checking for the presence of UTF-8 byte order mark. If there is one, we move the pointer past BOM. This is not a generic solution since there are other types BOMs, but you can adjust it as needed.