php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #46569 SplFileObject: fgetcsv after seek returns wrong line
Submitted: 2008-11-13 21:57 UTC Modified: 2020-11-18 12:46 UTC
Votes:50
Avg. Score:4.2 ± 1.0
Reproduced:46 of 50 (92.0%)
Same Version:5 (10.9%)
Same OS:5 (10.9%)
From: duke at masendav dot com Assigned: cmb (profile)
Status: Duplicate Package: SPL related
PHP Version: 5.2.6 OS: Macos 10.5
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: duke at masendav dot com
New email:
PHP Version: OS:

 

 [2008-11-13 21:57 UTC] duke at masendav dot com
Description:
------------
Using fgetcsv() after seek()-ing to a non-zero position returns the contents of wrong line - off by one.

Note that seek(0) works as expected. Also, using current() instead of fgetcsv() gives the correct line.

Source file (5 lines)
first,line
second,line
third,line
fourth,line
fifth,line



Reproduce code:
---------------
<?php
$file = new SplFileObject('lines.csv');
$file->seek(1);
print_r($file->fgetcsv());



Expected result:
----------------
Array
(
    [0] => second
    [1] => line
)


Actual result:
--------------
Array
(
    [0] => third
    [1] => line
)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-11-14 22:53 UTC] jordan dot raub at dataxltd dot com
I have the same issue w/ 5.2.6 when writing.

<?php
$fobject = new SplFileObject('/tmp/test', 'w');

$fobject->fwrite("111111111111111\n");
$fobject->fwrite("222222222222222\n");
$fobject->fwrite("333333333333333\n");
$fobject->fwrite("444444444444444\n");
$fobject->seek(2);
$fobject->fwrite("555555555555555\n");
$fobject->fwrite("666666666666666\n");
$fobject->fwrite("777777777777777\n");
$fobject->fwrite("888888888888888\n");

foreach(new SplFileObject('/tmp/test', 'r') as $line)
{
	echo $line;
}
?>

Expected result:
----------------
111111111111111
222222222222222
555555555555555
666666666666666
777777777777777
888888888888888


Actual result:
--------------
555555555555555
666666666666666
777777777777777
888888888888888
 [2008-11-15 00:23 UTC] felipe@php.net
It's due the check in spl_filesystem_file_read(): "long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0;"

I don't know the reason of this checking. Etienne?
 [2014-01-12 11:50 UTC] asylow at free dot fr
If think the cases above (not using seek) are related to this bug
PHP 5.4.7

Case 1 is Wrong
-----
$file = new SplFileObject('file.csv', 'r');
echo $file->current();
var_dump($file->fgetcsv());

echo $file->current();
var_dump($file->fgetcsv());
-----
Result :
First array(1) { [0]=> string(6) "Second" }
Second array(1) { [0]=> string(5) "Third" } 


Case 2 is OK
-----
$file = new SplFileObject('file.csv', 'r');
var_dump($file->fgetcsv());
echo $file->current();

var_dump($file->fgetcsv());
echo $file->current();
-----

Result :
array(1) { [0]=> string(5) "First" } First
array(1) { [0]=> string(6) "Second" } Second
 [2017-10-24 07:26 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: colder +Assigned To:
 [2017-10-28 23:48 UTC] sylvain dot witmeyer at gmail dot com
9 years later this bug isn't solved so here is a snippet to achieve the same

function readBigCsv($path, $skip=1)
{
    $file = new \SplFileObject($path, 'r');
    $file->setFlags(\SplFileObject::READ_CSV);
    $file->seek($skip);

    while (!$file->eof()){
        yield $file->current();
        $file->next();
    }

}
 [2018-03-29 23:34 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2018-03-29 23:34 UTC] cmb@php.net
Still unresolved: <https://3v4l.org/3Uh2L>.
 [2019-03-20 09:48 UTC] tomme87 at gmail dot com
Still an issue with PHP 7.3
 [2019-12-12 09:29 UTC] jeremy dot touati at gmail dot com
Note that this doesn't seem related specifically to fgetcsv. 

It's just that SplFileObject::seek appears to set the file pointer position differently between the first line and the other ones.

Example (still valid in PHP 7.4):
https://3v4l.org/O89dJ
 [2020-11-18 12:46 UTC] cmb@php.net
-Status: Verified +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2020-11-18 12:46 UTC] cmb@php.net
Indeed, this is not particularly related to fgetcsv(), but rather
a duplicate of bug #62004.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 19:01:30 2024 UTC