php - 是否可以知道 php 是否为 ://input contains data before starting reading it?

标签 php http

根据 documentation , php://input并不总是包含 HTTP 请求正文。

我有一些代码总是在脚本启动时打开流,以使其可供用户应用程序使用:

$stream = fopen('php://input', 'rb');

如果用户应用程序尝试从空流中读取数据,则 Content-Length > 0 ,我希望我的库抛出异常:

The request body is not available.

我的问题是:

  • 如果流为空,feof()返回falsefread()尚未被调用;
  • 我不能fread() 1 个字节则 fseek() ,因为该流不支持查找;
  • 我无法打开另一个 php://input并尝试事先读取它,因为我们不能依赖此流多次可用;
  • 我不想盲目复制php://inputphp://temp出于性能原因,在将手交给用户应用程序之前。

因此,是否可以判断 php://input包含 fopen() 之后的数据,但在任何 fread() 之前

最佳答案

我找到的解决方案是创建一个表示请求正文的类,并从该类读取而不是直接读取 php://input:

class RequestBody
{
    protected $firstByte;

    protected $isEmpty;

    public function __construct($stream)
    {
        $this->firstByte = fread($stream, 1);
        $this->isEmpty = ($this->firstByte === '');

        // ...
    }

    public function isEmpty()
    {
        return $this->isEmpty;
    }

    public function read($length)
    {
        // ...
    }
}

$body = new RequestBody(fopen('php://input', 'rb'));

类构造函数读取流的第一个字节,将其存储以供以后使用,并立即知道流是否为空。

read() 通过在第一次调用时返回第一个字节 + $length - 1 字节来隐藏这种复杂性。

关于php - 是否可以知道 php 是否为 ://input contains data before starting reading it?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11298887/

相关文章:

android - 如何在没有本地主机通信的情况下使用 REST API 在 android 客户端和 python-Flask 服务器之间进行连接?

node.js - 无法访问 ec2 上的快速服务器

javascript - Codechef api 上的 CORS(使用 angularjs)

javascript - 如何使用ajax通过表单中的按钮提交数据

php - 在 Symfony 1.4 中的每个 Action 后执行代码

PHP计算执行时间,有时返回负值

php - 在 IF 语句中计算一个表中的行数

php - 在 "Location:" header 中使用协议(protocol)相关 URI

php - 我正在尝试使用 php 代码删除使用复选框选择的行

http - 使用相同的处理程序处理 websockets 和 HTTP