이 기사의 예에서는 PHP에서 feof() 함수의 사용법을 설명합니다. feof() 함수에 대한 특정 테스트를 수행했는데 이는 매우 실용적인 가치가 있습니다. 구체적인 분석은 다음과 같습니다.
이 기사의 실행 환경 예시:
OS: Mac OS X 10.8.4
PHP: 5.3.15
공식 PHP 매뉴얼에는 feof() 함수에 대한 논의가 많이 있습니다.
테스트 코드는 다음과 같습니다.
<?php print <<<EOF <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>测试PHP中的feof()函数效果</title> </head> <body> <div> EOF; function bool2str($bool) { if ($bool == TRUE) { return "TRUE"; } else { return "FALSE"; } } /* * 请随便创建一个文件。 * 比如:本测试中,在脚本文件的相同路径下创建了一个文本文件, * 文件内容为“abcdefg”,文件名为“7bytesfile”。 */ $filename = './7bytesfile'; $handle = fopen($filename, 'r'); if (!$handle) { die("文件打开失败"); } for($i = 0; $i <= filesize($filename); $i++) { fseek($handle, $i); echo "文件位置" . ftell($handle) . ":<br />\n"; echo "执行fseek,尚未执行读取操作之前,feof结果:" . bool2str(feof($handle)) . "<br />\n"; echo "当前位置字符:" . fgetc($handle) . "<br />\n"; echo "执行文件读取操作之后,feof结果:" . bool2str(feof($handle)) . "<hr />\n"; } /* * 通过上面一段代码可以观察到, * 随着循环的执行,文件指针从文件头一直移动到文件末尾。 * 但是当完成了字符“g”的读取输出,文件指针继续向后移动,这是feof()依然返回False。 * 只有当执行了一次fgetc()操作之后,才返回true,表示到达文件末尾。 */ echo "ftell()结果:". ftell($handle). "<hr />\n"; //输出一下,很郁闷的发现文件指针的位置还是7。+_+ fseek($handle, 4); echo "文件位置" . ftell($handle) . ":<br />\n"; echo "执行fseek,尚未执行读取操作之前,feof结果:" . bool2str(feof($handle)) . "<br />\n"; echo "当前位置字符:" . fgetc($handle) . "<br />\n"; echo "执行文件读取操作之后,feof结果:" . bool2str(feof($handle)) . "<hr />\n"; fseek($handle, 7); echo "文件位置" . ftell($handle) . ":<br />\n"; echo "执行fseek,尚未执行读取操作之前,feof结果:" . bool2str(feof($handle)) . "<br />\n"; echo "当前位置字符:" . fgetc($handle) . "<br />\n"; echo "执行文件读取操作之后,feof结果:" . bool2str(feof($handle)) . "<hr />\n"; fclose($handle); //再次移动文件指针,效果依旧。 //再用另外一段代码测试一下: $handle = fopen($filename, 'r'); if (!$handle) { die("文件打开失败"); } while (!feof($handle)) { $char = fgetc($handle); if ($char === FALSE) { echo 'FALSE'; } else { echo $char; } } fclose($handle); //依然是输出了字符g之后,再次执行读取操作,才终止循环。 print <<<EOF </div> </body> </html> EOF; ?>
이러한 상황에 대한 추측은 PHP에서 feof() 구현이 파일을 기준으로 파일 포인터의 위치를 직접 확인하지 않고 특정 식별자를 기반으로 결과를 반환한다는 것입니다. 이 플래그는 각 fseek() 후에 "False"로 설정됩니다. 파일 내용 읽기 작업이 수행된 후에만 플래그는 파일 읽기 결과에 따라 설정됩니다.
이러한 추측을 바탕으로 두 가지 코드 논리를 사용할 수 있습니다.
feof() 감지를 수행하지 않고 콘텐츠 읽기 함수(예: fgetc(), fgets())의 실행 결과를 직접 감지하는 방법도 있습니다.
샘플 코드는 다음과 같습니다.
while (($content = fgets($fileHandle)) !==FALSE) { //文件内容处理…… }
이 처리 방법은 PHP의 비판적인 함수 반환 방법을 활용하므로 감지를 위해 "===" 또는 "!=="를 사용해야 합니다. 코드는 다음과 같이 단순화될 수 없습니다.
while ($content = fgets($fileHandle)) {}
또 다른 방법은 아래와 같이 먼저 파일을 읽은 다음 feof() 루프를 입력하는 것입니다.
$content = fgets($fileHandle); while (!feof($fileHandle)) { //处理文件内容…… $content = fgets($fileHandle); }
테스트해본 결과 전자의 방법이 더 효율적이었습니다.
이 기사의 예제가 PHP 프로그래밍에 종사하는 모든 사람에게 도움이 되기를 바랍니다.