Determine in PHP that the file was guaranteed to download, unfortunately, will not succeed. However, if nginx is used as a frontend, then you can at least make sure that the file (in this case, part of the file) has been given.
In nginx there is a directive post_action
, which makes a repeated internal request after the answer has already been sent to the client. Accordingly, thanks to it, you can find out how much real data was sent to the client. The config will look like this:
# скрипт, который отдает файл по частям location = /download.php { fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME /var/www/localhost/htdocs/$fastcgi_script_name; include fastcgi_params; post_action /complete; } # а этот скрипт уже будет подсчитывать байты location = /complete { internal; fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME /var/www/localhost/htdocs/complete.php; # количество отправленных клиенту байт fastcgi_param BYTE-SEND $body_bytes_sent; # заголовок Range fastcgi_param RANGE $http_range; include fastcgi_params; }
After download.php will send another piece of the file, nginx will make an internal request to complete.php, where in $_SERVER['BYTE-SEND']
will be the number of bytes sent, and in $_SERVER['BYTE-SEND']
Range header from the client.
Well, after that is a matter of technology. We consider somewhere (for example in a session) bytes or, for greater reliability, Range spans are better. And the code, the number of bytes given will be equal to the file size - it means the file was given entirely.
PS Unfortunately the post_action directive is not documented.
UPD. If PHP works through fastcgi or any reverse-proxy stands behind it (again, nginx for example), then it is useless to define it on PHP itself. After PHP gives the web server a piece of data, the further fate of it is no longer known to him.
If PHP works on apache via mod_php without any reverse-proxy, then it is probably a stretch to assume that after flush()
data has gone to the client.
Another way is to give the file directly through the sockets. Those. write a script that would itself act as a web server. However, this is not a very productive solution.
All other options for PHP, I do not see.