Page 1 sur 1

Gérer l'annulation d'un téléchargement par l'utilisateur

Posté : 27 nov. 2019, 13:09
par Naroth
Bonjour,

Pour des raisons de volumes j'utilise un téléchargement via des chunks pour ne pas dépassé la limite de mémoire de php

Le script ci-dessous ouvre la fenêtre classique à l'utilisateur pour savoir si il veut télécharger ou non le fichier
C'est sur ce point précis que je rencontre un problème

1 - Si l'utilisateur accepte le télécharge tout est ok
2 - Si l'utilisateur le refuse avant que "readfile_chunked" ait fini de récupérer le fichier alors "file_put_contents" n'est jamais exécuté

De ce que j'en comprend actuellement :
PHP n'attend pas le retour de l'utilisateur est commence directement le téléchargement
Si l'utilisateur clique sur annuler le script est arrêté et le fichier n'est jamais envoyé à l'utilisateur

La fonction readfile à le même comportement

Est-ce qu'il y a un moyen en cas de cancel de la part de l'utilisateur de ne pas télécharger mais de continuer le script malgré tout ?

<?php
define('CHUNK_SIZE', 1024 * 1024); // Size (in bytes) of tiles chunk

$file = "http://www.ovh.net/files/10Gio.dat";

$mimetype = 'application/octet-stream';

header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Type: ' . $mimetype);
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
readfile_chunked($file);

// Jamais exécuté si 2
file_put_contents("./test.txt", "test", FILE_APPEND);


la fonction readfile_chunked
// Read a file and display its content chunk by chunk
function readfile_chunked($filename, $retbytes = TRUE)
{
    $buffer = '';
    $cnt    = 0;
    $handle = fopen($filename, 'rb');

    if ($handle === false) {
        return false;
    }

    while (!feof($handle)) {
        $buffer = fread($handle, CHUNK_SIZE);
        echo $buffer;
        ob_flush();
        flush();

        if ($retbytes) {
            $cnt += strlen($buffer);
        }
    }

    $status = fclose($handle);

    if ($retbytes && $status) {
        return $cnt; // return num. bytes delivered like readfile() does.
    }

    return $status;
}

Re: [RESOLU] Gérer l'annulation d'un téléchargement par l'utilisateur

Posté : 27 nov. 2019, 13:21
par Naroth
Bon j'ai fini par trouvé

En utilisant

// Si l'utilisateur annule le téléchargement le script n'est plus arrêté
ignore_user_abort(true);

define('CHUNK_SIZE', 1024 * 1024); // Size (in bytes) of tiles chunk

$file = "http://www.ovh.net/files/10Gio.dat";

$mimetype = 'application/octet-stream';

header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Type: ' . $mimetype);
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
readfile_chunked($file);

// Traitement spécial en cas d'annulation
if (connection_aborted()) {
// L'utilisateur a soit annuler le téléchargement soit pas accepté
}

// Executé même si l'utilisateur cancel
file_put_contents("./test.txt", "test", FILE_APPEND);