Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
$file->;eof()在使用PHP';在';r';模式_Php_Fwrite_Eof_Splfileobject - Fatal编程技术网

$file->;eof()在使用PHP';在';r';模式

$file->;eof()在使用PHP';在';r';模式,php,fwrite,eof,splfileobject,Php,Fwrite,Eof,Splfileobject,为什么我的PHP脚本挂起了 $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($pat

为什么我的PHP脚本挂起了

$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
如果删除最后一行(
迭代器计数(…
),并将其替换为以下内容:

$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,因此我得到一个无限循环


为什么会发生这些事情?我需要得到一个行数。

虽然在PHP5.3.9中,这看起来有点违反直觉,但是:

<?php
$f = new SplFileObject('test.txt', 'r');
while (!$f->eof()) {
    $f->next();
}
<?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));
应改写为:

$fileObject2->rewind();
while (!$fileObject2->eof()) {
    $fileObject2->current();
}

$i = $fileObject2->key();

在PHP 5.3.9中,这似乎与直觉相反,但它:

<?php
$f = new SplFileObject('test.txt', 'r');
while (!$f->eof()) {
    $f->next();
}
应改写为:

$fileObject2->rewind();
while (!$fileObject2->eof()) {
    $fileObject2->current();
}

$i = $fileObject2->key();
编辑01 如果您需要的是文件中的行数:

<?php

$path = tempnam(sys_get_temp_dir(), '').'.txt';

$fileInfo = new SplFileInfo($path);
$fileObject = $fileInfo->openFile('a+');

$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar".PHP_EOL);

echo count(file($path));  // outputs 2

?>



编辑02 这是上面的代码,但由于文件指针的原因,不会进入无限循环:

<?php

$path = tempnam(sys_get_temp_dir(), '').'.txt';

$fileInfo = new SplFileInfo($path);
$fileObject = $fileInfo->openFile('a+');

$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar");

foreach($fileObject as $line_num => $line) {
    echo 'Line: '.$line_num.' "'.$line.'"'."<br/>";
}
echo 'Total Lines:' . $fileObject->key();

?>

输出

行:0“Foo”

行:1“巴”

总行数:2



原始答案 应用的逻辑有点不正确。我简化了代码:

<?php

// set path to tmp with random file name
echo $path = tempnam(sys_get_temp_dir(), '').'.txt';
echo "<br/>";

// new object
$fileInfo = new \SplFileInfo($path);

// open to write
$fileObject = $fileInfo->openFile('a');

// write two lines
$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar".PHP_EOL);

// open to read
$fileObject2 = $fileInfo->openFile('r');

// output contents
echo "File Exists: " .file_exists($path);
echo "<br/>";
echo "File Contents: " . file_get_contents($path);
echo "<br/>";

// foreach line get line number and line contents 
foreach($fileObject2 as $line_num => $line) {
  echo 'Line: '.$line_num;
  echo ' With: "'.$line.'" is the end? '.($fileObject2->eof()?'yes':'no')."<br>";
}

?>

输出:

/tmp/EAdklY.txt

文件存在:1

文件内容:foobar

行:0,结尾是“Foo”吗?否

行:1加上:“Bar”是结尾吗?否

行:2,带:“”是结尾吗?是

编辑01 如果您需要的是文件中的行数:

<?php

$path = tempnam(sys_get_temp_dir(), '').'.txt';

$fileInfo = new SplFileInfo($path);
$fileObject = $fileInfo->openFile('a+');

$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar".PHP_EOL);

echo count(file($path));  // outputs 2

?>



编辑02 这是上面的代码,但由于文件指针的原因,不会进入无限循环:

<?php

$path = tempnam(sys_get_temp_dir(), '').'.txt';

$fileInfo = new SplFileInfo($path);
$fileObject = $fileInfo->openFile('a+');

$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar");

foreach($fileObject as $line_num => $line) {
    echo 'Line: '.$line_num.' "'.$line.'"'."<br/>";
}
echo 'Total Lines:' . $fileObject->key();

?>

输出

行:0“Foo”

行:1“巴”

总行数:2



原始答案 应用的逻辑有点不正确。我简化了代码:

<?php

// set path to tmp with random file name
echo $path = tempnam(sys_get_temp_dir(), '').'.txt';
echo "<br/>";

// new object
$fileInfo = new \SplFileInfo($path);

// open to write
$fileObject = $fileInfo->openFile('a');

// write two lines
$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar".PHP_EOL);

// open to read
$fileObject2 = $fileInfo->openFile('r');

// output contents
echo "File Exists: " .file_exists($path);
echo "<br/>";
echo "File Contents: " . file_get_contents($path);
echo "<br/>";

// foreach line get line number and line contents 
foreach($fileObject2 as $line_num => $line) {
  echo 'Line: '.$line_num;
  echo ' With: "'.$line.'" is the end? '.($fileObject2->eof()?'yes':'no')."<br>";
}

?>

输出:

/tmp/EAdklY.txt

文件存在:1

文件内容:foobar

行:0,结尾是“Foo”吗?否

行:1加上:“Bar”是结尾吗?否

行:2,带:“”是结尾吗?是


为什么会发生这些事情?

您在编写
SplFileObject
类时遇到了一种特殊情况。如果不使用默认(
0
)标记调用
next()
current()
方法,迭代器将永远不会向前移动

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

这应该被视为一个bug(无论是在PHP本身中,还是文档中的一个故障),下面的代码应该(也不是)按预期工作

解决办法

让事情进展的一个快速步骤是在对象上设置
READ_AHEAD
标志。这将导致
next()
方法读取下一个可用行

$file->setFlags(SplFileObject::READ_AHEAD);
如果出于任何原因,您不希望出现预读行为,则必须自己调用
next()
current()

回到两个SPLFileObject的原始问题

下面的内容现在应该可以像您预期的那样工作,允许追加到文件并读取其行数

<?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));

为什么会发生这些事情?

您在编写
SplFileObject
类时遇到了一种特殊情况。如果不使用默认(
0
)标记调用
next()
current()
方法,迭代器将永远不会向前移动

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

这应该被视为一个bug(无论是在PHP本身中,还是文档中的一个故障),下面的代码应该(也不是)按预期工作

解决办法

让事情进展的一个快速步骤是在对象上设置
READ_AHEAD
标志。这将导致
next()
方法读取下一个可用行

$file->setFlags(SplFileObject::READ_AHEAD);
如果出于任何原因,您不希望出现预读行为,则必须自己调用
next()
current()

回到两个SPLFileObject的原始问题

下面的内容现在应该可以像您预期的那样工作,允许追加到文件并读取其行数

<?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));

“test line”是@your file?@Zuul唯一一行代码没有任何依赖项。您可以按原样运行它。它会在临时目录中创建一个文件。“test line”只有一行是@your file?@Zuul代码没有任何依赖项。您可以按原样运行它。它会在临时目录中创建一个文件。谢谢。
var\u转储(迭代器计数($fileObject2))的原因是什么
行挂起?在测试时,它仍然挂起,即使我用
current
替换
next
。什么仍然挂起?
迭代器的计数()
call?似乎您不能在
SPLFileObject
对象上使用此函数。似乎您需要自己迭代该对象。每次
eof
方法仍然返回false。上面的示例清楚地显示了
eof()
函数在使用
current()时确实返回false
函数。这表示您有一个不同的,而不是带有
eof()
的函数。谢谢。为什么
var\u转储(迭代器计数($fileObject2));
行挂起?经过测试,它仍然挂起,即使我用
current
替换
next
。还有什么挂起?迭代器计数()
call?似乎您不能在
SPLFileObject
对象上使用此函数。似乎您需要自己迭代该对象。每次
eof
方法仍然返回false。上面的示例清楚地显示了
eof()
函数确实返回了