<?php// Create an iterator to be limited $fruits = new ArrayIterator(array( 'apple', 'banana', 'cherry', 'damson', 'elderberry' ));// Loop over first three fruits only foreach (new LimitIterator($fruits, 0, 3) as $fruit) { var_dump($fruit); }
echo
"\n";// Loop from third fruit until the end // Note: offset starts from zero for apple foreach (new LimitIterator($fruits, 2) as $fruit) { var_dump($fruit); }?>
string(5) "apple"
string(6) "banana"
string(6) "cherry"
string(6) "cherry"
string(6) "damson"
string(10) "elderberry"
<?php// Create an iterator to be limited $fruits = new ArrayIterator(array( 'apple', 'banana', 'cherry', 'damson', 'elderberry' ));// Loop over first three fruits only foreach (new LimitIterator($fruits, 0, 3) as $fruit) { var_dump($fruit); }
echo
"\n";// Loop from third fruit until the end // Note: offset starts from zero for apple foreach (new LimitIterator($fruits, 2) as $fruit) { var_dump($fruit); }?>
string(5) "apple"
string(6) "banana"
string(6) "cherry"
string(6) "cherry"
string(6) "damson"
string(10) "elderberry"
I have data file with two lines (two lines just for my example, in real, that file can contain millions of lines) and I use SplFileObject and LimitIterator with offseting. But this combination have strange behaviour in some cases: $offset = 0;
$file = new \SplFileObject($filePath);
$fileIterator = new \LimitIterator($file, $offset, 100);
foreach ($fileIterator as $key => $line) {
echo $key;
}
Output is: 01 But with $offset set
to 1, output is blank (foreach doesn't iterate any line). My data file contain this: {"generatedAt":1434665322,"numRecords":"1}
{"id":"215255","code":"NB000110"}
What I'm doing wrong? Thanks asked Jun 19, 2015 at 7:37 4 Required: Use SplFileObject to process a number of records from: - a given start record
number
- for a given number of records or until
EOF .
The issue is that SplFileObject gets confused as regards the last record in the file. This prevents it working correctly in foreach loops. This code uses the SplFileObject and 'skip records' and 'processes records'. Alas, It cannot use foreach loops. - Skip a number of records from the start of the file (
$offset ). - Process a given number of records or unit the end of file (
$recordsToProccess )
The code:
<?php
$filePath = __DIR__ . '/Q30932555.txt';
// $filePath = __DIR__ . '/Q30932555_1.txt';
$offset = 1;
$recordsToProcess = 100;
$file = new \SplFileObject($filePath);
// skip the records
$file->seek($offset);
$recordsProcessed = 0;
while ( ($file->valid() || strlen($file->current()) > 0)
&& $recordsProcessed < $recordsToProcess
) {
$recordsProcessed++;
echo '<br />', 'current: ', $file->key(), ' ', $file->current();
$file->next();
}
answered Jun 19, 2015 at 10:38 Ryan
VincentRyan Vincent 4,4587 gold badges21 silver badges31 bronze badges 6 Reading the related PHP bug 65601 suggests adding the READ_AHEAD flag will fix this. Tested and works as you expected it to. $offset = 0;
$file = new \SplFileObject($filePath);
$file->setFlags(SplFileObject::READ_AHEAD);
$fileIterator = new \LimitIterator($file, $offset, 100);
foreach ($fileIterator as $key => $line) {
echo $key;
}
answered Feb 1, 2021 at 3:12 |