2010-04-14 14 views
42

estoy usando esto para el envío de archivos a usuariosborrar un archivo después de descargarlo de usuario

header('Content-type: application/zip'); 
header('Content-Length: ' . filesize($file)); 
header('Content-Disposition: attachment; filename="file.zip"'); 
readfile($file); 

Quiero borrar este archivo después de usuario lo descarga, ¿cómo puedo hacer esto?

EDITAR: Mi escenario es así, cuando el usuario acciona el botón de descarga, mi script crea un archivo zip temporal y el usuario lo descarga, luego ese archivo zip temporal se eliminará.

EDIT2: OK la mejor manera parece ejecutar un trabajo cron que limpiará archivos temporales una vez por hora.

EDIT3: He probado mi script con unlink, funciona a menos que el usuario cancele la descarga. Si el usuario cancela la descarga, el archivo zip permanece en el servidor. Entonces eso es suficiente por ahora. :)

EDIT4: ¡GUAU! connection_aborted() hizo el truco!

ignore_user_abort(true); 
if (connection_aborted()) { 
    unlink($f); 
} 

Este eliminará el archivo incluso si el usuario cancela la descarga.

+0

posible duplicado de [comprobar si se ha completado descargar] (http://stackoverflow.com/questions/1563187/check- if-download-is-completed) – hakre

Respuesta

21
unlink($filename); 

Esto eliminará el archivo.

Necesita combinarse con ignore_user_abort()Docs para que el unlink se ejecute incluso si el usuario canceló la descarga.

ignore_user_abort(true); 

... 

unlink($f); 
+0

bien, pero ¿funcionará mientras el usuario lo descargue? –

+2

Su mejor opción sería no entregar el archivo directamente desde el disco y, en su lugar, usar una URL única que pueda deshabilitar después de la solicitud de descarga. – inkedmn

+1

mi escenario es así, cuando el usuario acceda al botón de descarga, mi script creará una temperatura. archivo zip y el usuario lo descarga luego ese archivo zip temporal se eliminará –

8

No hay ninguna forma correcta de detectar si el archivo se descargó completamente por el usuario o no.
Así que la mejor manera será eliminar el archivo después de un período de inactividad.

+0

Creo que es mejor configurar un trabajo de Cron para eliminar el archivo después de un tiempo, digamos 5 minutos después de que se inició la descarga del archivo. (suponiendo que la descarga no lleva más de 5 minutos). –

0

La manera más segura que se me ocurre es usar alguna película flash del lado del cliente que pueda observar la transferencia desde el lado del cliente, y luego realizar una llamada XmlHttpRequest al servidor una vez que finaliza la descarga.

yo sepa, no hay manera de hacerlo de forma fiable y sin el uso de Flash (o un plugin para el navegador similar)

2

yo también tienen una funcionalidad muy similar en uno de mi página web. Será como eliminar la carpeta creada al azar & archivo zip después de/cancelar la descarga. Intento explicarlo aquí, puede ser que alguien lo encuentre útil.

skin.php:
Esta página contiene enlace de descarga como "http://mysite.com/downoload/bluetheme"

.htaccess:
He siguiente regla en el archivo .htaccess para redirigir la solicitud de descarga a un archivo php. [download.php].

RewriteRule ^download/([A-Za-z0-9]+)$ download.php?file=$1 [L] 

download.php:

include "class.snippets.php"; 
$sn=new snippets(); 
$theme=$_GET['file']; 
$file=$sn->create_zip($theme); 
$path="skins/tmp/$file/$file.zip"; 
$config_file="skins/tmp/$file/xconfig.php"; 
$dir="skins/tmp/$file"; 

$file.=".zip"; 
header("Content-type: application/zip"); 
header("Content-Disposition: attachment; filename=$file"); 
header("Pragma: no-cache"); 
header("Expires: 0"); 
readfile($path); 

//remove file after download 
unlink($path); 
unlink($config_file); 
rmdir($dir); 

tan bajo petición download.php creará directorio con un nombre aleatorio utilizando fragmentos de clase. Dentro del directorio creará un archivo zip. después de descargar/cancelar la solicitud, se eliminarán todos los archivos y el directorio.

1

no pude encontrar algo que funcionó para mí, así que se le ocurrió esto, que parece funcionar bien para mí:

header('Content-type: application/zip'); //this could be a different header 
header('Content-Disposition: attachment; filename="'.$zipName.'"'); 

ignore_user_abort(true); 

$context = stream_context_create(); 
$file = fopen($zipName, 'rb', FALSE, $context); 
while(!feof($file)) 
{ 
    echo stream_get_contents($file, 2014); 
} 
fclose($file); 
flush(); 
if (file_exists($zipName)) { 
    unlink($zipName); 
} 

Espero que ayude a alguien

0

connection_aborted (nunca) trabajó para mi. Pero ob_clean() funciona exactamente como debería. Espero que esta ayuda a otros también

header('Content-type: application/pdf'); 
header('Content-Disposition: inline; filename="' . $file . '"'); 
header('Content-Transfer-Encoding: binary'); 
header('Accept-Ranges: bytes'); 
ob_clean(); 
flush(); 
if (readfile($file)) 
{ 
    unlink($file); 
} 
8

siempre uso la siguiente solución:

register_shutdown_function('unlink', $file); 
+0

Perfecto para mi situación donde el archivo necesitaba existir mientras se ejecutaba la función, pero una vez que la secuencia de comandos estaba completamente hecha, borraba con éxito el archivo temporal. – Reisclef

+0

funciona mejor con 'ignore_user_abort (true);', en mi humilde opinión deben ser aceptados anwser –

+0

Esta solución fija mi problema por el que llama ob_end_flush() parecían terminar la ejecución del script (a pesar de que una de desenlace fue llamado en la línea siguiente). – danielcraigie

Cuestiones relacionadas