2009-10-13 15 views
7

Mi pregunta es - ¿Cuál es la mejor manera de detectar si se completa una descarga, porque después de eso quiero actualizar la base de datos.compruebe si se completa la descarga

He intentado con algo de este código de php manuel, pero no hace mucho por mí.

Header ("Content-Type: application/octet-stream"); 
Header ("Content-Length: ".filesize($file)); 
Header("Content-Disposition: attachment; filename=$filename"); 

// buffered read not using readfile($file); 

if ($fp = fopen($bestand, 'rb')) { 
    while (!feof($fp)) { 
     $buf = fread($fp, 4096); 
     echo $buf; 
     $bytesSent += strlen($buf); /* We know how many bytes were sent to the user */ 
    }  
} 

if ($bytesSent == filesize($fp)) { 
    //do something with db 
} 

gracias en adv, Richard

+0

im encontró una buena solución implementada PHP puro: http://bytes.com/topic/php/answers/551302-how-detect-if-file-download-completed- canceló – StefanoCudini

Respuesta

9

Eso realmente no le dirá si la descarga se ha completado para el usuario. Le indicará cuando usted haya terminado de enviar bytes al usuario, pero no dice nada acerca de cuántos de ellos ha recibido realmente el usuario.

En realidad, no hay forma de que PHP (que es un idioma del lado del servidor, no del lado del cliente) detecte realmente cuándo se ha completado la descarga de un archivo. Lo mejor que puede hacer es registrar la descarga en su base de datos cuando comienza. Si necesita absoluta y completamente saber cuándo se completó la descarga, tendrá que hacer algo como insertar un applet de Java o usar Flash. Sin embargo, generalmente esa no es la respuesta correcta en términos de usabilidad para su usuario (¿por qué requieren que tengan instalado Java o Flash solo para descargar algo de usted?).

+0

sí, lo he implementado y le he dado un mensaje de devolución para contactarme si algo salía mal. También utilicé un complemento de jquery para obtener una devolución de llamada cuando se completó y no tengo actualización de página. – Richard

+0

http://php.net/function.ignore_user_abort - http://www.php.net/connection_aborted – hakre

+0

@hakre for connection_aborted from the doc: Al ejecutar PHP como un script de línea de comandos solamente (tty). – Mike

1

No creo que sea posible a través de php para saber cuántas picaduras se han enviado (y, de hecho descargado a través del cliente), ya que no hay manera de saber si el usuario ha cancelado la descarga o recibido el archivo completo.

+0

Y está el servidor web entremedio. PHP no tiene control sobre él. – powtac

+1

También un proxy al final del usuario puede completar la descarga incluso si el usuario lo ha cancelado –

+0

gracias, Gnibbler. Entonces eso lo dice todo. No es una manera confiable. – Richard

2

Como Marc W ya señaló, php solo puede decirle lo que ha enviado desde el servidor, no lo que ha recibido el cliente, por lo que utilizar terminantemente php no es válido.

Pero siempre existe la posibilidad de solicitar al usuario que confirme la descarga presionando un botón que invoca una comprobación JS generando un hash MD5 y comparándolo con el hash MD5 del archivo en su servidor (el servidor MD5 está siendo generado por usted), y en una comparación exitosa utilice esa secuencia de comandos JS para actualizar su base de datos o úsela para llamar a un script php para que haga lo mismo.

Siempre puede pedirles que comprueben que la descarga es la que esperaban y, si presionan "sí, está bien", actualice la base de datos.


Editado: en respuesta al comentario de OP.

Gracias, pero no puede depender de la cooperatividad de los usuarios. Como también tienen que pagar por la descarga, es mejor que yo tenga todo el control. Creo que actualizaré la base de datos cuando se acceda al script. Eso parece ser el más confiable entonces.

¿Qué le parece usar un control Ajax para iniciar -y mantener- la descarga y, al finalizar, verificar su integridad y ejecutar una actualización de su base de datos?

Sugiero no asumir automáticamente que sus clientes van a estafarlo, sea lo que sea que termine eligiendo. Preguntarles amablemente '¿le funcionó? y, si no, conducir a un informe de errores podría ser útil para usted y para ellos.

Pero, independientemente, mientras que algunos de sus usuarios pueden decir "no" solo por la copia adicional, tiene que equilibrar el costo de eso con el costo de su mayor carga de trabajo para evitar que suceda. Si el costo de mantener la "honestidad" excede el costo potencial/probable de que tomen una copia adicional, entonces no tiene mucho sentido.

+0

Gracias, pero no puede depender de la cooperación de los usuarios. Como también tienen que pagar por la descarga, es mejor que yo tenga todo el control. Creo que actualizaré la base de datos cuando se acceda al script. Eso parece ser el más confiable entonces. – Richard

+0

Gracias por su aporte adicional, pero repasó el hecho de que usted mencionó que hay una forma de ajax. ¿Tienes un ejemplo para eso? – Richard

+0

Desafortunadamente, yo no. No sé JS/jQuery/Ajax lo suficientemente bien como para ofrecer una solución. Podría valer la pena editar tu pregunta original para incluir una solicitud y una nueva etiqueta para las soluciones Ajax, JS y/o jQuery. Lamento no poder ser más útil para ti en esto. –

-4

El siguiente código funciona.Si el cliente detiene la descarga, la base de datos no se actualiza y el enlace puede volver a iniciarse.

$file='pathto.zip'; 

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

    $sql = "UPDATE YOUR TABLE"; 

    exit; 
+0

Esto no funciona. 'readfile' no puede decir si el usuario ha cancelado. Se devuelve sin error, suponiendo que el archivo es lo suficientemente pequeño como para caber en el búfer de salida de una vez, y luego el código procede a la actualización de la base de datos. Nada se propaga hacia arriba desde la capa TCP para indicar la entrega al otro lado de la tubería. –

+0

Esto no funciona como tal. – Mike

+0

Esto ya no funciona. –

0

No es una solución si usted está mezclando php (para la llamada del lado del servidor) un javascript (para el cliente de llamadas completo).

Mire esta respuesta sobre cómo Detect when browser receives file download

Estoy bastante seguro de que puede tener un buen resultado como este. espero que esto ayuda a otros, Mike

Cuestiones relacionadas