使用原始文件名下载短URL的文件

时间:2014-10-21 11:58:52

标签: php apache .htaccess

问题(见下面有更长的解释和我已经尝试过的事情):

有没有办法让短网址http://example.com/qf56p9z重定向到/files/qf56p9z_(.*)格式的服务器上找到的第一个文件,并将其下载到客户端,文件名为{{1} 1}}?(如果可能,没有PHP)


背景:

我在(.*)存储的服务器上有一个文件,我想通过这个简短的URL访问:

http://example.com/qf56p9z

(+其他数千个文件相同)

此外,我希望当用户访问此网址时,该文件将使用原始文件名下载到客户端计算机上,即/files/qf56p9z_blahblah.xls

这可能适用于PHP,我尝试过这样的事情(这可以很容易地为我的每千个文件自动化):

blahblah.xls

但是我发现这个方法存在两个问题:

  • 对于客户端每次读取文件,PHP必须将整个文件加载到内存中,然后输出新文件。与没有PHP

  • 的apache刚发送文件相比,这会消耗更多的CPU /内存
  • 如果有一天我将所有这些文件托管在其他地方(例如在Amazon S3上),则该文件必须执行此路由:

    <?php header('Content-type: ...'); header('Content-Disposition: attachment; filename="blahblah.xls"'); readfile('qf56p9z_blahblah.xls'); ?>

    遗憾的是数据必须这样做而不是:

    Distant-Hosting (AmazonS3) ==> my server/header modified with PHP ==> client

1 个答案:

答案 0 :(得分:1)

您可以结合使用 PHP .htaccess 使用mod_rewrite

网站结构

  • /var/www/html/files/ :包含您的文件的目录 {prefix}_{filename}格式
  • /var/www/html/download.php :找到带有给定前缀的第一个文件的PHP脚本
  • /var/www/html/.htaccess :使用2条mod_rewrite规则重写下载网址

<强> download.php

<?PHP

$files_dir = "files/";

if(isset($_GET['prefix'])){
    $files = glob($files_dir.$_GET['prefix']."_*");
    if(count($files) > 0) {
        $dl = strlen($files_dir);
        $pl = strlen($_GET['prefix']);
        $fn = substr($files[0], $dl+$pl+1);
        header("Location: d/".$_GET['prefix']."/".$fn);
    }
}

?>

这将选择具有所需前缀的第一个文件并重定向到它。

<强> .htaccess

RewriteEngine On
RewriteRule ^(\w+)$     download.php?prefix=$1 [L]
RewriteRule ^d/(.+)/(.+)$   files/$1_$2 [L]

第一条规则将短URL重写为download.php,第二条规则将URL重写为原始文件位置。

这就是它的工作方式

  1. http://example.com/qf56p9z - .htaccess - &gt; http://example.com/download.php?prefix=qf56p9z
  2. download.php - PHP重定向 - &gt; http://example.com/d/qf56p9z/blahblah.xls
  3. http://example.com/d/qf56p9z/blahblah.xls - .htaccess - &gt; http://example.com/files/qf56p9z_blahblah.xls
  4. 在上述所有步骤中,浏览器的位置栏网址保持不变,没有任何变化。