<span 本文环境: OS:Mac OS X </span>10.8.4<span PHP:</span>5.3.15
In the official manual of PHP, there is a lot of discussion under the function feof(), and some related tests have been done on this.
<span 1</span> <?<span php </span><span 2</span> <span print</span> <<<<span EOF </span><span 3</span> <!DOCTYPE html> <span 4</span> <html> <span 5</span> <head> <span 6</span> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <span 7</span> <title>测试PHP中的feof()函数效果</title> <span 8</span> </head> <span 9</span> <body> <span 10</span> <div> <span 11</span> <span EOF; </span><span 12</span> <span 13</span> <span function</span> bool2str(<span $bool</span><span ) { </span><span 14</span> <span if</span> (<span $bool</span> == <span TRUE</span><span ) { </span><span 15</span> <span return</span> "TRUE"<span ; </span><span 16</span> } <span else</span><span { </span><span 17</span> <span return</span> "FALSE"<span ; </span><span 18</span> <span } </span><span 19</span> <span } </span><span 20</span> <span 21</span> <span /*</span> <span 22</span> <span * 请随便创建一个文件。 </span><span 23</span> <span * 比如:本测试中,在脚本文件的相同路径下创建了一个文本文件, </span><span 24</span> <span * 文件内容为“abcdefg”,文件名为“7bytesfile”。 </span><span 25</span> <span */</span> <span 26</span> <span $filename</span> = './7bytesfile'<span ; </span><span 27</span> <span $handle</span> = <span fopen</span>(<span $filename</span>, 'r'<span ); </span><span 28</span> <span if</span> (!<span $handle</span><span ) { </span><span 29</span> <span die</span>("文件打开失败"<span ); </span><span 30</span> <span } </span><span 31</span> <span 32</span> <span for</span>(<span $i</span> = 0; <span $i</span> <= <span filesize</span>(<span $filename</span>); <span $i</span>++<span ) { </span><span 33</span> <span fseek</span>(<span $handle</span>, <span $i</span><span ); </span><span 34</span> <span echo</span> "文件位置" . <span ftell</span>(<span $handle</span>) . ":<br />\n"<span ; </span><span 35</span> <span echo</span> "执行fseek,尚未执行读取操作之前,feof结果:" . bool2str(<span feof</span>(<span $handle</span>)) . "<br />\n"<span ; </span><span 36</span> <span echo</span> "当前位置字符:" . <span fgetc</span>(<span $handle</span>) . "<br />\n"<span ; </span><span 37</span> <span echo</span> "执行文件读取操作之后,feof结果:" . bool2str(<span feof</span>(<span $handle</span>)) . "<hr />\n"<span ; </span><span 38</span> <span } </span><span 39</span> <span /*</span> <span 40</span> <span * 通过上面一段代码可以观察到, </span><span 41</span> <span * 随着循环的执行,文件指针从文件头一直移动到文件末尾。 </span><span 42</span> <span * 但是当完成了字符“g”的读取输出,文件指针继续向后移动,这是feof()依然返回False。 </span><span 43</span> <span * 只有当执行了一次fgetc()操作之后,才返回true,表示到达文件末尾。 </span><span 44</span> <span */</span> <span 45</span> <span 46</span> <span echo</span> "ftell()结果:". <span ftell</span>(<span $handle</span>). "<hr />\n"<span ; </span><span 47</span> <span //</span><span 输出一下,很郁闷的发现文件指针的位置还是7。+_+</span> <span 48</span> <span 49</span> <span fseek</span>(<span $handle</span>, 4<span ); </span><span 50</span> <span echo</span> "文件位置" . <span ftell</span>(<span $handle</span>) . ":<br />\n"<span ; </span><span 51</span> <span echo</span> "执行fseek,尚未执行读取操作之前,feof结果:" . bool2str(<span feof</span>(<span $handle</span>)) . "<br />\n"<span ; </span><span 52</span> <span echo</span> "当前位置字符:" . <span fgetc</span>(<span $handle</span>) . "<br />\n"<span ; </span><span 53</span> <span echo</span> "执行文件读取操作之后,feof结果:" . bool2str(<span feof</span>(<span $handle</span>)) . "<hr />\n"<span ; </span><span 54</span> <span 55</span> <span fseek</span>(<span $handle</span>, 7<span ); </span><span 56</span> <span echo</span> "文件位置" . <span ftell</span>(<span $handle</span>) . ":<br />\n"<span ; </span><span 57</span> <span echo</span> "执行fseek,尚未执行读取操作之前,feof结果:" . bool2str(<span feof</span>(<span $handle</span>)) . "<br />\n"<span ; </span><span 58</span> <span echo</span> "当前位置字符:" . <span fgetc</span>(<span $handle</span>) . "<br />\n"<span ; </span><span 59</span> <span echo</span> "执行文件读取操作之后,feof结果:" . bool2str(<span feof</span>(<span $handle</span>)) . "<hr />\n"<span ; </span><span 60</span> <span fclose</span>(<span $handle</span><span ); </span><span 61</span> <span //</span><span 再次移动文件指针,效果依旧。 </span><span 62</span> <span //再用另外一段代码测试一下:</span> <span 63</span> <span 64</span> <span $handle</span> = <span fopen</span>(<span $filename</span>, 'r'<span ); </span><span 65</span> <span if</span> (!<span $handle</span><span ) { </span><span 66</span> <span die</span>("文件打开失败"<span ); </span><span 67</span> <span } </span><span 68</span> <span while</span> (!<span feof</span>(<span $handle</span><span )) { </span><span 69</span> <span $char</span> = <span fgetc</span>(<span $handle</span><span ); </span><span 70</span> <span if</span> (<span $char</span> === <span FALSE</span><span ) { </span><span 71</span> <span echo</span> 'FALSE'<span ; </span><span 72</span> } <span else</span><span { </span><span 73</span> <span echo</span> <span $char</span><span ; </span><span 74</span> <span } </span><span 75</span> <span } </span><span 76</span> <span fclose</span>(<span $handle</span><span ); </span><span 77</span> <span //</span><span 依然是输出了字符g之后,再次执行读取操作,才终止循环。</span> <span 78</span> <span 79</span> <span print</span> <<<<span EOF </span><span 80</span> </div> <span 81</span> </body> <span 82</span> </html> <span 83</span> <span EOF; </span><span 84</span> ?>
The guess for this situation is that in PHP, the implementation of feof() does not directly check the position of the file pointer relative to the file, but returns the result based on a certain identifier. This flag will be set to "False" after each fseek(). Only after a file content reading operation is performed, the flag will be set based on the result of the file reading.
Based on this guess, two code logics can be used.
One method is to directly detect the execution results of content reading functions (such as fgetc(), fgets()) without performing feof() detection.
<span 1</span> <span while</span> ((<span $content</span> = <span fgets</span>(<span $fileHandle</span><span )) !==FALSE) { </span><span 2</span> <span //</span><span 文件内容处理…… </span> <span 3</span> }
This method of processing takes advantage of PHP’s criticized function return method, so it must use “===” or “!==” for detection. The code cannot be simplified to:
<span while</span> (<span $content</span> = <span fgets</span>(<span $fileHandle</span>)) {}
Another method is to read the file first and then enter the feof() loop:
<span 1</span> <span $content</span> = <span fgets</span>(<span $fileHandle</span><span ); </span><span 2</span> <span while</span> (!<span feof</span>(<span $fileHandle</span><span )) { </span><span 3</span> <span //</span><span 处理文件内容……</span> <span 4</span> <span $content</span> = <span fgets</span>(<span $fileHandle</span><span ); </span><span 5</span> }
After testing, it seems that the former method is more efficient.