<span 本文环境: OS:Mac OS X </span>10.8.4<span PHP:</span>5.3.15
PHP的官方手册中,函数feof()下面的讨论不少,对此做了一些相关的测试。
<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> ?>
针对这种情况的猜测是,在PHP中,feof()的实现方式并非直接检查文件指针相对于文件的位置,而是根据某个标识返回结果。每次fseek()之后都会都会把这个标识设置为“False”,只有当执行一次文件内容读取操作之后,才会根据文件读取的结果对标识进行设置。
根据这种猜测,可以使用两种代码逻辑。
一个方法是不做feof()检测,直接检测内容读取函数(比如fgetc()、fgets())的执行结果。
<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> }
这种处理办法,利用了PHP被诟病的函数返回方式,所以得用“===”或“!==”进行检测,不能把代码简化成:
<span while</span> (<span $content</span> = <span fgets</span>(<span $fileHandle</span>)) {}
另外一个方法是先进行一次文件读取,然后再进入feof()循环:
<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> }
经过测试,似乎前一种方法效率会高一些。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

记事本++7.3.1
好用且免费的代码编辑器

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Dreamweaver CS6
视觉化网页开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。