【问题标题】:Rename uploaded files to avoid overwriting重命名上传的文件以避免覆盖
【发布时间】:2011-02-23 02:07:27
【问题描述】:

我有一个运行良好的简单脚本,但目前会覆盖具有重复名称的文件。我怎样才能避免这种情况?

<?php
   // Configuration - Your Options
    $allowed_filetypes = array('.mp3'); // These will be the types of file that will pass the validation.
    $max_filesize = 1048576; // Maximum filesize in BYTES (currently 0.5MB).
    $upload_path = './uploads/'; // The place the files will be uploaded to (currently a 'files' directory).

    $filename = $_FILES['userfile']['name']; // Get the name of the file (including file extension).
    $ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Get the extension from the filename.

    if(!in_array($ext,$allowed_filetypes))

        header('Location: http://www.website.com/five/error');

    if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize)

        header('Location: http://www.website.com/five/error');

    if(!is_writable($upload_path))

        header('Location: http://www.website.com/five/error');

    if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $filename))

//         echo 'Your file upload was successful, view the file <a href="' . $upload_path . $filename . '" title="Your File">here</a>'; // It worked.
        header('Location: http://www.website.com/five/sent');

    else

        header('Location: http://www.website.com/five/error');

?>

【问题讨论】:

标签: php upload duplicates


【解决方案1】:

在上传之前添加if (file_exists($upload_path.$filename)),如果有,请将$filename 设置为其他值。

【讨论】:

    【解决方案2】:

    一种选择是使用数据库来存储原始名称以及唯一 ID。

    然后您可以将文件保存为您想要的任何唯一名称。

    • 仅使用 id... 文件 = 1
    • 使用 id 和扩展名 = 1.mp3
    • 使用 id 和 name 的组合 = 1_name_of_file.mp3
    • 或任何其他独特的命名选项。

    然后您使用 php 来提供文件。使用原始文件名设置标题。

    用户不会知道您是如何存储文件的。可以使用该名称上传和下载具有相同名称的多个文件,但在服务器上是唯一存储的。

    <?php
    
    $actualFile = './uploads/'.$id;
    
    // Can use some smarts to determine the mime type here
    header('Content-type: application/force-download');
    
    // The user will be prompted to save it as the filename given here.
    header('Content-Disposition: attachment; filename="'.$originalName.'"');
    header("Content-Length: ".filesize($actualFile));
    
    
    // The actual file on the server
    readfile($actualFile);
    ?>
    

    您还可以为缓存等设置许多其他标头选项。

    http://php.net/manual/en/function.header.php

    Fileinfo 是确定 mimetypes 的一个很好的扩展

    http://www.php.net/manual/en/function.finfo-file.php

    【讨论】:

      【解决方案3】:

      使用您自己的文件名而不是原始文件名。

      这可以例如通过 uniqid() 生成

      【讨论】:

        【解决方案4】:

        以哈希作为名称存储文件,并将原始文件名与哈希一起存储在数据库/平面文件中。

        如果您想使用平面文件,可能只是将用户文件存储为 .dat,而有关文件的信息存储为 .json 或 .xml,或者如果您愿意,甚至只是一个序列化的 PHP 对象。

        此外,只要文件名中包含多个点(句点),您的文件扩展检测逻辑就会失败。

        【讨论】:

          猜你喜欢
          • 2016-09-06
          • 1970-01-01
          • 1970-01-01
          • 2013-01-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-02
          • 1970-01-01
          相关资源
          最近更新 更多