Maison >développement back-end >tutoriel php >Comment puis-je obtenir la taille du fichier en temps réel d'un téléchargement lié au serveur ?
Question :
Obtenir la taille en temps réel d'un fichier téléchargé pendant son écriture sur le serveur sans bloquer à la fois le serveur et client.
Contexte :
Progression du téléchargement du fichier dans le navigateur d'un client lors de l'écriture sur le serveur à l'aide de la requête POST de fetch() avec un corps de fichier ou de blob.
Exigence :
Afficher la taille du fichier sous forme de texte/flux d'événements pendant son écriture sur le système de fichiers du serveur. Arrêtez-vous lorsque tous les octets fournis en tant que paramètre de chaîne de requête lors du téléchargement du fichier ont été écrits. La taille du fichier est actuellement récupérée à partir d'un script distinct, qui est appelé après que le fichier a été écrit sur le serveur.
Implémentation :
Initialement tenté d'utiliser PHP mais rencontré erreurs dues à un HTTP_LAST_EVENT_ID non défini et à une taille de fichier incorrecte signalée. J'ai également expérimenté différentes approches et langages comme bash, c, nodejs et python.
Solution :
<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>
Remarques importantes :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!