【问题标题】:Download a renamed file with PHP使用 PHP 下载重命名的文件
【发布时间】:2012-02-13 18:38:25
【问题描述】:

我正在制作一个 PHP 脚本,它将下载一个给定名称和版本的文件。文件将像这样存储在服务器上:

/dl/Project1/1.0.txt
/dl/Project1/1.1.txt
/dl/Project2/2.3.jar
/dl/Project2/2.3.1.jar

检索此类文件的路径如下所示:

download.php?name=Project1&type=txt&version=1.0
download.php?name=Project1&type=txt&version=1.1
download.php?name=Project2&type=jar&version=2.3
download.php?name=Project2&type=jar&version=2.3.1

实际下载文件时会出现问题。在此示例中,我希望前两个文件都下载为 Project1.txt,我希望后两个文件下载为 Project2.jar。如何临时重命名这些以使其正常工作?

【问题讨论】:

    标签: php file download rename


    【解决方案1】:

    发送一个定义文件名的标题。

    $filename = $name . "." . $type;
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . $filename);
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    

    我已经包含了额外的标题,因为您也应该发送这些标题。这只是您可以see in the PHP documentation on readfile 的修改示例。

    【讨论】:

      【解决方案2】:

      您可能只想使用 content-disposition 标头:

      header('Content-disposition: attachment; filename=Project1.txt');
      readfile('Project1/1.0.txt');
      

      【讨论】:

        【解决方案3】:

        不用重命名,只需要在header中改名字,有脚本:

        <?php
        // Check is set all params
        if (isset($_GET['name'], $_GET['type'], $_GET['version'])) {
          // Get the params into variables.
        
          // Secure replace to avoid the user downloading anyfile like @Kristian Antonsen said.
          // Replace all '..' to a single '.';
          $name = preg_replace('/[\.]{2,}/', '.', trim($_GET['name']));
          // Replace any strange characters.
          $type = preg_replace('/[^A-Za-z0-9]/', '', trim($_GET['type']));
          // Replace any letter and strange character.
          $version = preg_replace('/[^0-9\.]/', '', trim($_GET['version']));
        
          /**
           * Check is all the params filled with text
           *   and check if the version is in the right format.
           */
          if (!empty($name) &&
              !empty($type) &&
              !empty($version) &&
              preg_match('/^[0-9](\.[0-9])+$', $version)) {
            /**
             * Get the file path, here we use 'dirname' to get the absolute path
             *   if the download.php is on root
             */
            $filePath = dirname(__FILE__) . '/dl/' . $name . '/' . $version . '.' . $type;
        
            // Check if the file exist.
            if (file_exists($filePath)) {
              // Add headers
              header('Cache-Control: public');
              header('Content-Description: File Transfer');
              header('Content-Disposition: attachment; filename=' . $name . '.' . $type);
              header('Content-Length: ' . filesize($filePath));
              // Read file
              readfile($filePath);
            } else {
              die('File does not exist');
            }
          } else {
            die('Missing params');
          }
        }
        

        【讨论】:

        • 你是对的,有一个错误会允许用户下载任何文件......我现在要编辑它。
        • 已编辑。我添加了一些preg_replace 来替换该位置没有意义的字符,并在获取文件之前添加了preg_match 检查。
        • 是的,你现在解决了。一般的解决方案是拒绝任何尝试使用.. 访问任何内容的人,因为他们显然有不良意图,因此无需为他们提供任何帮助。
        • @KristianAntonsen 是的,在发布答案之前我没有考虑过这一点,因为我只考虑了解决方案。感谢您花时间检查我的代码。 :)
        猜你喜欢
        • 2023-03-14
        • 1970-01-01
        • 2012-05-25
        • 2016-12-20
        • 2014-03-04
        • 1970-01-01
        • 2016-11-22
        • 1970-01-01
        • 2017-10-20
        相关资源
        最近更新 更多