2015-05-17 66 views
2

PHP manual,在SplFileObject有兩種方法似乎很相似:fgets和當前有什麼區別?

$file->fgets()

從文件一行。

$file->current()

檢索該文件的當前行。

對文檔的程序fgets,更接近current()

從文件指針線。

但是沒有關於其中一個別名的註釋。兩者都沒有參數。這些有何區別?

+0

如果你downvote,請讓我知道爲什麼這樣我就可以改善這個問題。謝謝! – Josiah

+0

我不知道人們爲什麼低估它,但我也想知道這些方法之間的根本區別。他們看起來模棱兩可,差別很小。 – Axalix

+2

似乎唯一的區別是當前READ_CSV的事情,但你可能也看到了這一點。這是一個很好的問題。 – rjdown

回答

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開始開始,讀出下一行是第一行,然後它讀取下一行,這是秒行,並停止,因爲它發現文件的結尾,但current總是讀取當前行,從來就沒有到下一行,所以它永遠不會打破循環,你需要使用next函數讀取下一行,所以第一個代碼是等效採用:

$file = new \SplFileObject("test.txt"); 
while (!$file->eof()) { 
    echo $file->current(); 
    $file->next(); 
} 

編輯:還要檢查Josiah回答有關與國旗和Axalix的差異看源代碼diffrence

+0

因此'當前'不會移動指針?有趣。這對於什麼有用? – Josiah

+0

嗯,也許是因爲你想讀取該行並檢查其值之前繼續到下一行 – Almis

+0

我認爲@Almis是正確的。看看src中方法的註釋。碼。 '從文件中返回當前行並從文件中返回下一行' – Axalix

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) {如果我們只是想從文件中讀取一行而不做任何其他工作,那麼它比其他任何東西都快。

+3

請解釋一下代碼,不只是複製粘貼 – Almis

+1

我看到'RETURN_STRINGL(intern-> u.file.current_line,intern-> u.file.current_line_len);'兩個。這是什麼'如果{ spl_filesystem_file_read_line(獲得OS 3.0(),實習生,1)(intern-> u.file.current_line && Z_ISUNDEF(intern-> u.file.current_zval)!); }'做? – Josiah

+0

謝謝。我認爲編輯回答了我的問題。我會等幾分鐘,看看有沒有更多的信息。你能想到一個情況,你會選擇'current()'而不是其中的一個?這似乎有點毫無意義。 – Josiah

2

一個區別是current可以作爲fgetcsvfgetsdepending on whether the SplFileObject::READ_CSV flag is set。根據該標誌,底層實現幾乎相同(不移動指針,查看其他答案)。

這意味着current可以返回一個字符串或一個數組,取決於標誌的存在。

大概這是爲代碼可移植性完成的,儘管看起來它會比完成相同工作的代碼多於fgetcsv,並且由於額外的邏輯調用(請參閱Axalix的答案)可能性能稍差。