如果文件名已存在,则将PHP重命名文件名并在末尾添加数字

27

如果上传的图片已经存在,我想在上传时将其文件名重命名,比如我的文件名是test.jpg并且已经存在,我想将它重命名为test1.jpg,然后是test2.jpg以此类推。但是我写的代码会将我的文件名更改为test1.jpg,然后是test12.jpg。希望能提供修复建议,谢谢!

PHP

$name = $_FILES['picture']['name'];
$actual_name = pathinfo($name,PATHINFO_FILENAME);
$extension = pathinfo($name, PATHINFO_EXTENSION);

$i = 1;
while(file_exists('tmp/'.$actual_name.".".$extension))
{           
    $actual_name = (string)$actual_name.$i;
    $name = $actual_name.".".$extension;
    $i++;
}

在使用完变量$actual_name后,请将其清空,因为它是一个循环变量,可以通过以下方式实现:$actual_name = ''。 - Aravind.HU
你可以在 while 循环中使用 $i 来测试名称,例如 "tmp/".$actual_name.$i.".".$extension,并在 while 循环后创建 $name 值,即 $name = "tmp/".$actual_name.$i.".".$extension - dbf
我通常不是那种人,但你真的应该考虑尝试我的答案并将其选为最佳答案。祝你有美好的一天 :) - connectedMind
4个回答

50

这是一个我认为可以实现你想要的微小修改:

$actual_name = pathinfo($name,PATHINFO_FILENAME);
$original_name = $actual_name;
$extension = pathinfo($name, PATHINFO_EXTENSION);

$i = 1;
while(file_exists('tmp/'.$actual_name.".".$extension))
{           
    $actual_name = (string)$original_name.$i;
    $name = $actual_name.".".$extension;
    $i++;
}

运行得很顺利,你是我的英雄。 - ucMedia
看起来这个答案只是简单地每次增加 1,所以:foo.bar -> foo1.bar -> foo11.bar 等等。从技术上讲它可以工作,但任何之前处理过文件的人都会期望数字递增(foo2.bar),而不仅仅是追加数字。 - connectedMind

8
受@Jason答案的启发,我创建了一个函数,我认为它的文件名格式更短、更易读。
function newName($path, $filename) {
    $res = "$path/$filename";
    if (!file_exists($res)) return $res;
    $fnameNoExt = pathinfo($filename,PATHINFO_FILENAME);
    $ext = pathinfo($filename, PATHINFO_EXTENSION);

    $i = 1;
    while(file_exists("$path/$fnameNoExt ($i).$ext")) $i++;
    return "$path/$fnameNoExt ($i).$ext";
}

示例:

$name = "foo.bar";
$path = 'C:/Users/hp/Desktop/ikreports';
for ($i=1; $i<=10; $i++) {
  $newName = newName($path, $name);
  file_put_contents($newName, 'asdf');
}

新版本(2022年):

function newName2($fullpath) {
  $path = dirname($fullpath);
  if (!file_exists($fullpath)) return $fullpath;
  $fnameNoExt = pathinfo($fullpath,PATHINFO_FILENAME);
  $ext = pathinfo($fullpath, PATHINFO_EXTENSION);

  $i = 1;
  while(file_exists("$path/$fnameNoExt ($i).$ext")) $i++;
  return "$path/$fnameNoExt ($i).$ext";
}

使用方法:

for ($i=1; $i<=10; $i++) {
  $newName = newName2($fullpath);
  file_put_contents($newName, 'asdf');
}

看起来这个答案只是一直附加 ' (1)',所以:foo.bar -> foo (1).bar -> foo (1) (1).bar 等等。从技术上讲,它可以工作,但任何之前处理过文件的人都会期望数字增加(foo (2).bar),而不仅仅是附加。 - connectedMind
看起来像是?你有尝试过吗?也许你用错了。 - Fandi Susanto
我自己提供了一个答案,你应该能够看到不同之处。 - connectedMind

1
在上传图像到服务器之前,有几种在PHP中重命名图像的方法。例如追加时间戳、唯一标识符、图像尺寸和随机数等。你可以在这里看到它们全部。
首先,检查托管图像文件夹中是否存在图像文件名,否则上传它。while循环检查图像文件名是否存在,并追加一个唯一标识符,如下所示...
function rename_appending_unique_id($source, $tempfile){

    $target_path ='uploads-unique-id/'.$source;
     while(file_exists($target_path)){
        $fileName = uniqid().'-'.$source;
        $target_path = ('uploads-unique-id/'.$fileName);
    }

    move_uploaded_file($tempfile, $target_path);

}

if(isset($_FILES['upload']['name'])){

    $sourcefile= $_FILES['upload']['name'];
    tempfile= $_FILES['upload']['tmp_name'];

    rename_appending_unique_id($sourcefile, $tempfile);

}

检查更多图片 重命名策略

-1

我在 Stack Overflow 上查找到了一个不错的 C# 回答 这里, 所以我将其移植到了 PHP:

['extension' => $extension] = pathinfo($filePath);
$count = 0;
while (file_exists($filePath) === true) {
    if ($count === 0) {
        $filePath = str_replace($extension, '[' . ++$count . ']' . ".$extension", $filePath);
    } else {
        $filePath = str_replace("[$count].$extension", '[' . ++$count . ']' . ".$extension", $filePath);
    }
}

$extension变量未声明。 - Fandi Susanto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接