问题:
在不阻塞服务器的情况下,获取上传文件写入服务器的实时文件大小和客户端。
上下文:
使用带有文件或 Blob 正文的 fetch() 的 POST 请求写入服务器时,客户端浏览器中的文件上传进度。
要求:
在将文件大小写入服务器文件系统时将其显示为文本/事件流。当文件上传期间作为查询字符串参数提供的所有字节都已写入时停止。当前从单独的脚本检索文件大小,该脚本在文件写入服务器后调用。
实现:
最初尝试使用 PHP 但遇到了问题由于未定义的 HTTP_LAST_EVENT_ID 和报告的文件大小不正确而导致的错误。还尝试了不同的方法和语言,如 bash、c、nodejs 和 python。
解决方案:
<code class="php">clearstatcache(true, $upload); $data = filesize($upload);</code>
<code class="php">// Check if the header's been sent to avoid `PHP Notice: Undefined index: HTTP_LAST_EVENT_ID in stream.php on line ` // php 7+ //$lastId = $_SERVER["HTTP_LAST_EVENT_ID"] ?? 0; // php < 7 $lastId = isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? intval($_SERVER["HTTP_LAST_EVENT_ID"]) : 0; $upload = $_GET["filename"]; $data = 0; // if file already exists, its initial size can be bigger than the new one, so we need to ignore it $wasLess = $lastId != 0; while ($data < $_GET["filesize"] || !$wasLess) { // system calls are expensive and are being cached with assumption that in most cases file stats do not change often // so we clear cache to get most up to date data clearstatcache(true, $upload); $data = filesize($upload); $wasLess |= $data < $_GET["filesize"]; // don't send stale filesize if ($wasLess) { sendMessage($lastId, $data); $lastId++; } // not necessary here, though without thousands of `message` events will be dispatched //sleep(1); // millions on poor connection and large files. 1 second might be too much, but 50 messages a second must be okay usleep(20000); }</code>
<code class="javascript">const [fileId, request, source] = [ Math.random().toString(36).substr(2), new Request(`${url}?fileId=${fileId}&size=${filesize}`, { method: "POST", headers: headers, body: file }), new EventSource(`${stream}?fileId=${fileId}`) ];</code>
<code class="php">function setUnique(string $id, int $size) { // implement with your storage of choice } function updateProgress(string $id, int $processed) { // implement with your storage of choice }</code>
<code class="php">list($progress, $size) = getProgress($_GET["fileId"]);</code>
重要提示:
以上是如何获取服务器绑定上传的实时文件大小?的详细内容。更多信息请关注PHP中文网其他相关文章!