【问题标题】:Start the PHP script after headers, but before body is received在标头之后但在收到正文之前启动 PHP 脚本
【发布时间】:2012-05-03 21:44:54
【问题描述】:

使用 PHP 和 Apache,是否可以在接收到标头之后但在发送正文之前启动 PHP 脚本?

我的意思是这样的:

PUT /sync/testStream.php HTTP/1.1
Host: localhost
User-Agent: test
Content-Length: 500
Content-Type: text/plain

<start the script here>

hello
this is a test

目标是在脚本期间锁定文件(实际上是在上传期间)。

我尝试从 php://input 读取,但没有成功:脚本仅在收到整个正文时启动。

这是我的脚本:

<?php
echo "Hello. Start sending data.";
ob_flush();

$file = fopen('php://input', 'r');
if ($file === false) {
    die("Could not open php://input");
}

while (($line = fgets($file)) !== false) {
    echo $line;
}

echo "Bye";

欢迎任何提示!

【问题讨论】:

  • 你能澄清你的问题吗? PHP 通常在发送标头之前由 Web 服务器启动。

标签: php apache stream


【解决方案1】:

我以前在这里看到过这个问题(现在找不到,但我有),经过多次讨论/辩论,得出的结论是不,你不能。

这是因为文件上传过程和请求正文的接收由上层 Web 服务器处理,并且 PHP 直到请求被完全接收/解析/验证后才会启动。

这里有一点是您的脚本似乎试图通过 HTTP 建立全双工通信,这是不可能的。 HTTP 本质上是一种半双工协议 - 它具有请求-响应架构,在完全接收到请求之前您不能开始发送响应,这将违反协议。

如果您准确解释您要做什么/为什么要在上传期间锁定文件,也许我们可以找到替代解决方案。

【讨论】:

  • 好吧,我正在尝试创建一种可以部署在简单 apache 服务器上的同步机制。这个想法是在上传过程中锁定文件,以防止其他人通过上传相同的文件来破坏某人的上传,但速度更快。
  • 通过 POST 方法上传,您应该从客户端抽象出服务器上文件的路径 - POST 方法不是幂等的,应该这样对待。或者你想在这里处理 PUT 方法上传?
  • 这是一个 PUT,在某种意义上它是文件替换(新版本)。在我的情况下,文件的路径无法抽象,因为它是 1. 文件的标识符,以及 2. 人类明智地选择的位置。所以是的,我需要在这里上传。
  • OK 很好 - 在这种情况下,由于您允许多个用户 PUT 到同一个 URI 这一事实的本质,您确实冒着同时上传的风险。如果您实施锁定,这不会导致服务器上的文件损坏 - 只有一个用户能够一次写入文件 - 但您确实冒着上传文件和其他人的风险覆盖它。它是否同时发生有点无关紧要。
  • 好吧,也许你是对的。事实是,我想阻止用户发送会导致冲突的文件(通常是两个用户同时发送到相同的文件路径),而不是让他通过 3G 发送 20Mb 然后只告诉他“嘿,它失败了”。你觉得我有什么办法可以做到这一点吗?
【解决方案2】:

实际上,这是不可能的,因为 PHP 在 HTTP 请求完成之前并不知道任何请求。也就是说,PHP在上传完成后接收查询。

【讨论】:

    【解决方案3】:

    PHP 在整个请求之后执行。 要实现此功能,您可以编写自定义 apache 模块。

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 2014-12-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      相关资源
      最近更新 更多