Heim > Backend-Entwicklung > PHP-Tutorial > Wie kann ich die Dateigröße eines servergebundenen Uploads in Echtzeit ermitteln?

Wie kann ich die Dateigröße eines servergebundenen Uploads in Echtzeit ermitteln?

Susan Sarandon
Freigeben: 2024-10-20 22:02:02
Original
301 Leute haben es durchsucht

How Can I Get the Real-Time File Size of a Server-Bound Upload?

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:

  1. Löschen Sie den Dateistatistik-Cache, um eine Echtzeitdatei zu erhalten Größe:
<code class="php">clearstatcache(true, $upload);
$data = filesize($upload);</code>
Nach dem Login kopieren
  1. Stream.php mit Fehlerbehandlung und Verwendung von usleep für bessere Leistung geändert:
<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>
Nach dem Login kopieren
  1. FileId und fileSize einschließen als Teil der POST-Anfrage und fügen Sie In-Memory-Speicher mit Redis oder Memcache hinzu, um Dateimetadaten zu speichern.
  2. Verwenden Sie EventSource im clientseitigen JavaScript:
<code class="javascript">const [fileId, request, source] = [
    Math.random().toString(36).substr(2),
    new Request(`${url}?fileId=${fileId}&amp;size=${filesize}`, {
        method: "POST",
        headers: headers,
        body: file
    }),
    new EventSource(`${stream}?fileId=${fileId}`)
];</code>
Nach dem Login kopieren
  1. Passen Sie die Funktionen setUnique und updateProgress basierend auf dem von Ihnen gewählten Speichermechanismus an:
<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>
Nach dem Login kopieren
  1. Erhalten Sie den Fortschritt aus dem Speicher:
<code class="php">list($progress, $size) = getProgress($_GET["fileId"]);</code>
Nach dem Login kopieren

Wichtige Hinweise:

  • Die bereitgestellte Lösung priorisiert Funktionalität vor Sicherheit und wird nicht für den Produktionseinsatz ohne Implementierung zusätzlicher Sicherheitsmaßnahmen empfohlen.
  • Die Anzahl der offenen Verbindungen muss möglicherweise angepasst werden angepasst basierend auf Serverkonfiguration und Ressourcenauslastung.
  • Anstelle von EventSource kann die Verwendung von Polling in Betracht gezogen werden, um die Anzahl offener Verbindungen zu reduzieren, aber es kann sich auf die Reaktionsfähigkeit auswirken.
  • Die optimale Schlafzeit in usleep () kann je nach gewünschter Aktualisierungshäufigkeit und Leistungskompromissen variieren.

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!

Quelle:php
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage