ファイルが完全にダウンロードされたかどうかを知る方法があるかどうか知りたかったのです。つまり、ファイルがダウンロードされたら、何らかのアクション (サーバーにメッセージを送信したり、ユーザーに警告したりするなど) をトリガーすることは可能ですか?
おそらくJava、phpで。
ありがとうございました。
反対のコメントにもかかわらず、これは可能ですが、HTTP プロトコルの知識とファイル ストリーミングの理解が必要なため、気弱な人向けではありません。
PHPを想定して...
ignore_user_abort()
次のように指示します。これにより、ユーザーが接続を閉じた後も php スクリプトを実行し続けることができます。Connection: close
ヘッダーとヘッダーを送信しContent-Length: 1234
ます。ここで、1234 は提供されるファイルのサイズです。fwrite
出力したバイト数を追跡します。出力バイト数がファイルサイズに達すると、終了したことがわかります。クライアントは接続を閉じますが、スクリプトは引き続き実行されます。ただし、Web SAPI では、PHP の最大時間制限に簡単に達する可能性があるため、注意してください。
アップデート:
このようなことを行う場合はconnection_aborted
、出力ループにチェックを追加して、クライアントが転送を完了する前に接続を中止した場合に出力をストリーミングし続けないようにする必要があることに注意してください。これは常識のはずですが、警告しなかったとは言わないでください。
phpscript 経由でファイルを送信するだけです。例: http://exmaple.com/download.php?filename=some_filename.txt
$file=$_GET['filename'];
if (file_exist($file)){
send_message_to_somebody(); //DO what ever you want here and then
$mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $file);
header("Content-Type: " . $mime);
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
header('Content-Disposition: attachment; filename="' . basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
}
データベースに情報を書き込みます。ダウンロードがキャンセル/中止された場合、「is_downloaded」のような列は 1 ではなく 0 になります... 説明が不十分で、時間がありません。
ここで重要なのは、ダウンロード完了のトリガーとなる_destruct()です。
<?php
class Download
{
protected $file;
private $session;
private $_last_insert_id;
public function __construct($file, $session)
{
$this->file = $file;
$this->session = $session;
}
public function send()
{
$info = pathinfo($this->file);
$query = DB::insert('downloads', array('user_id', 'file', 'path', 'start'))
->values(array($this->session->get('id'), $info['basename'], $this->file, DB::expr('NOW()')))
->execute();
$this->_last_insert_id = $query[0];
$this->session->set('downloading', 1);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$info['basename'].'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($this->file));
readfile($this->file);
}
public function __destruct()
{
$aborted = connection_aborted();
$this->session->set('downloading', 0);
$query = DB::update('downloads')->set(array('stop' => DB::expr('NOW()')))->where('id', '=', $this->_last_insert_id)->execute();
}
}