【问题标题】:Upload image with unique name上传具有唯一名称的图像
【发布时间】:2018-05-18 18:31:53
【问题描述】:

所以我正在尝试使用下面的脚本将一些图像上传到我的服务器上的文件夹,但是它将每个图像保存为“image.jpg”,如果我尝试上传多个图像,它会覆盖最后上传的图像。正如你可以看到我评论了检查文件是否已经存在的部分,让我上传文件并覆盖最新的文件。帮助!我需要修改一些东西来随机化名称或获取原始图像名称。

<?php
$target_dir = "wp/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);

// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
    } else {
        echo "File is not an image.";
        $uploadOk = 0;
    }
}
// Check if file already exists
/*if (file_exists($target_file)) {
    echo "Sorry, file already exists.";
    $uploadOk = 0;
}*/
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
    echo "Sorry, your file is too large.";
    $uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "png" && $imageFileType != "jpg") {
    echo "Sorry, only PNG and JPG files are allowed.";
    $uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?>

【问题讨论】:

  • 问题是 $target_file 这被 $_FILES["fileToUpload"]["name"] 填充。试试 var_dump(`$_FILES["fileToUpload"]["name"])。文件作为文件数组发送。这将使您知道名称存储在数组中。应该为您指明解决方案的方向。
  • 要随机化您上传的名称,您可以使用 time() 将当前日期附加到名称后面(以毫秒为单位),这样每次使用相同名称的更新都不会发生冲突,并且上传无需覆盖现有文件。

标签: php html file-upload


【解决方案1】:

获取唯一文件名的一种简单方法是获取当前的 Unix 时间(以毫秒为单位)并将其附加(或前置)到文件名中。使用的命令是microtime()

例如:

$target_file = $target_dir . microtime() . basename($_FILES["fileToUpload"]["name"]);

您也可以尝试对文件进行散列处理,以获得冲突概率较低的唯一散列,但这更快且同样有效。

【讨论】:

  • 谢谢!完美运行。
  • 如果两个请求同时来自两个具有相同文件名的客户端怎么办?
  • 碰撞的可能性很小。另一个需要探索的想法是使用某种使用 PHP 的 UUID generation function 并启用 more_entropy 来减少冲突的机会(请注意,该函数仍然依赖于 microtime 来生成 UUID)。
【解决方案2】:

您可以实现类似 Windows 的自动文件重命名功能:

$try = 1;
while($file_exists($target_file)) {
    $target_file = preg_replace('/(\(\\d+\))*(\.[^\\(\\)]+)$/',
        "({$try})\\2", $target_file);
    $try++;
}

这会将文件“duplicate.jpg”替换为“duplicate(1).jpg”,然后是“duplicate(2).jpg”,以此类推。

它仍然容易出现不太可能的竞争条件,就像使用 uniqid()microtime() 一样(从冲突角度来看,两者都更好)。

否则,请始终使用tempnam()。您可以查看this answer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 2015-04-02
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    相关资源
    最近更新 更多