php函数

时间:2015-12-24 02:16:13

标签: php fgets fseek ftell

这是我的代码:

<?php
    $url="http://www.sina.com.cn";
    $handle = @fopen($url, "r");
    $len=get_headers($url,true);
    print_r($len);
    echo $len['Content-Length']."\n";
    if ($handle) {
        while (($buffer = fgets($handle,1024)) !== false) {
            echo ftell($handle)."\n";
            fseek($handle,200000,SEEK_CUR);
            echo ftell($handle)."\n";
        }
        if (!feof($handle)) {
            echo "Error: unexpected fgets() fail\n";
        }
        fclose($handle);
    }
?>

结果如下:

    Array
(
    [0] => HTTP/1.1 200 OK
    [Content-Type] => text/html
    [Vary] => Accept-Encoding
    [X-Powered-By] => shci_v1.03
    [Server] => nginx
    [Date] => Thu, 24 Dec 2015 04:03:39 GMT
    [Last-Modified] => Thu, 24 Dec 2015 04:01:28 GMT
    [Expires] => Thu, 24 Dec 2015 04:04:39 GMT
    [Cache-Control] => max-age=60
    [Age] => 32
    [Content-Length] => 518264
    [X-Cache] => HIT from xidan33-99.sina.com.cn
    [Connection] => close
)
518264
16
200016
200058
400058
400065
518264

Content-Length可能与我的不同 - 518264,它会在您执行代码时动态更改,无论讨论如何都是如此。 为什么结果不是以下?

518264
1024
201024
202048
402048
403072

请解释文件指针对fgets和ftell和fseek函数的操作。

4 个答案:

答案 0 :(得分:10)

fgets的长度参数表示最大长度。 PHP documentation州:

  

读取长度 - 读取1个字节,或换行(包含在返回值中)或EOF(以先到者为准)时结束。如果没有指定长度,它将继续从流中读取,直到它到达行尾。

在您的情况下,第一行包含<!DOCTYPE html>,其中解释了ftell给出的16的结果。

答案 1 :(得分:7)

根据fgets()的PHP文档,

  

读取长度 - 读取1个字节或换行(包含在返回值中)或EOF(以先到者为准)时结束。

此处长度是您在调用fgets()时使用的第二个参数, 1024 。因此,当发生以下任何情况时,您对fgets()的调用将结束阅读:

  1. 已从同一行读取 1023 个字节。
  2. 已到达当前行的末尾。
  3. 已到达文件末尾。
  4. 所以,在你的情况下,当fgets()读取第一行时,它在读取 16 字节后到达第一行的末尾,这将是文件指针的位置由旁边的ftell()呼叫。 ftell() 返回文件中文件指针的当前位置。

    当您在下一行再次呼叫fgets()时(由while循环重复),您在文件中的起始位置现在 16 (特别是不是1024)并且您可以读取最多(16 + 1024) 1040 字节(不高达2048)。再次,如果您的下一行只有 42 字节,则此fgets()将以 58 字节结束读取,这将是{调用}时文件指针的位置{1}}再次。

    再次,您将从 58 字节开始下一个ftell(),以读取(58 + 1024 =) 1082 字节。它将继续这种方式。

    fgets()的影响
    fseek()用于将文件指针移动到文件中由 $ offset (第二个参数)设置的特定位置。根据{{​​3}}的PHP文档,第3个参数值可以是 -

    fseek() - 设置位置等于偏移字节。
    SEEK_SET - 将位置设置为当前位置加偏移。
    SEEK_CUR - 将位置设置为文件结束加偏移。

    因此,通过SEEK_END,您将文件指针设置为200000 +当前位置。例如,它将在16年时移至200016。

答案 2 :(得分:3)

有三个函数可用于设置和确定给定文件的文件指针的位置。

<强>与fgets()

从文件指针获取一行。它假设1024为行长度。如果文件中的大多数行都大于8KB,则脚本指定最大行长度的资源效率会更高。

返回最长为length的字符串 - 从handle指向的文件中读取1个字节。如果文件指针中没有要读取的数据,则返回FALSE

ftell()

内置函数:pos = ftell (fid)

将文件指针的位置返回为文件描述符fid指定的文件开头的字符数。

<强> FSEEK()

内置函数:fseek (fid, offset) 内置函数:fseek (fid, offset, origin)

将文件指针设置为文件fid中的位置偏移量。

指针位于偏离原点的位置,可能是预定义变量之一SEEK_CUR (current position), SEEK_SET (beginning),SEEK_END (end of file)或字符串"cof", "bof" or "eof".如果省略原点,则假设为SEEK_SET。偏移可以是正,负或零,但并非所有原点和偏移的组合都可以实现。

fseek成功时返回0,错误时返回-1。

答案 3 :(得分:3)

使用PHP函数stream_get_meta_data()查看您打开的流是否可搜索:

$url="http://www.sina.com.cn";
$handle = @fopen($url, "r");

$meta_data = stream_get_meta_data($handle);
var_dump($meta_data['seekable']);

// It prints `bool(false)`

该流不可寻找。这意味着函数fseek()ftell()rewind()具有意外(可能不一致)的行为。