Skip to content

Commit ca6af4a

Browse files
committed
Refine fgets() to reuse cached line when present
When current() reads a line into the cache without advancing line_num, a subsequent fgets() would re-read the stream and return the next line, skipping the cached one and leaving key() out of sync with current() for the rest of the iteration. Use the cached line if present; otherwise read a fresh line. Either way, advance line_num by one.
1 parent 0353557 commit ca6af4a

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

ext/spl/spl_directory.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,11 +2096,17 @@ PHP_METHOD(SplFileObject, fgets)
20962096

20972097
CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
20982098

2099-
if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) {
2100-
RETURN_THROWS();
2099+
if (intern->u.file.current_line) {
2100+
RETVAL_STR_COPY(intern->u.file.current_line);
2101+
spl_filesystem_file_free_line(intern);
2102+
intern->u.file.current_line_num++;
2103+
} else {
2104+
if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) {
2105+
RETURN_THROWS();
2106+
}
2107+
RETVAL_STR_COPY(intern->u.file.current_line);
2108+
spl_filesystem_file_free_line(intern);
21012109
}
2102-
RETVAL_STR_COPY(intern->u.file.current_line);
2103-
spl_filesystem_file_free_line(intern);
21042110
} /* }}} */
21052111

21062112
/* {{{ Return current line from file */

ext/spl/tests/SplFileObject/gh8561.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ echo "After current+fgets: key=" . $file->key() . " current=" . trim($file->curr
2727
--EXPECT--
2828
After rewind+fgets: key=1 current=line 1
2929
After rewind+fgets+fgets: key=2 current=line 2
30-
After current+fgets: key=1 current=line 2
30+
After current+fgets: key=1 current=line 1

0 commit comments

Comments
 (0)