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