在'r'模式下使用PHP的SplFileObject时,$ file-> eof()始终返回false [英] $file->eof() always returning false when using PHP's SplFileObject in 'r' mode

查看:135
本文介绍了在'r'模式下使用PHP的SplFileObject时,$ file-> eof()始终返回false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我的PHP脚本挂起了?

Why is my PHP script hanging?

$path = tempnam(sys_get_temp_dir(), '').'.txt';
$fileInfo = new \SplFileInfo($path);
$fileObject = $fileInfo->openFile('a');
$fileObject->fwrite("test line\n");
$fileObject2 = $fileInfo->openFile('r');
var_dump(file_exists($path));          // bool(true)
var_dump(file_get_contents($path));    // string(10) "test line
                                       // "
var_dump(iterator_count($fileObject2)); // Hangs on this

如果我删除最后一行( iterator_count(。 .. )并替换为:

If I delete the last line (iterator_count(...) and replace it with this:

$i = 0;
$fileObject2->rewind();
while (!$fileObject2->eof()) {
    var_dump($fileObject2->eof());
    var_dump($i++);
    $fileObject2->next();
}

// Output:
// bool(false)
// int(0)
// bool(false)
// int(1)
// bool(false)
// int(2)
// bool(false)
// int(3)
// bool(false)
// int(4)
// ...

$ fileObject-> eof()总是返回false,所以我得到一个无限循环

The $fileObject->eof() always returns false so I get an infinite loop.

为什么会发生这些事情?我需要获取行数。

Why are these things happening? I need to get a line count.

推荐答案

为什么会发生这些事情?

您正在体验 SplFileObject的特殊性类被编写,而没有调用 next() current()方法-使用默认值( 0 )标志-迭代器永远不会向前移动。

You are experiencing a peculiarity in the way that the SplFileObject class is written. Without calling next() and current() methods—using the default (0) flags—the iterator never moves forward.

iterator_count()函数从不调用 current();它仅检查 valid()并调用 next()。您的定制循环仅调用 current() next()中的一个或另一个。

The iterator_count() function never calls current(); it checks valid() and calls next() only. Your bespoke loops only call one or other of current() and next().

应将其视为错误(无论是PHP本身还是文档失败),并且以下代码应该(并且不能)按预期工作。我邀请您报告此不当行为

This should be considered a bug (whether in PHP itself, or a failure in the documentation) and the following code should (and does not) work as expected. I invite you to report this misbehaviour.

// NOTE: This currently runs in an infinite loop!
$file = new SplFileObject(__FILE__);
var_dump(iterator_count($file));

解决方法

让事情前进的一个捷径是在对象上设置 READ_AHEAD 标志。这将导致 next()方法读取下一条可用行。

One quick sidestep to get things moving is to set the READ_AHEAD flag on the object. This will cause the next() method to read the next available line.

$file->setFlags(SplFileObject::READ_AHEAD);

如果出于任何原因您不希望提前阅读行为那么您必须自己调用 next() current()

If, for any reason, you do not want the read ahead behaviour then you must call both next() and current() yourself.

回到两个SplFileObjects的原始问题

以下内容现在应该可以正常工作,允许附加到文件和

The following should now work as you expected, allowing appending to a file and reading its line count.

<?php
$info = new SplFileInfo(__FILE__);
$write = $info->openFile('a');
$write->fwrite("// new line\n");
$read = $info->openFile('r');
$read->setFlags(SplFileObject::READ_AHEAD);
var_dump(iterator_count($read));

这篇关于在'r'模式下使用PHP的SplFileObject时,$ file-&gt; eof()始终返回false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆