【问题标题】:php first fseek in stream then fread?php首先在流中fseek然后fread?
【发布时间】:2016-09-22 20:52:48
【问题描述】:

我正在尝试一些 php 文件/流功能。我在 fread 上遇到了麻烦。

这个数据被发送到一个 php 脚本:

    baz=bomb&foo=bar&baz=bomb&foo=bar&foo=bar&baz=bomb

该脚本运行以下代码:

    <php
    $fp = fopen("php://input", "rb");
    fseek($fp, 3, SEEK_SET);
    echo "<br>ftell: ".ftell($fp)."<br>";
    echo "<br>fread(resource, 4): ".fread($fp, 4)."<br>";
    fclose($fp);

输出显示:

    ftell: 3
    fread(resource, 4): baz=

我期望它显示的是:

    =bom

为什么看起来 fread 先将指针设置到流的开头然后再读取?在流中寻找而无法从某个位置读取有什么意义?

我使用的 php 版本是: 7.0.8 在 Windows 机器上。

【问题讨论】:

  • 只是想知道为什么不$_POSTparse_str()
  • 我正在准备自己实现 php-fig psr-7 流接口。这是学习构建现代 php 框架的一部分。
  • 您确定将数据流式传输到 php 的内容不是在开头添加数据吗?当您使用与fseek() 不同的偏移量时会发生什么?
  • 我确信开头没有任何内容。例如,当我将 fseek 的偏移量更改为 5 时,会出现相同的“baz=”输出。而 ftell 说 5. 通过创建一个流上下文 (http) 并在调用上面代码的 readfile 函数上使用它来发送发布数据
  • 这解释了它:stackoverflow.com/questions/3107624/…the underlying stream does not implement the seek handler

标签: php position fread fseek


【解决方案1】:

这是问题的答案,我希望很多人会从中受益:

使用 fseek 时,ftell 似乎会告诉您指针在流中的位置。但事实并非如此。奇怪的是,fseek 函数无法移动流中的指针。正如 Starson Hochschild 指出的那样,这是因为底层流没有实现查找处理程序。

因此,另一种选择可能是读取 $_POST。但是大内容呢?

有一个名为 php://temp 的流。您放入的前两个 MB 将进入您电脑的内存。更多数据将进入您电脑上的临时文件。

所以你可以像这样使用它:

    $tempStream = fopen("php://input", "rb");
    $stream = fopen("php://temp", "w+b");
    $size = 0;
    while (!feof($in)) $size += fwrite($stream,fread($tempStream,8192)); //Copy the php://input stream to the seekable php://temp stream. $size will contain the size in bytes of the $stream resource.
    fclose($tempStream);

    //Do your next fread's, fseek's, ftell's etc here on the $stream resource.

    fclose($stream);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多