fgets和current之间的区别是什么?

时间:2015-05-17 17:23:09

标签: php

PHP manual中,SplFileObject有两种看似非常相似的方法:

$file->fgets()

  

从文件中获取一行。

$file->current()

  

检索文件的当前行。

有关程序fgets的文档更接近current()

  

从文件指针获取行。

但是没有人注意到一个是另一个的别名。两者都没有参数。这些有什么区别?

3 个答案:

答案 0 :(得分:2)

一个区别是current可以作为fgetcsvfgets 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();
}

修改:还要检查Josiah有关与旗帜和Axalix的差异的答案,以查看源代码差异

答案 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) {也比其他任何东西都快。