Heim >Backend-Entwicklung >PHP-Tutorial >Wie kann ich die Dateigröße eines servergebundenen Uploads in Echtzeit ermitteln?
Frage:
Ermitteln Sie die Dateigröße einer hochgeladenen Datei in Echtzeit, während diese auf den Server geschrieben wird, ohne dass beide Server blockiert werden und Client.
Kontext:
Datei-Upload-Fortschritt im Browser eines Clients, während mit der POST-Anfrage von fetch() mit einem Datei- oder Blob-Körper auf den Server geschrieben wird.
Anforderung:
Zeigen Sie die Dateigröße als Text/Ereignis-Stream an, während sie in das Serverdateisystem geschrieben wird. Stoppen Sie, wenn alle Bytes, die während des Datei-Uploads als Abfragezeichenfolgenparameter bereitgestellt wurden, geschrieben wurden. Die Dateigröße wird derzeit von einem separaten Skript abgerufen, das aufgerufen wird, nachdem die Datei auf den Server geschrieben wurde.
Implementierung:
Zunächst mit PHP versucht, aber scheiterte Fehler aufgrund undefinierter HTTP_LAST_EVENT_ID und falscher Dateigröße. Experimentierte auch mit verschiedenen Ansätzen und Sprachen wie Bash, C, NodeJS und Python.
Lösung:
<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>
Wichtige Hinweise:
Das obige ist der detaillierte Inhalt vonWie kann ich die Dateigröße eines servergebundenen Uploads in Echtzeit ermitteln?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!