Prevent one image from overlapping another in the input file

-1

I have this code:

$img = $_FILES['file']['name'];
$diretorio = "imagens/";
$tmp = $_FILES['file']['tmp_name'];
move_uploaded_file($tmp, $diretorio.$img);

If I put, for example: ball.png and another user put ball.png after, his image will change mine. I would like that if there is already this file in my images folder and in my database, it appears as, for example: ball (1) .png, then ball (2) .png and so on.

    
asked by anonymous 18.12.2017 / 13:44

1 answer

2

Just use is_file and create a recursive function to avoid duplicating

function increment_name($path)
{
    //Se o arquivo não existir o nome será aceito
    if (!is_file($path)) {
        return $path;
    }

    //Pega as informações do PATH
    $info = pathinfo($path);

    //Pega o nome sem extensão
    $name = $info['filename'];

    /*
     * Se não houver um formato como "x (1).txt"
     * então inicia do zero para incrementar 1
     */
    $current = 0;


    /*
     * Verifica se já existe algo como "x (1).txt"
     * se existir pega o numero e manda os valores do regex para $out
     */
    if (preg_match('#\((\d+)\)$#', $name, $out)) {
        //Pega o numero que estava entre parenteses
        $current = $out[1];

        //Remove o numero e os parenteses do final
        $name = rtrim(substr($name, 0, -strlen($current)-2));
    }

    //Incrementa um numero
    $name .= ' (' . (++$current) . ')';

    //Checa recursivamente se o NOVO nome já existe ou não
    return increment_name($info['dirname'] . '/' . $name . '.' . $info['extension']);
}

//Usando

$img = $_FILES['file']['name'];
$diretorio = "imagens/";
$tmp = $_FILES['file']['tmp_name'];

$new_name = increment_name($diretorio.$img);

move_uploaded_file($tmp, $new_name);

Using uniqid ()

Following the suggestions for comments, you can use uniqid() only have a problem, it is not 100% guaranteed because it uses "time" work around the problem you try to apply a rand() and also check if the name already exists, doing a recursive check

I created an example:

function create_ufilename($name, $path = '.')
{
    //Pega a extensão da imagem original
    $ext = pathinfo($name, PATHINFO_EXTENSION);

    //Gera um nome baseado no tempo
    $id = uniqid(rand(1, 100));

    //Gera o caminho
    $path .= '/' . $id . '.' . $ext;

    //Se existir tentará novamente, caso contrário retornará o novo nome
    return is_file($path) ? create_ufilename($name, $path) : $path;
}

//Usando

$img = $_FILES['file']['name'];
$diretorio = "imagens/";
$tmp = $_FILES['file']['tmp_name'];

$new_name = increment_name($diretorio.$img);

//Deve passar o nome da imagem e a pasta que deseja salvar, assim:
$salvar = create_ufilename($img, $diretorio);

move_uploaded_file($tmp, $salvar);
    
18.12.2017 / 14:20