5

The problem I'm facing is that I have a SplFileObject that reads a CSV file, then I wrap it into a LimitIterator.

The CSV file has 2 rows, header, and 1 row, I set the LimitIterator offset to 1 and I can't reach over it, seems some internal problems with the indexing.

here is the code:

    $csvFile = new \SplFileObject($fileName);
    $csvFile->setFlags(\SplFileObject::READ_CSV);
    $iterator = new \LimitIterator($csvFile, 1);

    /** @var \LimitIterator $it */
    foreach ($iterator as $it) {

        list($.., $.., $..) = $it;
        $result[] = [
            ...
        ];
    }


    return $result;

The code works well if the CSV has 3 lines (header and 2 rows), but only with header and 1 row, it doesn't work.

Any Idea?

Thanks.

Aram Grigoryan
  • 740
  • 1
  • 6
  • 24
redigaffi
  • 429
  • 6
  • 22

2 Answers2

1

This is related to PHP bug 65601, which suggests adding the READ_AHEAD flag will fix this. Tested and works as you expected it to.

    $csvFile->setFlags(\SplFileObject::READ_CSV | \SplFileObject::READ_AHEAD);

See also SplFileObject + LimitIterator + offset

gaddman
  • 59
  • 7
0

Personally, I would use the fopen and fgetcsv functions for this as below;

<?php
$handle = fopen("myFile.csv", "r");

if ($handle != false)
{
    $header_row_handled = false;
    while ($datarow = fgetcsv($handle, 0, ",")
    {
        if (!$header_row_handled)
        {
            $header_row_handled = true;
        }
        else
        {
            /* Whatever you need */
            $dataparta = $datarow[0];
            $datapartb = $datarow[1];
            $datapartc = $datarow[2];
        }
    }
}

Looping means you can just skip the first row each time and perhaps use less resource for this as you don't have as many objects floating around

The php.net page should help you out too

Can O' Spam
  • 2,718
  • 4
  • 19
  • 45
  • I suppose question is not how to loop over dataset. But why certain selected approach does not work. – u_mulder Jun 27 '18 at 11:33
  • @u_mulder - well, yes, this is purely an alternative method to achieve the same result – Can O' Spam Jun 27 '18 at 11:34
  • That was the approach we were using before, but I was refactoring this to some more modern approach, so I could have something really easy, readable and removing the conditional inside the loop. – redigaffi Jun 27 '18 at 11:34
  • @redigaffi - sometimes, reinventing the wheel isn't the best thing to do, simplicity is great at times, IMO it boils sown to "why fix what isn't broken" :) – Can O' Spam Jun 27 '18 at 11:36
  • Yes I know that, but I always try to improve all. And removing these conditionals means simpler and easier code. (And less cyclomatic complexity too). But thanks for the help. – redigaffi Jun 27 '18 at 11:40