문제

왜 내 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

를 삭제하면 마지막 라인(iterator_count(... 다)및 그것을 대체 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 를 반환합니다 그래서 나는 무한 루프입니다.

왜 이러한 일이 일어나고 있는가?내가 필요로 라인을 얻기 위해 계산합니다.

도움이 되었습니까?

해결책

왜 이러한 일이 일어나고 있는가?

당신이 발생한 특수성에 기인하는 방식 SplFileObject 클래스를 작성합니다.를 호출하지 않고 next() current() 메서드를 사용하는 기본(0)플래그—반복기 절대 앞으로 이동합니다.

iterator_count() 함수 호출하지 않 current();확인 valid() 와 통화 next() 니다.귀하의 맞춤형 루프를 만화 중 하나 또는 기타의 current()next().

이 것으로 간주되어야 버그(에서 여 PHP 자체가 실패하거나 설명서)및 다음과 같은 코드 (하지 않)예상대로 작동합니다.나는 당신을 초대 보고서 이 비행.

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

해결 방법

한 빠른 회피 움직이는 물건을 얻을 수을 설정하는 것입니다 READ_AHEAD 깃발에서 객체입니다.이의 원인이됩니다 next() 메서드를 읽을 다음 사용 가능한 라인입니다.

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

는 경우,어떤 이유로,당신은 당신을 원하지 않는 미리 읽기 행동한 다음 호출해야 합니다 모두 next()current() 자신입니다.

다시 원래의 문제는 두 SplFileObjects

다음과 같은 이유로 당신은 당신이 예상할 수 있도록,추가하여 파일을 읽는 해당 라인 수입니다.

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

다른 팁

편집 된 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

파일 내용 : foo bar

라인 : 0 : "foo"는 끝입니까?아니오

라인 : 1 : "바"는 끝입니까?아니오

라인 : 2 : ""끝까지?예

PHP 5.3.9와 함께 직관적 인 것처럼 보일 수 있습니다.

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

인 무한 루프가되어 결코 종료되지 않습니다.

파일의 끝에 도달하면 다음을 종료합니다.

<?php
$f = new SplFileObject('test.txt', 'r');
while (!$f->eof()) {
    $f->current();
}
.

그래서 :

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

는 다음과 같이 다시 작성해야합니다 :

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

$i = $fileObject2->key();
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top