在PHP manual中,SplFileObject
有两种看似非常相似的方法:
$file->fgets()
从文件中获取一行。
$file->current()
检索文件的当前行。
有关程序fgets
的文档更接近current()
:
从文件指针获取行。
但是没有人注意到一个是另一个的别名。两者都没有参数。这些有什么区别?
答案 0 :(得分:2)
一个区别是current
可以作为fgetcsv
或fgets
depending on whether the SplFileObject::READ_CSV
flag is set。根据该标志,底层实现几乎相同(不移动指针,请参阅其他答案)。
这意味着current
可以返回字符串或数组,具体取决于标志的存在。
据推测,这是为了代码可移植性而做的,尽管似乎代码比fgetcsv
更多来完成同样的工作,并且由于额外的逻辑调用,可能性能稍差(参见Axalix' s)回答)。
答案 1 :(得分:2)
重要的真正区别是,例如我们有这个文件
foo
bar
以下功能将打印foo bar
$file = new \SplFileObject("test.txt");
while (!$file->eof()) {
echo $file->fgets();
}
但此功能会连续打印foo
$file = new \SplFileObject("test.txt");
while (!$file->eof()) {
echo $file->current();
}
因为fgets
从begin开始并读取作为第一行的下一行,然后它读取下一行是秒行并停止,因为它找到了文件末尾但current
总是读取当前行并且永远不会进入下一行,因此它永远不会中断循环,您需要使用next
函数来读取下一行,因此第一个代码与以下代码相同:
$file = new \SplFileObject("test.txt");
while (!$file->eof()) {
echo $file->current();
$file->next();
}
答案 2 :(得分:1)
实施方面存在一些差异。似乎fgets
更短,只做了从文件中读取行
https://github.com/php/php-src/blob/4d9a1883aa764e502990488d2e8b9c978be6fbd2/ext/spl/spl_directory.c
/* {{{ proto string SplFileObject::current()
Return current line from file */
SPL_METHOD(SplFileObject, current)
{
spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if(!intern->u.file.stream) {
zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized");
return;
}
if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) {
spl_filesystem_file_read_line(getThis(), intern, 1);
}
if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || Z_ISUNDEF(intern->u.file.current_zval))) {
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
} else if (!Z_ISUNDEF(intern->u.file.current_zval)) {
RETURN_ZVAL(&intern->u.file.current_zval, 1, 0);
}
RETURN_FALSE;
} /* }}} */
VS
/* {{{ proto string SplFileObject::fgets()
Rturn next line from file */
SPL_METHOD(SplFileObject, fgets)
{
spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis());
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if(!intern->u.file.stream) {
zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized");
return;
}
if (spl_filesystem_file_read(intern, 0) == FAILURE) {
RETURN_FALSE;
}
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
} /* }}} */
修改强>
所以区别在于回报。 current
(如果设置了某些标志)可能会返回RETURN_ZVAL(此情况下为php数组)或字符串OR。 fgets
返回字符串或FALSE。如果我们只是想从文件中读取一行而没有做任何其他工作,那么if (spl_filesystem_file_read(intern, 0) == FAILURE) {
也比其他任何东西都快。