下载特定文件URL时触发操作

时间:2019-04-26 21:17:46

标签: php apache sqlite download

我想触发Apache侦测到某个文件URL已开始下载的动作(或:成功下载)。

示例:当客户端下载https://example.com/download/token_A6FZ523/myfile.zip时,对SQLite数据库执行以下查询:

INSERT INTO downloads(date, tokenID) VALUES(CURRENT_TIMESTAMP, "A6FZ523");

用法:然后,在PHP仪表板中,我可以检查谁下载了所提供的文件。

我可以这样:

  • 每分钟在服务器上运行一个脚本,
  • 解析Apache日志/var/log/apache2/other_vhosts_access.log以搜索模式download/token_.*/myfile.zip

  • 在这种情况下执行INSERT INTO查询

这似乎相当复杂,每分钟必须运行脚本的事实并不是一个很好的解决方案。

要求Apache将信息“与下载令牌A6FZ523关联的文件已由客户端下载”保存到SQLite数据库中,是什么好的解决方案?? 还是应该改用PHP?

2 个答案:

答案 0 :(得分:2)

我认为您的问题在于,您直接获取存储在服务器上的文件,而不是使用PHP以编程方式“保留”该文件。这不是使用此方法遇到的第一个问题,您也无法检查安全性或从外部文件存储中获取文件(通常来说,这些天您不直接将文件存储在Web服务器上!)。

但是,一旦您知道如何做,便很容易:)

首先,让我们将下载文件的URL更改为https://example.com/download.php?token=A6FZ523

因此,我们正在将GET变量发送到名为“ download.php”的php脚本。在该脚本中,您将具有以下内容:

<?php 
$token = $_GET['token'];

// Get the information about the file from the DB, something like:
// SELECT filename, size, path FROM files WHERE token = $token;
// Giving you $filename, $size and $path

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename); 
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $size);

echo file_get_contents($path);

// This will be on a completed download
// INSERT INTO downloads(date, tokenID) VALUES(CURRENT_TIMESTAMP, $token);
?>

调用download.php文件时,将获取令牌并将其与数据库中文件的信息匹配。然后,您设置标题,该标题基本上告诉浏览器“这是一个文件”,您的浏览器通过正常执行文件下载来做出相应的响应。然后,您将文件的内容读取给用户。完成此操作后,您可以通过另一个数据库调用记录下载。

要说的一个很大的事情是,该脚本(显然带有写入的DB调用)应该为您做最基础的事情,但是根据您的使用场景,还有很多要添加的内容。考虑安全性,输入验证,存储文件并发送MIME类型标头的位置。

希望这可以使您指向正确的方向:)

答案 1 :(得分:1)

如果您有权访问服务器并有权安装Thins,则可以添加mod_log_sql并让apache将日志直接保存到数据库表中(它甚至为您解析信息),您可以在仪表板中进行简单查询。这里的“事物”表明您需要获取下载程序的名称,因此,应将“ tokenID”添加到您的URL中,并设置Apache以拒绝不存在tokenID的URL。您需要从日志思想中解析url中的tokenID。