Search code examples
phpmysqlcodeigniter-4

Undefined array key just for first key in array, every other key works fine. Codeigniter 4


So i am trying to import data from csv file to the database. Everything except first key in array works fine. All the rest data is inserted in db.

    $boltReport    = array();
    $count = 0;
    foreach($rows as $row) {
        if(!empty($row)){
            $boltReport[] = array_combine($header_row, $row);
        }
    }
    $boltReportTrimed = array();
    foreach($boltReport as $driver){
        if (!empty($driver['Telefonski_broj_vozaca'])){
            if($driver['Period'] != 'Period'){
                if(!empty($driver['Utilization'])){
                    $driver['report_for_week']= $week;
                    $boltReportTrimed[] = $driver;
                    $count++;
                    
                }
            }
        }
        
    }
    $driverData = new BoltReportModel();
    $findRecord = $driverData->where('report_for_week', $week)->countAllResults();

    $count1 = 0;
    foreach($boltReportTrimed as $driver){
            if($findRecord == 0){
                                
                if($driverData->insert($driver)){
                    $count1++;}
                }
            }

Here i am doing some filtering and using model to insert data in database. All the data except first item in array $boltReportTrimed is inserted in database.

So to debug i was using print_r and echo to check what data i have.

Here is the code

foreach($boltReportTrimed as $driver){
    if($findRecord == 0){
        echo '<pre>';
        print_r($driver);
        echo '</pre>';
        die();

        if($driverData->insert($driver)){
            $count1++;}
        }

With this code i get response like this:

Array
(
    [Vozac] => Ante Antunović
    [Telefonski_broj_vozaca] => +385958759630
    [Period] => Tjedan 2023-01-09 - 2023-01-15
    [Bruto_iznos] => 0.00
    [Otkazna_naknada] => 0.00
    [Naknada_za_rezervaciju_(placanje)] => 0.00
    [Naknada_za_rezervaciju_(odbitak)] => 0.00
    [Naknada_za_cestarinu] => 0.00
    [Bolt_naknada] => 0.00
    [Voznje_placene_gotovinom_(prikupljena_gotovina)] => 0.00
    [Popusti_na_voznje_na_gotovinu_od_Bolt_] => 0.00
    [Bonus] => 0.00
    [Nadoknade] => 
    [Povrati_novca] => 0.00
    [Napojnica] => 0.00
    [Tjedno_stanje_racuna] => 0.00
    [Sati_na_mrezi] => 0.20
    [Utilization] => 0.00
    [report_for_week] => 02
)

I know it's almost all 0 but data is correct. First array item does not get inserted in database so i was trying to echo first item with this code:

foreach($boltReportTrimed as $driver){
    if($findRecord == 0){
        echo '<pre>';
        print_r($driver);
        echo $driver['Vozac'];
        echo '</pre>';
        die();
        
        if($driverData->insert($driver)){
            $count1++;}
        }

Here is one more thing i was trying:

                foreach($boltReportTrimed as $driver){
                        if($findRecord == 0){
                                            echo '<pre>';
                                            print_r($driver);
                                            //echo $driver['Vozac'];
                                            echo '</pre>';
                            $firstKey = array_key_first($driver);

                            var_dump($firstKey);                
                            
                            die();

And result is:

Array
(
    [Vozac] => Ante Antunović
    [Telefonski_broj_vozaca] => +385958733630
    [Period] => Tjedan 2023-01-09 - 2023-01-15
    [Bruto_iznos] => 0.00
    [Otkazna_naknada] => 0.00
    [Naknada_za_rezervaciju_(placanje)] => 0.00
    [Naknada_za_rezervaciju_(odbitak)] => 0.00
    [Naknada_za_cestarinu] => 0.00
    [Bolt_naknada] => 0.00
    [Voznje_placene_gotovinom_(prikupljena_gotovina)] => 0.00
    [Popusti_na_voznje_na_gotovinu_od_Bolt_] => 0.00
    [Bonus] => 0.00
    [Nadoknade] => 
    [Povrati_novca] => 0.00
    [Napojnica] => 0.00
    [Tjedno_stanje_racuna] => 0.00
    [Sati_na_mrezi] => 0.20
    [Utilization] => 0.00
    [report_for_week] => 02
)
string(8) "Vozac"

Now i got this error from the title:

ErrorException Undefined array key "Vozac"

echoing any other key works fine and i get expected results Help me please.

By @nnichols suggestion i try this:

print_r(array_map('dechex', array_map('mb_ord', mb_str_split('Vozac'))));
print_r(array_map('dechex', array_map('mb_ord', mb_str_split($firstKey))));

And result is :

Array
(
    [0] => 56
    [1] => 6f
    [2] => 7a
    [3] => 61
    [4] => 63
)
Array
(
    [0] => feff
    [1] => 56
    [2] => 6f
    [3] => 7a
    [4] => 61
    [5] => 63
)

Any further help or suggestions are welcome because i have no idea what this means. Thank you in advance


Solution

  • It looks like an encoding issue. string(8) "Vozac" when string(5) "Vozac" expected?

    var_dump(
        array_map('dechex', array_map('mb_ord', mb_str_split('Vozac'))),
        array_map('dechex', array_map('mb_ord', mb_str_split($firstKey)))
    )
    

    As per your comment, the additional invisible character at the beginning of $firstKey is the byte order mark (BOM) and because you array_combine($header_row, $row) foreach $row you are seeing this issue throughout the $boltReportTrimed array.

    If you change the initial code which is opening the file and reading the lines of the csv then you won't have strange little hacks throughout your code.

    function importCSV(string $file, bool $firstRowHeaders = false) {
    
        if (($fp = fopen($file, 'r')) !== false) {
    
            // Skip BOM if present, otherwise rewind to start of file
            if (fgets($fp, 4) !== "\xef\xbb\xbf") {
                rewind($fp);
            }
    
            // Read CSV into an array.
            $lines = array();
            $rows = 0;
    
            while(($line = fgetcsv($fp)) !== false) {
                if ($firstRowHeaders === true && $rows === 0) {
                    $lines['headers'] = $line;
                } else {
                    $lines['rows'][] = $line;
                }
                $rows++;
            }
    
            fclose($fp);
    
            return $lines;
        }
    }