我可以使用函数md5_file在上传时命名文件而不会与名称冲突吗?

时间:2014-04-13 09:04:27

标签: php file-upload md5 filenames md5-file

所有想法我需要确保文件不会保存多次并且不会丢失任何文件,因为如果两个文件相同(md5),则第二个文件将无法保存 (我的目标是不要将相同的文件保存在硬盘上两次)

换句话说, 如果一个用户上传图像,之后另一个用户上传相同的图像,我需要不保存第二个图像,因为它已经存在于硬盘中所有这一切,因为 我需要节省硬盘空间 这是我的代码,它工作正常

$targetFolder = '/test/uploadify/uploads'; // Relative to the root
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;

$myhash = md5_file($_FILES['Filedata']['tmp_name']);
$temp = explode(".", $_FILES['Filedata']['name']);
$extension = end($temp);

$targetFile = rtrim($targetPath,'/') . '/' .$myhash.'.'.$extension;
if(file_exists($targetFile)){
    echo 'exist';
}

// Validate the file type
$fileTypes = array('jpg','jpeg','gif','png'); // File extensions
$fileParts = pathinfo($_FILES['Filedata']['name']);
if (in_array($fileParts['extension'],$fileTypes)) {
    move_uploaded_file($tempFile,$targetFile);
} 
else {
    echo 'Invalid file type.';
}

感谢所有人

3 个答案:

答案 0 :(得分:0)

它非常小,但机会就在那里。您可以阅读更多herehere

我建议你在文件名的末尾添加一个盐,使文件几乎不可能发生冲突(你应该把盐放在不同的md5函数中)

$salt = md5(round(microtime(true) * 1000));
$hash = md5_file($_FILES['Filedata']['tmp_name']);
$targetFile = rtrim($targetPath,'/') . '/' .$hash.$salt.'.'.$extension;

然后,您应该在数据库中插入文件名,以便以后可以访问它。

答案 1 :(得分:0)

您始终可以将系统当前时间(以毫秒为单位)添加到文件名中。加上md5,返回相同值的可能性很小。

答案 2 :(得分:0)

如果我正确理解您的问题,您的目标只是生成唯一的文件名。如果是这样,重新发明轮子是没有意义的 - 每个具有固定输出长度的散列函数都会发生冲突 - 只需使用内置的tempnam函数。

手动状态:

  

在指定目录中创建具有唯一文件名的文件,其访问权限设置为0600。如果该目录不存在,tempnam()可能会在系统的临时目录中生成一个文件,并返回该文件的完整路径,包括其名称。

以下应该运作良好:

$targetDirectory = $_SERVER['DOCUMENT_ROOT'] . '/test/uploadify/uploads';
$uploadedFile = $_FILES['Filedata']['tmp_name'];
$targetFile = tempnam($targetDirectory, '');
move_uploaded_file($uploadedFile, $targetFile);